免责声明:我对整个 RE 事情相对较新。所以我成功地将一些指令塞进了现有 DLL 的末尾并重定向了一个调用。
现在我实际上想在调用原始代码之前用函数参数做一些事情并尝试OutputDebugStringA
它。
OutputDebugStringA
由我的 Dll 静态导入,因此我尝试执行以下操作:
call dword ptr ds:[<&OutputDebugStringA>]
这是我从 DLL 本身的用法中复制的指令。
所以这有效并被成功调用。但是,当我用这条指令修补 Dll 时,在下一次运行时地址无效,这会导致访问冲突和崩溃。(见图中红线)
为什么呢?相对于加载 Dll 的位置,函数的 IAT 条目不应该始终位于同一位置吗?
我该如何解决?
我需要复杂的技巧来找到我的模块的基地址吗?
或者是否有某种我愚蠢地不知道的相对远呼叫指令?
谢谢您的帮助。
我想我现在明白了。所以我不能确定 IAT 总是在同一个地址,甚至与 ds 段无关(这在我看来有点没用)。
但是,我可以确定 IAT 地址始终与我要运行的代码保持固定的相对数量。
所以我在 x86 下搜索了 PIC 技术,最终得到了到目前为止似乎工作正常的代码。
push ebp
mov ebp,esp
push eax
push ecx
push edx
push dword ptr ss:[ebp+C]
call <rcp-be-name.tmplbl>
pop ebx ;@tmplbl
lea eax,dword ptr ds:[ebx+80F] ;the relative offset
call dword ptr ds:[eax-5] ;dunno why 5
pop edx
pop ecx
pop eax
push dword ptr ss:[ebp+C] ;the original arguments
push dword ptr ss:[ebp+8] ; ...
call rcp-be-name.644A97D0 ;the original function
add esp,8
pop ebp
ret
非常感谢!