visual-c++ - 从 exe 加载 exe

标签 visual-c++ winapi

我正在从 C++ exe 中导出一个函数 [使用 _declspec(dllexport)]。当由 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] 

考虑最后两条指令。 mov 将传入的参数移动到 ecx 中。在 40EFF0h,我们有各个 case 语句的各种指令的地址。因此,jmp 会将我们带到相关的案例说明

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 的情况下解决这个问题?

最佳答案

只是不要这样做。不值得这么麻烦。

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

Here's the question I posted about this a while back

关于visual-c++ - 从 exe 加载 exe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2048301/

相关文章:

C++:检查bmp文件是否合法

visual-studio - 在保留公共(public)控件功能的同时禁用 list 中的视觉样式

c# - 为什么 win32 上没有 c# native 编译器项目?

windows - 虚拟机如何检测应用程序窗口?

windows - 加载 PE 文件的资源时

c++ - 编辑 ui 文件时,不会重新生成 cpp.obj 文件

c++ - 抽象类 c++(错误 LNK 2001 : unresolved external symbol)

c++ - 没有重载函数的实例....(消息框::显示)

c - 为什么这个C程序会无限循环?

c - SetWindowPos 在 64 位 Windows 中编译错误