在反汇编程序中找不到 SetCooperativeLevel 调用

逆向工程 艾达 拆卸 ollydbg
2021-06-21 13:20:06

我正在尝试对安装游戏“皇帝:沙丘之战”的安装程序进行一些更改。如果你想看看我正在处理的 EXE,你可以从这里的官方安装修复补丁下载这个安装程序的副本:http : //dune2k.com/Duniverse/Games/Emperor/Downloads/Patches(下载“安装修复:”条目,它是 Setup.exe)。

出于某种原因,开发人员决定使安装程序成为全屏应用程序,因此我试图将其修改为在窗口中运行。它使用 DirectDraw API(不完全确定是什么版本,但我认为它是 7 或 8)。因此,我知道函数“SetCooperativeLevel”(https://docs.microsoft.com/en-us/windows/desktop/api/ddraw/nf-ddraw-idirectdraw7-setcooperativelevel)用于在全屏模式下初始化 DDraw 应用程序或窗口模式。

我的问题是我尝试使用 IDA Pro 7.0 和 OllyDbg 2.01 反汇编 EXE,但他们都无法找到对该函数的任何调用。谁能告诉我我是否可以做些什么来帮助其中一个程序找到这个电话?或者,DDraw 程序是否有可能在没有 SetCooperativeLevel 函数的情况下进入全屏模式?

编辑:我试图在下面使用 Defragger 的建议。不幸的是,它没有奏效。我修改了他在下面指出的代码,只是将尺寸更改为 800x600,但它没有改变任何东西。该窗口仍处于全屏状态,并没有出现任何不同:

.text:004619BF                 mov     esi, ds:GetSystemMetrics
.text:004619C5                 push    258h            ; yBottom
.text:004619CA                 push    320h            ; xRight
.text:004619CF                 push    0               ; yTop
.text:004619D1                 push    0               ; xLeft
.text:004619D3                 push    offset Rect     ; lprc
.text:004619D8                 call    ds:SetRect

我发现我只能安全地修改“yBottom”和“xRight”参数。如果我修改了“yTop”或“xLeft”,程序就会崩溃。

2个回答

还可以使用该功能将屏幕设置为全屏 SetRect

我在提到的可执行文件上找到了这个位置:

0x004619bf mov esi, dword [sym.imp.USER32.dll_GetSystemMetrics]
0x004619c5 push 1
0x004619c7 call esi
0x004619c9 push eax
0x004619ca push 0
0x004619cc call esi
0x004619ce push eax
0x004619cf push 0
0x004619d1 push 0
0x004619d3 push 0x48e2f8
0x004619d8 call dword [sym.imp.USER32.dll_SetRect]

GetSystemMetrics 的标志 0 和 1 被调用SM_CYSCREENSM_CXSCREEN并将GetSystemMetrics返回最终用于的最大 x 和 y 像素SetRect

编辑:

我使用radare2 找到这个点:/c call~SetRect 在ollydbg 或任何其他动态工具中,您可以简单地在顶部添加一个断点,SetRect然后等到它被触发以更改它的参数。

编辑2:

我想我的搜索 /c 错过了一些地方。Idapro 为 SetRect 计算了四个外部参照。您可以尝试直接在 SetRect 顶部设置断点,看看是谁在调用它。如果你想完全改变一个函数的行为,你可以使用类似https://frida.re 的东西,我认为这样的东西会起作用:

Interceptor.attach (Module.findExportByName("user32.dll", "SetRect"), {
onEnter: function (args) {
    args[2]= args[2].shr(1);
    args[3] = args[3].shr(1);
},
onLeave: function (retval) {});

将其保存到一些 js 文件中,并在您的系统上安装 frida 后使用这一行生成您的进程:frida -f SETUP.EXE -l yourscript.js 我希望这对您有用

我的问题是我尝试使用 IDA Pro 7.0 和 OllyDbg 2.01 反汇编 EXE,但他们都无法找到对该函数的任何调用。

它不会被直接调用,因为这是一个方法而不是一个函数。换句话说,IDirectDraw 实例包含一个指向代码的指针数组(称为虚拟表),当进行调用时,生成的代码是使用该实例的间接调用。要找出调用此方法的位置,您有几种方法:

  • 动态:识别到该方法的地址并为其设置断点,然后您可以在触发断点时获取调用者。
  • 静态地,找到对DirectDrawCreateEx和跟踪lplpDD参数的调用,当 vtable 被取消引用,然后是带有偏移量的间接调用(方法编号 * sizeof(void*)),看看目标是否是你正在寻找的方法。
  • 懒惰地,只需使用DxWnd :)

我希望它能帮助你。