#include
#include
#include
using namespace std;
PVOID GetProcessMoudleBase(HANDLE hProcess, char* moduleName)
{
// 遍历进程模块,
HMODULE hModule[100] = { 0 };
DWORD dwRet = 0;
BOOL bRet = ::EnumProcessModules(hProcess, (HMODULE*)(hModule), sizeof(hModule), &dwRet);
if (FALSE == bRet)
{
::CloseHandle(hProcess);
return NULL;
}
char name[50] = { 0 };
for (int i = 0; i < dwRet; i++)
{
GetModuleBaseNameA(hProcess, hModule[i], name, 50);
if (!_stricmp(moduleName, name))
{
cout << name << " Addr:" << hex << hModule[i] <
UINT64 GetFunAddrByName32(HANDLE hProcess,char* ModName, char* FunName)
{
HANDLE hMod;
PVOID BaseAddress = NULL;
IMAGE_DOS_HEADER dosheader;
IMAGE_OPTIONAL_HEADER opthdr;//IMAGE_OPTIONAL_HEADER64
IMAGE_EXPORT_DIRECTORY exports;
USHORT index = 0;
ULONG addr, i;
char pFuncName[30] = {0};
PULONG pAddressOfFunctions;
PULONG pAddressOfNames;
PUSHORT pAddressOfNameOrdinals;
//获取模块基址
BaseAddress = GetProcessMoudleBase(hProcess,ModName);
if (!BaseAddress) return 0;
//获取PE头
hMod = BaseAddress;
ReadProcessMemory(hProcess, hMod, &dosheader, sizeof(IMAGE_DOS_HEADER), 0);
ReadProcessMemory(hProcess, (BYTE*)hMod + dosheader.e_lfanew + 24, &opthdr, sizeof(IMAGE_OPTIONAL_HEADER), 0);
//ReadProcessMemory(hProcess, (BYTE*)hMod + dosheader.e_lfanew + 24, &opthdr, sizeof(IMAGE_OPTIONAL_HEADER64), 0);
//查找导出表
ReadProcessMemory(hProcess, ((BYTE*)hMod + opthdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress), &exports, sizeof(IMAGE_EXPORT_DIRECTORY), 0);
pAddressOfFunctions = (ULONG*)((BYTE*)hMod + exports.AddressOfFunctions);
pAddressOfNames = (ULONG*)((BYTE*)hMod + exports.AddressOfNames);
pAddressOfNameOrdinals = (USHORT*)((BYTE*)hMod + exports.AddressOfNameOrdinals);
//对比函数名
for (i = 0; i < exports.NumberOfNames; i++)
{
ReadProcessMemory(hProcess, pAddressOfNameOrdinals + i, &index, sizeof(USHORT), 0);
ReadProcessMemory(hProcess, pAddressOfFunctions + index, &addr, sizeof(ULONG), 0);
ULONG a = 0;
ReadProcessMemory(hProcess, pAddressOfNames + i, &a, sizeof(ULONG), 0);
ReadProcessMemory(hProcess, (BYTE*)hMod + a, pFuncName, 30, 0);
ReadProcessMemory(hProcess, pAddressOfFunctions + index, &addr, sizeof(ULONG), 0);
if (!_stricmp(pFuncName, FunName))
{
UINT64 funAddr = (UINT64)BaseAddress + addr;
cout << pFuncName << " " << hex << funAddr << endl;
return funAddr;
}
}
return 0;
}
需要的头文件及结构体:
#include
#include
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER64 {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
ULONGLONG ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64;
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, * PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, * PIMAGE_EXPORT_DIRECTORY;
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
UINT64 GetFunAddrByName32(PEPROCESS process, wchar_t* ModName, char* FunName)
{
USHORT index = 0;
ULONG addr, i;
HANDLE hMod;
PVOID BaseAddress = NULL;
PUCHAR pFuncName = NULL;
UINT64 funAddr = 0;
IMAGE_DOS_HEADER* dosheader;
IMAGE_OPTIONAL_HEADER32* opthdr;
PIMAGE_EXPORT_DIRECTORY exports;
PULONG pAddressOfFunctions;
PULONG pAddressOfNames;
PUSHORT pAddressOfNameOrdinals;
if (!process || !ModName || !FunName) return 0;
BaseAddress = GetProcessModuleByName(process, ModName);
if (!BaseAddress) return 0;
hMod = BaseAddress;
KAPC_STATE ApcState;
KeStackAttachProcess(process, &ApcState);
dosheader = (IMAGE_DOS_HEADER*)hMod;
opthdr = (IMAGE_OPTIONAL_HEADER32*)((BYTE*)hMod + dosheader->e_lfanew + 24);
//查找导出表
exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader + opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
pAddressOfFunctions = (ULONG*)((BYTE*)hMod + exports->AddressOfFunctions);
pAddressOfNames = (ULONG*)((BYTE*)hMod + exports->AddressOfNames);
pAddressOfNameOrdinals = (USHORT*)((BYTE*)hMod + exports->AddressOfNameOrdinals);
//对比函数名
for (i = 0; i < exports->NumberOfNames; i++)
{
index = pAddressOfNameOrdinals[i];
addr = pAddressOfFunctions[index];
pFuncName = (PUCHAR)((BYTE*)hMod + pAddressOfNames[i]);
addr = pAddressOfFunctions[index];
//DbgPrint("Name:%s \t Addr:%p\n", pFuncName, (UINT64)BaseAddress + addr);
if (!_stricmp((const char*)pFuncName, FunName))
{
funAddr = (UINT64)BaseAddress + addr;
DbgPrint("Name:%s \t Addr:%p\n", pFuncName, (UINT64)BaseAddress + addr);
}
}
KeUnstackDetachProcess(&ApcState);
return funAddr;
}
UINT64 GetFunAddrByName64(PEPROCESS process, wchar_t* ModName, char* FunName)
{
USHORT index = 0;
ULONG addr, i;
HANDLE hMod;
PVOID BaseAddress = NULL;
PUCHAR pFuncName = NULL;
UINT64 funAddr = 0;
IMAGE_DOS_HEADER* dosheader;
IMAGE_OPTIONAL_HEADER64* opthdr;
PIMAGE_EXPORT_DIRECTORY exports;
PULONG pAddressOfFunctions;
PULONG pAddressOfNames;
PUSHORT pAddressOfNameOrdinals;
if (!process || !ModName || !FunName) return 0;
BaseAddress = GetProcessModuleByName(process, ModName);
if (!BaseAddress) return 0;
hMod = BaseAddress;
KAPC_STATE ApcState;
KeStackAttachProcess(process, &ApcState);
dosheader = (IMAGE_DOS_HEADER*)hMod;
opthdr = (IMAGE_OPTIONAL_HEADER64*)((BYTE*)hMod + dosheader->e_lfanew + 24);
//查找导出表
exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader + opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
pAddressOfFunctions = (ULONG*)((BYTE*)hMod + exports->AddressOfFunctions);
pAddressOfNames = (ULONG*)((BYTE*)hMod + exports->AddressOfNames);
pAddressOfNameOrdinals = (USHORT*)((BYTE*)hMod + exports->AddressOfNameOrdinals);
//对比函数名
for (i = 0; i < exports->NumberOfNames; i++)
{
index = pAddressOfNameOrdinals[i];
addr = pAddressOfFunctions[index];
pFuncName = (PUCHAR)((BYTE*)hMod + pAddressOfNames[i]);
addr = pAddressOfFunctions[index];
//DbgPrint("Name:%s \t Addr:%p\n", pFuncName, (UINT64)BaseAddress + addr);
if (!_stricmp((const char*)pFuncName, FunName))
{
funAddr = (UINT64)BaseAddress + addr;
DbgPrint("Name:%s \t Addr:%p\n", pFuncName, funAddr);
}
}
KeUnstackDetachProcess(&ApcState);
return funAddr;
}
UINT64 GetFunAddrByName(PEPROCESS process, wchar_t* ModName, char* FunName)
{
BOOLEAN IsWow64 = (PsGetProcessWow64Process(process) != NULL) ? TRUE : FALSE;
if (IsWow64)
return GetFunAddrByName32(process, ModName, FunName);
else
return GetFunAddrByName64(process, ModName, FunName);
}