Visual c++ 从exe加载exe

Visual c++ 从exe加载exe,visual-c++,winapi,Visual C++,Winapi,我从C++ exe导出函数[使用yDeExFrace(DLReutix])。当exe本身调用该函数时,该函数工作正常。我正在使用静态链接从另一个exe[测试项目的exe-我将调用此exe2]加载此exe(让我们调用此exe1),即在编译exe2时使用exe1的.lib文件,exe2在启动时将其加载到内存中,就像任何dll一样。这会导致函数执行失败 函数中的switch case语句的反汇编揭示了确切的问题 exe1调用函数时的汇编代码 switch (dwType) 0040FF84 m

我从C++ exe导出函数[使用yDeExFrace(DLReutix])。当exe本身调用该函数时,该函数工作正常。我正在使用静态链接从另一个exe[测试项目的exe-我将调用此exe2]加载此exe(让我们调用此exe1),即在编译exe2时使用exe1的.lib文件,exe2在启动时将其加载到内存中,就像任何dll一样。这会导致函数执行失败

函数中的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] 
   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]
考虑最后两个说明。mov将传入的参数移动到ecx中。在40EFF0h,我们有相应案例陈述的各种说明的地址。因此,jmp会将我们带到相关案例说明

exe2调用函数时的汇编代码

   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] 
   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的情况下,如何解决此问题?

不要这样做。这不值得费心

我试过做你刚才试过的事。您可以通过更改属性窗口中“Linker->Advenced->Fixed base address”下的选项来解决不可重定位的exe问题,但随后您将遇到其他问题。
最后让我意识到这是浪费时间的事情是认识到EXE没有
DllMain()
函数。这意味着CRT库没有得到初始化,并且各种各样的东西都没有按照您期望的方式工作


您是否考虑过另一种方法?例如,将第2个.exe转换为.dll,并在希望将其用作可执行文件时使用rundll32调用它

否则: 生成的程序集很好。问题在于Win32可移植可执行文件有一个基址(在本例中为0x0040000)和一个包含地址详细位置的部分,以便在需要时可以重新设置地址的基址

因此,一对二的事情正在发生: -编译器在生成.exe时没有包含映像\u BASE\u重定位记录。 -或者运行时在动态加载.exe时没有执行基重定位 -(可能两者都有)

如果.exe确实包含重新定位记录,则可以读取这些记录并自己执行基本重新定位。您将不得不跳转,比如确保您有对内存的写访问权(VirtualAlloc等),但这在概念上相当简单

如果.exe不包含您填充的重新定位记录,请找到一个编译器选项来强制包含这些记录,或者找到其他方法来执行您正在执行的操作


编辑:正如shoosh所指出的,一旦你解决了这个问题,你可能会遇到其他问题。

尝试了同样的方法,并得出了相同的结论。