在函数中的switch case语句的反汇编代码中揭示了确切的问题。
当exe1调用该函数时的汇编代码:
switch (dwType)
0040FF84 mov eax,dword ptr [dwType]
0040FF87 mov dword ptr [ebp-4],eax
0040FF8A cmp dword ptr [ebp-4],0Bh
0040FF8E ja $LN2+7 (40FFD2h)
0040FF90 mov ecx,dword ptr [ebp-4]
0040FF93 jmp dword ptr (40FFE0h)[ecx*4]
考虑最后两条指令。mov指令将传入的参数移动到ecx寄存器中。在40EFF0h处,我们有各种情况语句的指令地址。因此,jmp指令会将我们带到相关的case指令。
当exe2调用该函数时的汇编代码。
switch (dwType)
0037FF84 mov eax,dword ptr [dwType]
0037FF87 mov dword ptr [ebp-4],eax
0037FF8A cmp dword ptr [ebp-4],0Bh
0037FF8E ja $LN2+7 (37FFD2h)
0037FF90 mov ecx,dword ptr [ebp-4]
0037FF93 jmp dword ptr [ecx*4+40FFE0h]
发现问题了吗?指令地址。代码现在已经加载到内存的不同位置。当编译exe1时,编译器假定我们将始终启动它,因此它将始终加载到0x0040000 [与所有Windows exe一样]。因此,它在指令中硬编码了一些值,如40FFE0h。只有在第二种情况下,40FFE0才是无用的内存,因为我们要查找的指令地址表不在那里。
如何在不将exe1转换为dll的情况下解决此问题?