Last active
December 26, 2018 19:27
-
-
Save Barakat/45f3705bcaf5f3aabd58df46815011b7 to your computer and use it in GitHub Desktop.
Locating KERNEL32.DLL base address shellcode for x86 and x64 using C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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