gpt4 book ai didi

c - 获取实际函数 LoadLibraryExW 的地址而不是 Stub LoadLibraryExWStub

转载 作者:太空宇宙 更新时间:2023-11-04 07:45:44 26 4
gpt4 key购买 nike

我正在尝试获取 DLL LoadLibraryExW 中函数的地址。但是,当我尝试获取此函数的地址时,我实际上获取了 LoadLibraryExWStub 的地址。

#include <stdio.h>
#include <Windows.h>

intptr_t getFuncAddr(const char* func, const char* dll)
{
return (intptr_t)GetProcAddress(
GetModuleHandle(dll),
func);
}

int main()
{
// Actual address: 000007FEFD28B2B0 Stub address I get instead: 0x00000000771d5680
intptr_t loadLibExWAddr = getFuncAddr("LoadLibraryExW", "kernel32.dll");

printf("%x\n", (int)loadLibExWAddr);
}

从 Visual Studio 中组装这些函数:

LoadLibraryExWStub:
00000000771D5680 EB F2 jmp LoadLibraryExW (0771D5674h)
00000000771D5682 8B D6 mov edx,esi
00000000771D5684 E9 1F DC FF FF jmp ConstructKernelKeyPath+58h (0771D32A8h)
00000000771D5689 8B CE mov ecx,esi
00000000771D568B E9 29 DC FF FF jmp ConstructKernelKeyPath+69h (0771D32B9h)
00000000771D5690 41 89 1C 24 mov dword ptr [r12],ebx
00000000771D5694 E9 B3 DC FF FF jmp ConstructKernelKeyPath+0FCh (0771D334Ch)
00000000771D5699 90 nop
00000000771D569A 90 nop
00000000771D569B 90 nop
00000000771D569C 90 nop
00000000771D569D 90 nop
00000000771D569E 90 nop
00000000771D569F 90 nop

LoadLibraryExW:
000007FEFD28B2B0 FF F3 push rbx
000007FEFD28B2B2 56 push rsi
000007FEFD28B2B3 41 54 push r12
000007FEFD28B2B5 48 83 EC 60 sub rsp,60h
000007FEFD28B2B9 45 33 E4 xor r12d,r12d
000007FEFD28B2BC 33 C0 xor eax,eax
000007FEFD28B2BE 41 8B F0 mov esi,r8d
000007FEFD28B2C1 81 E6 00 20 00 00 and esi,2000h
; it's pretty long... but you can tell it's the core function that actually goes out and loads the DLL

kernel32.dll 的程序集中,我还看到另一个名为 LoadLibraryExW 的函数,其定义如下:

LoadLibraryExW:
00000000771D5674 FF 25 CE 80 08 00 jmp qword ptr [__imp_LoadLibraryExW (07725D748h)]
00000000771D567A 90 nop
00000000771D567B 90 nop
00000000771D567C 90 nop
00000000771D567D 90 nop
00000000771D567E 90 nop
00000000771D567F 90 nop

这让我更加困惑。它们怎么可能是两个 LoadLibraryExW 函数?

因此,重申一下,我想获取实际执行 DLL 加载的核心 LoadLibraryExW 函数的函数地址;并不是所有其他的东西似乎都跳到了它。

最佳答案

一点历史课有助于解释这一点。

Windows 95 只有正常的导出函数,NT3&4 可能有一些 forwarders .低级 Win32 函数存在于 kernel32、user32 和 gdi32 中,仅此而已。 NTDLL 应该是完全未记录和禁止的。

在 Vista 时代,Microsoft 进行了一项名为 MinWin 的实验这导致某些组件的分层发生了变化。部分功能实现大部分或全部移至 Windows 7 中的新 kernelbase.dll。

Win32 ABI 和数百万应用程序当然依赖于 kernel32 中的 LoadLibraryExW,因此那里仍然存在一个简单的 stub 函数。 该函数的名称仍然是 LoadLibraryExW,但这些符号的名称中通常带有 Stub 后缀,因为该函数在跳转到其新位置之前几乎不做任何工作。 Windows 7 还添加了 API Sets “功能”应该通过不将功能绑定(bind)到特定的 .dll 来使这些类型的更改在将来更容易。

一个 Hook 库不应该对此感到惊讶。忘记符号并关注 GetProcAddress 及其返回的地址。从 ABI 的角度来看,函数以 jmp 开头一直是合法的,并且任何类型的 trampoline/hooking 库都必须能够处理它。

如果您只关心符合文档化 API 的应用程序,那么您不妨改为使用 IAT Hook 。如果您想 Hook “一切”,那么 LoadLibrary* 永远都不够深入。

注意:加载程序的核心实际上是在 NTDLL 中,基于 NT 的系统上的 LoadLibrary* 从不执行实际加载。如果您想收到有关已加载模块的通知,真正的安全软件可能应该捕获内核中的图像部分。

注意:jmp qword ptr [__imp_...] 通常是对另一个 .dll 中函数的调用。这是有道理的,因为转储中的 000007FEFD28B2B0 很可能不在 kernel32 中。

关于c - 获取实际函数 LoadLibraryExW 的地址而不是 Stub LoadLibraryExWStub,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57336231/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com