如何使用 WinDbg 查找 `GetProcAddress` 函数的过程名称
How to find the proc name for `GetProcAddress` function using WinDbg
我想使用 GetProcAddress
获取加载的 DLL 中的一些函数地址。我 运行 对 PSAPI 库进行了一些尝试,我可以看到预期的过程名称与我在 WinDbg x
语句中找到的符号名称不同。例如,我用 x psapi!*EnumProcessModules*
查找 "EnumProcessModules"(这是 GetProcAddress
方法预期的名称),我找到
00007ff9`fe112210 PSAPI!_imp_K32EnumProcessModulesEx = <no type information>
00007ff9`fe111360 PSAPI!EnumProcessModulesExStub (<no parameter info>)
00007ff9`fe111030 PSAPI!EnumProcessModulesStub (<no parameter info>)
00007ff9`fe1121a8 PSAPI!_imp_K32EnumProcessModules = <no type information>
当我将上面找到的任何符号(有或没有 "PSAPI!" 作为前缀)提供给 GetProcAddress
方法作为第二个参数(procName)时 - 它 returns NULL ,但是当我使用方法名称 "EnumProcessModules" - 它 returns 0xfe111030,这是 "PSAPI!EnumProcessModulesStub".
的地址
我怎么能提前知道预期的procName
?如果我在一个 DLL 中有 2 个不同的 类 或具有相同方法名称的命名空间怎么办?调用GetProcAddress
时如何区分两个方法名?
PSAPI!
只是一个前缀,是WinDbg打印的DLL名称。这用于消除名称歧义。一个清楚的例子,为什么这是有用的:你的过程中会有很多 DllMain
。
GetProcAddress
的预期名称是函数的 文档化 名称,如 MSDN 中所述。请记住,当 MSDN 声明两个版本都可用时,您将需要添加 A
或 W
后缀。例如。你不能用 "GetDeviceDriverFileName"
调用 GetProcAddress
,你需要 "GetDeviceDriverFileNameA"
或 L"GetDeviceDriverFileNameW"
。
对于 non-system DLL,您需要来自导出地址 Table 的函数名称。
背景:您在 WinDbg 中看到的是来自 .PDB 的名称,正如您所发现的,它可能与导出的名称不同。没有任何东西可以强制两者之间建立关系。例如,技术上可以使用 PDB 名称 Foo
和 Bar
,并在导出地址 Table 中交换它们。更实际的是,Microsoft 可能随时在内部添加一个 _wrapper_EnumProcessModules
,但记录和导出的名称将保留 EnumProcessModules
.
此 API 的核心功能在 kernel32.dll 中实现
并命名为 K32EnumProcessModules
在 paspi.h header 这个 API 是基于 PSAPI_VERSION
#ifndef PSAPI_VERSION
#if (NTDDI_VERSION >= NTDDI_WIN7)
#define PSAPI_VERSION 2
#else
#define PSAPI_VERSION 1
#endif
#endif
#if (PSAPI_VERSION > 1)
#define EnumProcessModules K32EnumProcessModules
如果您在 psapi.dll 中获取 GetProcAddress,您会得到一个存根,该存根将传输到 kernel32.dll
0:001> u PSAPI!EnumProcessModulesStub l 5
PSAPI!EnumProcessModulesStub:
762d1408 8bff mov edi,edi
762d140a 55 push ebp
762d140b 8bec mov ebp,esp
762d140d 5d pop ebp
762d140e eb05 jmp PSAPI!K32EnumProcessModules (762d1415)
0:001> u 762d1415 l1
PSAPI!K32EnumProcessModules:
762d1415 ff2504102d76 jmp dword ptr [PSAPI!_imp__K32EnumProcessModules (762d1004)]
0:001> u poi(762d1004) l1
kernel32!K32EnumProcessModules:
7668cc52 8bff mov edi,edi
你可以在dll上使用dumpbin/exports看看有没有关联
或者如果有名称更改(请参阅 Stub@16 )
:\>dumpbin /exports c:\windows\System32\psapi.dll | grep -w EnumProcessModules
5 4 00001408 EnumProcessModules = _EnumProcessModulesStub@16
您还可以使用类似下面的东西从 psapi.dll 的导出 table 中找到相同的信息
0:001> .shell -ci "!dh psapi" grep Export
1088 [ 359] address [size] of Export Directory
.shell: Process exited
0:001> dt ole32!_IMAGE_EXPORT_DIRECTORY (psapi + 1088)
+0x000 Characteristics : 0
+0x004 TimeDateStamp : 0x4a5bc026
+0x008 MajorVersion : 0
+0x00a MinorVersion : 0
+0x00c Name : 0x11be
+0x010 Base : 1
+0x014 NumberOfFunctions : 0x1b
+0x018 NumberOfNames : 0x1b
+0x01c AddressOfFunctions : 0x10b0
+0x020 AddressOfNames : 0x111c
+0x024 AddressOfNameOrdinals : 0x1188
0:001> r? $t0 = (int *) @@(psapi + 10b0)
0:001> r? $t1 = (int *) @@(psapi + 111c)
0:001> r? $t2 = (short *) @@(psapi + 1188)
0:001> .printf "%x %ma %y\n" , @@(@$t2[4]) , (@@(@$t1[4]) + psapi) , (@@(@$t0[4]) + psapi)
4 EnumProcessModules PSAPI!EnumProcessModulesStub (762d1408)
我想使用 GetProcAddress
获取加载的 DLL 中的一些函数地址。我 运行 对 PSAPI 库进行了一些尝试,我可以看到预期的过程名称与我在 WinDbg x
语句中找到的符号名称不同。例如,我用 x psapi!*EnumProcessModules*
查找 "EnumProcessModules"(这是 GetProcAddress
方法预期的名称),我找到
00007ff9`fe112210 PSAPI!_imp_K32EnumProcessModulesEx = <no type information>
00007ff9`fe111360 PSAPI!EnumProcessModulesExStub (<no parameter info>)
00007ff9`fe111030 PSAPI!EnumProcessModulesStub (<no parameter info>)
00007ff9`fe1121a8 PSAPI!_imp_K32EnumProcessModules = <no type information>
当我将上面找到的任何符号(有或没有 "PSAPI!" 作为前缀)提供给 GetProcAddress
方法作为第二个参数(procName)时 - 它 returns NULL ,但是当我使用方法名称 "EnumProcessModules" - 它 returns 0xfe111030,这是 "PSAPI!EnumProcessModulesStub".
我怎么能提前知道预期的procName
?如果我在一个 DLL 中有 2 个不同的 类 或具有相同方法名称的命名空间怎么办?调用GetProcAddress
时如何区分两个方法名?
PSAPI!
只是一个前缀,是WinDbg打印的DLL名称。这用于消除名称歧义。一个清楚的例子,为什么这是有用的:你的过程中会有很多 DllMain
。
GetProcAddress
的预期名称是函数的 文档化 名称,如 MSDN 中所述。请记住,当 MSDN 声明两个版本都可用时,您将需要添加 A
或 W
后缀。例如。你不能用 "GetDeviceDriverFileName"
调用 GetProcAddress
,你需要 "GetDeviceDriverFileNameA"
或 L"GetDeviceDriverFileNameW"
。
对于 non-system DLL,您需要来自导出地址 Table 的函数名称。
背景:您在 WinDbg 中看到的是来自 .PDB 的名称,正如您所发现的,它可能与导出的名称不同。没有任何东西可以强制两者之间建立关系。例如,技术上可以使用 PDB 名称 Foo
和 Bar
,并在导出地址 Table 中交换它们。更实际的是,Microsoft 可能随时在内部添加一个 _wrapper_EnumProcessModules
,但记录和导出的名称将保留 EnumProcessModules
.
此 API 的核心功能在 kernel32.dll 中实现 并命名为 K32EnumProcessModules
在 paspi.h header 这个 API 是基于 PSAPI_VERSION
#ifndef PSAPI_VERSION
#if (NTDDI_VERSION >= NTDDI_WIN7)
#define PSAPI_VERSION 2
#else
#define PSAPI_VERSION 1
#endif
#endif
#if (PSAPI_VERSION > 1)
#define EnumProcessModules K32EnumProcessModules
如果您在 psapi.dll 中获取 GetProcAddress,您会得到一个存根,该存根将传输到 kernel32.dll
0:001> u PSAPI!EnumProcessModulesStub l 5
PSAPI!EnumProcessModulesStub:
762d1408 8bff mov edi,edi
762d140a 55 push ebp
762d140b 8bec mov ebp,esp
762d140d 5d pop ebp
762d140e eb05 jmp PSAPI!K32EnumProcessModules (762d1415)
0:001> u 762d1415 l1
PSAPI!K32EnumProcessModules:
762d1415 ff2504102d76 jmp dword ptr [PSAPI!_imp__K32EnumProcessModules (762d1004)]
0:001> u poi(762d1004) l1
kernel32!K32EnumProcessModules:
7668cc52 8bff mov edi,edi
你可以在dll上使用dumpbin/exports看看有没有关联 或者如果有名称更改(请参阅 Stub@16 )
:\>dumpbin /exports c:\windows\System32\psapi.dll | grep -w EnumProcessModules
5 4 00001408 EnumProcessModules = _EnumProcessModulesStub@16
您还可以使用类似下面的东西从 psapi.dll 的导出 table 中找到相同的信息
0:001> .shell -ci "!dh psapi" grep Export
1088 [ 359] address [size] of Export Directory
.shell: Process exited
0:001> dt ole32!_IMAGE_EXPORT_DIRECTORY (psapi + 1088)
+0x000 Characteristics : 0
+0x004 TimeDateStamp : 0x4a5bc026
+0x008 MajorVersion : 0
+0x00a MinorVersion : 0
+0x00c Name : 0x11be
+0x010 Base : 1
+0x014 NumberOfFunctions : 0x1b
+0x018 NumberOfNames : 0x1b
+0x01c AddressOfFunctions : 0x10b0
+0x020 AddressOfNames : 0x111c
+0x024 AddressOfNameOrdinals : 0x1188
0:001> r? $t0 = (int *) @@(psapi + 10b0)
0:001> r? $t1 = (int *) @@(psapi + 111c)
0:001> r? $t2 = (short *) @@(psapi + 1188)
0:001> .printf "%x %ma %y\n" , @@(@$t2[4]) , (@@(@$t1[4]) + psapi) , (@@(@$t0[4]) + psapi)
4 EnumProcessModules PSAPI!EnumProcessModulesStub (762d1408)