Skip to content

Instantly share code, notes, and snippets.

@Barakat
Last active December 26, 2018 19:27
Show Gist options
  • Save Barakat/45f3705bcaf5f3aabd58df46815011b7 to your computer and use it in GitHub Desktop.
Save Barakat/45f3705bcaf5f3aabd58df46815011b7 to your computer and use it in GitHub Desktop.
Locating KERNEL32.DLL base address shellcode for x86 and x64 using C++
#include <Windows.h>
#include <winternl.h>
#include <cassert>
__declspec(dllexport)
__declspec(noinline)
void*
__stdcall
GetKernel32BaseAddress()
{
return CONTAINING_RECORD(
// Obtain TEB strcutre
NtCurrentTeb()
// Obtain PEB strcutre
->ProcessEnvironmentBlock
// Obtain the loader data
->Ldr
// Get the head pointer of the loaded modules list and travarse the doubly-linked list inplace
->InMemoryOrderModuleList
// Skip the current module
.Flink
// Skip NTDLL.DLL
->Flink
// KERNEL32.DLL is almost always the the third module to be loaded in Win32 subsystem
->Flink
// Get the base address of KERNEL32.DLL
, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks)->DllBase;
}
int main()
{
assert(GetKernel32BaseAddress() == GetModuleHandleW(L"KERNEL32.DLL"));
// cl /O1 /GS- shellcode.cpp
static const BYTE shellcode[] =
{
#if _WIN64
//
// 0: 65 48 8b 04 25 30 00 mov rax,QWORD PTR gs:0x30
// 7: 00 00
// 9: 48 8b 48 60 mov rcx,QWORD PTR [rax+0x60]
// d: 48 8b 41 18 mov rax,QWORD PTR [rcx+0x18]
// 11: 48 8b 48 20 mov rcx,QWORD PTR [rax+0x20]
// 15: 48 8b 01 mov rax,QWORD PTR [rcx]
// 18: 48 8b 00 mov rax,QWORD PTR [rax]
// 1b: 48 8b 40 20 mov rax,QWORD PTR [rax+0x20]
// 1f: c3 ret
//
0x65, 0x48, 0x8B, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x48, 0x60, 0x48, 0x8B, 0x41,
0x18, 0x48, 0x8B, 0x48, 0x20, 0x48, 0x8B, 0x01, 0x48, 0x8B, 0x00, 0x48, 0x8B, 0x40, 0x20, 0xC3
#elif _WIN32
//
// 0: 64 a1 18 00 00 00 mov eax,fs : 0x18
// 6: 8b 40 30 mov eax,DWORD PTR[eax + 0x30]
// 9: 8b 40 0c mov eax,DWORD PTR[eax + 0xc]
// c: 8b 40 14 mov eax,DWORD PTR[eax + 0x14]
// f: 8b 00 mov eax,DWORD PTR[eax]
// 11: 8b 00 mov eax,DWORD PTR[eax]
// 13: 8b 40 10 mov eax,DWORD PTR[eax + 0x10]
// 16: c3 ret
//
0x64, 0xA1, 0x18, 0x00, 0x00, 0x00, 0x8B, 0x40, 0x30, 0x8B, 0x40, 0x0C, 0x8B, 0x40, 0x14, 0x8B,
0x00, 0x8B, 0x00, 0x8B, 0x40, 0x10, 0xC3
#endif
};
const auto buffer = VirtualAlloc(nullptr, sizeof(shellcode), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
CopyMemory(buffer, shellcode, sizeof(shellcode));
DWORD old_memory_protection;
VirtualProtect(buffer, sizeof(shellcode), PAGE_EXECUTE_READ, &old_memory_protection);
(void)old_memory_protection;
const auto get_kernel32_shellcode = reinterpret_cast<void *(*)()>(buffer);
assert(get_kernel32_shellcode() == GetModuleHandleW(L"KERNEL32.DLL"));
VirtualFree(buffer, sizeof(shellcode), MEM_RELEASE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment