该 API 的核心功能在kernel32.dll中实现
并命名为K32EnumProcessModules
在 paspi.h 标头中,此 API 是基于 PSAPI_VERSION 的 ifdefed
#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 的导出表中找到相同的信息
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)