Windows x64 platform to obtain PEB table, and get kernel32.dll base address, function and get it

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!

 

Guess you like

Origin blog.csdn.net/Giser_D/article/details/90718842