Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/Giser_D/article/details/90718842
Reference: https://www.cnblogs.com/aliflycoris/p/5185097.html
And another blogger
Man of few words said, that is entered:
The first is to obtain the base address of PEB, come to understand how the assembly code in 64-bit embedded platforms: The reference bloggers https://blog.csdn.net/Giser_D/article/details/90670974
Assembly code:
.CODE
GetPeb PROC
mov rax,gs:[60h]
ret
GetPeb ENDP
END
External reference header file:
extern "C" PVOID64 _cdecl GetPeb();
Then get Kernel32 base address:
HMODULE getKernel32Address()
{
PVOID64 Peb = GetPeb();
PVOID64 LDR_DATA_Addr = *(PVOID64**)((BYTE*)Peb+0x018); //0x018是LDR相对于PEB偏移 存放着LDR的基地址
UNICODE_STRING* FullName;
HMODULE hKernel32 = NULL;
LIST_ENTRY* pNode = NULL;
pNode =(LIST_ENTRY*)(*(PVOID64**)((BYTE*)LDR_DATA_Addr+0x30)); //偏移到InInitializationOrderModuleList
while(true)
{
FullName = (UNICODE_STRING*)((BYTE*)pNode+0x38);//BaseDllName基于InInitialzationOrderModuList的偏移
if(*(FullName->Buffer+12)=='\0')
{
hKernel32 = (HMODULE)(*((ULONG64*)((BYTE*)pNode+0x10)));//DllBase
break;
}
pNode = pNode->Flink;
}
return hKernel32;
}
Then is the address, the name of the function obtained by the method above, obtaining an address corresponding to the function:
PVOID GetAddressFromExportTable(PVOID pBaseAddress, PCHAR pszFunctionName)
{
PVOID get_address;
ULONG ulFunctionIndex = 0;
// Dos Header
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
// NT Header
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);
// Export Table
PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress);
// 有名称的导出函数个数
ULONG ulNumberOfNames = pExportTable->NumberOfNames;
// 导出函数名称地址表
PULONG lpNameArray = (PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfNames);
PCHAR lpName = NULL;
// 开始遍历导出表
for (ULONG i = 0; i < ulNumberOfNames; i++)
{
lpName = (PCHAR)((PUCHAR)pDosHeader + lpNameArray[i]);
// 判断是否查找的函数
if (0 == _strnicmp(pszFunctionName, lpName, strlen(pszFunctionName)))
{
// 获取导出函数地址
USHORT uHint = *(USHORT *)((PUCHAR)pDosHeader + pExportTable->AddressOfNameOrdinals + 2 * i);
ULONG ulFuncAddr = *(PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfFunctions + 4 * uHint);
get_address = (PVOID)((PUCHAR)pDosHeader + ulFuncAddr);
break;
}
}
return get_address;
}
ok, I want to help, not to speak carefully, but can be used directly. For 64-bit platforms, remember!
Kernel32.dll function of ExitThread address GetAddressFromExportTable is obtained with the actual margin of error, the specific cause is not known, is not recommended!