From bf022c621c6e37a75c395f40a11f77a338344b37 Mon Sep 17 00:00:00 2001 From: devseed Date: Mon, 28 Mar 2022 23:16:25 +0900 Subject: [PATCH] v0.3.3, add support for aslr --- README.md | 6 +- src/memdll/libwinpe.def | 3 + src/memdll/win_injectmemdll.c | 60 ++++---- src/memdll/win_injectmemdll_shellcodestub.py | 153 +++++++++++++------ util | 2 +- 5 files changed, 148 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index c2b5378..d0ee945 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ A tool to parse and load module in memory, as well as attach a DLL in EXE. Most of the functions are inline, so that it can also be used in shellcode. -This project is tested on `windows xp `, `windows 7`, `windows 10`, `windows 11`, -also the attached exe file packed by upx is tested. +This project is tested on `windows xp `, `windows 7`, `windows 10`, `windows 11`, `linux wine` +also the attached exe file packed by `upx` is tested. ## compile @@ -138,4 +138,4 @@ See `winpe.h` for parsing and loading PE structure in detail. ## todo * ~~TLS initialize support~~ finished, but not tested, because I didn't find DLL with TLS example. -* support ASLR \ No newline at end of file +* ~~support ASLR~~ finished \ No newline at end of file diff --git a/src/memdll/libwinpe.def b/src/memdll/libwinpe.def index a431a8d..281c502 100644 --- a/src/memdll/libwinpe.def +++ b/src/memdll/libwinpe.def @@ -4,13 +4,16 @@ EXPORTS winpe_findkernel32 winpe_findloadlibrarya winpe_findspace + winpe_findmodulea winpe_imagebaseval + winpe_imagesizeval winpe_memFreeLibrary winpe_memFreeLibraryEx winpe_memGetProcAddress winpe_memLoadLibrary winpe_memLoadLibraryEx winpe_membindiat + winpe_membindtls winpe_memfindexp winpe_memfindiat winpe_memforwardexp diff --git a/src/memdll/win_injectmemdll.c b/src/memdll/win_injectmemdll.c index 2bb4e3d..cd861e8 100644 --- a/src/memdll/win_injectmemdll.c +++ b/src/memdll/win_injectmemdll.c @@ -1,6 +1,6 @@ /* A tool to attach a dll inside a pe file - v0.3.2, developed by devseed + v0.3.3, developed by devseed history: see win_injectmemdll_shellcodestub.py @@ -26,8 +26,8 @@ unsigned char g_findloadlibrarya_code[] = {0x90}; unsigned char g_findgetprocaddress_code[] = {0x90}; void _makeoepcode(void *shellcode, - size_t shellcodebase, size_t exeimagebase, size_t dllimagebase, - DWORD exeoeprva, DWORD dlloeprva) + size_t shellcoderva, size_t dllrva, + DWORD orgexeoeprva, DWORD orgdlloeprva) { // bind the pointer to buffer size_t oepinit_end = sizeof(g_oepinit_code); @@ -38,22 +38,22 @@ void _makeoepcode(void *shellcode, size_t findgetprocaddress_start = findloadlibrarya_start + FUNC_SIZE; // fill the address table - size_t *pexeoepva = (size_t*)(g_oepinit_code + oepinit_end - 8*sizeof(size_t)); - size_t *pdllbase = (size_t*)(g_oepinit_code + oepinit_end - 7*sizeof(size_t)); - size_t *pdlloepva = (size_t*)(g_oepinit_code + oepinit_end - 6*sizeof(size_t)); - size_t *pmemreloc = (size_t*)(g_oepinit_code + oepinit_end - 5*sizeof(size_t)); - size_t *pmembindiat = (size_t*)(g_oepinit_code + oepinit_end - 4*sizeof(size_t)); - size_t *pmembindtls = (size_t*)(g_oepinit_code + oepinit_end - 3*sizeof(size_t)); + size_t *pexeoeprva = (size_t*)(g_oepinit_code + oepinit_end - 8*sizeof(size_t)); + size_t *pdllbrva = (size_t*)(g_oepinit_code + oepinit_end - 7*sizeof(size_t)); + size_t *pdlloeprva = (size_t*)(g_oepinit_code + oepinit_end - 6*sizeof(size_t)); + size_t *pmemrelocrva = (size_t*)(g_oepinit_code + oepinit_end - 5*sizeof(size_t)); + size_t *pmembindiatrva = (size_t*)(g_oepinit_code + oepinit_end - 4*sizeof(size_t)); + size_t *pmembindtlsrva = (size_t*)(g_oepinit_code + oepinit_end - 3*sizeof(size_t)); size_t *pfindloadlibrarya = (size_t*)(g_oepinit_code + oepinit_end - 2*sizeof(size_t)); size_t *pfindgetprocaddress = (size_t*)(g_oepinit_code + oepinit_end - 1*sizeof(size_t)); - *pexeoepva = exeimagebase + exeoeprva; - *pdllbase = dllimagebase; - *pdlloepva = dllimagebase + dlloeprva; - *pmemreloc = shellcodebase + memreloc_start; - *pmembindiat = shellcodebase + membindiat_start; - *pmembindtls = shellcodebase + membindtls_start; - *pfindloadlibrarya = shellcodebase + findloadlibrarya_start; - *pfindgetprocaddress = shellcodebase + findgetprocaddress_start; + *pexeoeprva = orgexeoeprva; + *pdllbrva = dllrva; + *pdlloeprva = dllrva + orgdlloeprva; + *pmemrelocrva = shellcoderva + memreloc_start; + *pmembindiatrva = shellcoderva + membindiat_start; + *pmembindtlsrva = shellcoderva + membindtls_start; + *pfindloadlibrarya = shellcoderva + findloadlibrarya_start; + *pfindgetprocaddress = shellcoderva + findgetprocaddress_start; // copy to the target memcpy(shellcode , @@ -109,7 +109,6 @@ int injectdll_mem(const char *exepath, ((void*)mempe + pDosHeader->e_lfanew); PIMAGE_FILE_HEADER pFileHeader = &pNtHeader->FileHeader; PIMAGE_OPTIONAL_HEADER pOptHeader = &pNtHeader->OptionalHeader; - imgbase_exe = pOptHeader->ImageBase; // append section header to exe size_t align = sizeof(size_t) > 4 ? 0x10000: 0x1000; @@ -123,14 +122,13 @@ int injectdll_mem(const char *exepath, winpe_appendsecth(mempe_exe, §h); // adjust dll addr and append shellcode, iatbind is in runing - size_t shellcodebase = imgbase_exe + secth.VirtualAddress; - size_t dllimagebase = shellcodebase + SHELLCODE_SIZE + padding; - size_t exeimagebase = winpe_imagebaseval(mempe_exe, 0); - DWORD dlloeprva = winpe_oepval(mempe_dll, 0); - DWORD exeoeprva = winpe_oepval(mempe_exe, secth.VirtualAddress); - _makeoepcode(shellcode, shellcodebase, - exeimagebase, dllimagebase, exeoeprva, dlloeprva); - winpe_memreloc(mempe_dll, dllimagebase); + size_t shellcoderva = secth.VirtualAddress; + size_t dllrva = shellcoderva + SHELLCODE_SIZE + padding; + DWORD orgdlloeprva = winpe_oepval(mempe_dll, 0); // origin orgdlloeprva + DWORD orgexeoeprva = winpe_oepval(mempe_exe, secth.VirtualAddress); + _makeoepcode(shellcode, shellcoderva, dllrva, orgexeoeprva, orgdlloeprva); + // reloc while runing + // winpe_memreloc(mempe_dll, dllrva); // write data to new exe FILE *fp = fopen(outpath, "wb"); @@ -161,8 +159,14 @@ void test_getfunc(HMODULE hmod, const char *funcname) void test_exp() { - // test loadlibrary, getprocaddress HMODULE hmod = NULL, hmod2 = NULL, hmod3 = NULL; + // test winpe_findmodulea + hmod = GetModuleHandleA(NULL); + hmod2 = winpe_findmodulea(NULL); + assert(hmod!=NULL && hmod==hmod2); + printf("winpe_findmodulea(NULL) %p passed!\n", hmod2); + + // test loadlibrary, getprocaddress hmod = LoadLibraryA("kernel32.dll"); hmod2 = winpe_findkernel32(); hmod3 = winpe_findmodulea("kernel32.dll"); @@ -208,7 +212,7 @@ int main(int argc, char *argv[]) if(argc < 3) { printf("usage: win_injectmemdll exepath dllpath [outpath]\n"); - printf("v0.3.2, developed by devseed\n"); + printf("v0.3.3, developed by devseed\n"); return 0; } char outpath[MAX_PATH]; diff --git a/src/memdll/win_injectmemdll_shellcodestub.py b/src/memdll/win_injectmemdll_shellcodestub.py index 89902b0..9f99895 100644 --- a/src/memdll/win_injectmemdll_shellcodestub.py +++ b/src/memdll/win_injectmemdll_shellcodestub.py @@ -1,6 +1,6 @@ """ this file is for automaticly generate some shellcodes stub informations - v0.3.2, developed by devseed + v0.3.3, developed by devseed """ import re import sys @@ -11,51 +11,85 @@ def gen_oepinit_code32(): ks = Ks(KS_ARCH_X86, KS_MODE_32) code_str = f""" // for relative address, get the base of addr - call geteip; + call getip; lea ebx, [eax-5]; + // get the imagebase + mov eax, 0x30; // to avoid relative addressing + mov edi, dword ptr fs:[eax]; //peb + mov edi, [edi + 0ch]; //ldr + mov edi, [edi + 14h]; //InMemoryOrderLoadList, this + mov edi, [edi -8h + 18h]; //this.DllBase + // get loadlibrarya, getprocaddress - call [ebx + findloadlibrarya]; + mov eax, [ebx + findloadlibrarya]; + add eax, edi; + call eax; mov [ebx + findloadlibrarya], eax; - call [ebx + findgetprocaddress]; + mov eax, [ebx + findgetprocaddress]; + add eax, edi; + call eax; mov [ebx + findgetprocaddress], eax; + // reloc + mov eax, [ebx + dllrva]; + add eax, edi; + push eax; + push eax; + mov eax, [ebx + memrelocrva]; + add eax, edi; + call eax; + // bind iat - push [ebx + findgetprocaddress]; // arg3, getprocaddress - push [ebx + findloadlibrarya]; // arg2, loadlibraryas - push [ebx + dllbase]; // arg1, dllbase value - call [ebx + membindiat]; - add esp, 0xc; + mov eax, [ebx + findgetprocaddress]; + push eax; // arg3, getprocaddress + mov eax, [ebx + findloadlibrarya]; + push eax; // arg2, loadlibraryas + mov eax, [ebx + dllrva]; + add eax, edi; + push eax; // arg1, dllbase value + mov eax, [ebx + membindiatrva]; + add eax, edi + call eax; // bind tls - xor edx, edx; - inc edx; // arg2, reason for tls - push edx; - push [ebx + dllbase] // arg1, dllbase - call [ebx + membindtls] - add esp, 0x8; - + xor eax, eax; + inc eax; + push eax; // arg2, reason for tls + mov eax, [ebx + dllrva] + add eax, edi; + push eax; // arg1, dllbase + mov eax, [ebx + membindtlsrva]; + add eax, edi; + call eax; + // call dll oep, for dll entry xor eax, eax; push eax; // lpvReserved - inc eax; + inc eax; push eax; // fdwReason, DLL_PROCESS_ATTACH - push [ebx + dllbase]; // hinstDLL - call [ebx+dlloepva]; + mov eax, [ebx + dllrva]; + add eax, edi; + push eax; // hinstDLL + mov eax, [ebx + dlloeprva]; + add eax, edi; + call eax; // jmp to origin oep - jmp [ebx+exeoepva]; + mov eax, [ebx+exeoeprva]; + add eax, edi; + jmp eax; - geteip: + getip: mov eax, [esp] ret - exeoepva: nop;nop;nop;nop; - dllbase: nop;nop;nop;nop; - dlloepva: nop;nop;nop;nop; - memreloc: nop;nop;nop;nop; - membindiat: nop;nop;nop;nop; - membindtls: nop;nop;nop;nop; + exeoeprva: nop;nop;nop;nop; + dllrva: nop;nop;nop;nop; + dlloeprva: nop;nop;nop;nop; + memrelocrva: nop;nop;nop;nop; + membindiatrva: nop;nop;nop;nop; + membindtlsrva: nop;nop;nop;nop; findloadlibrarya: nop;nop;nop;nop; findgetprocaddress: nop;nop;nop;nop; """ @@ -68,7 +102,7 @@ def gen_oepinit_code64(): ks = Ks(KS_ARCH_X86, KS_MODE_64) code_str = f""" // for relative address, get the base of addr - call geteip; + call getip; lea rbx, [rax-5]; push rcx; push rdx; @@ -76,30 +110,58 @@ def gen_oepinit_code64(): push r9; sub rsp, 0x28; // this is for memory 0x10 align + // get the imagebase + mov rax, 0x60; // to avoid relative addressing + mov rdi, qword ptr gs:[rax]; //peb + mov rdi, [rdi + 18h]; //ldr + mov rdi, [rdi + 20h]; //InMemoryOrderLoadList, this + mov rdi, [rdi -10h + 30h]; //this.DllBase + // get loadlibrarya, getprocaddress - call [rbx + findloadlibrarya]; + mov rax, [rbx + findloadlibrarya]; + add rax, rdi; + call rax; mov [rbx + findloadlibrarya], rax; - call [rbx + findgetprocaddress]; + mov rax, [rbx + findgetprocaddress]; + add rax, rdi; + call rax; mov [rbx + findgetprocaddress], rax; + // reloc + mov rcx, [rbx + dllrva]; + add rcx, rdi; + mov rdx, rcx; + mov rax, [rbx + memrelocrva]; + add rax, rdi; + call rax; + // bind iat mov r8, [rbx + findgetprocaddress]; // arg3, getprocaddress mov rdx, [rbx + findloadlibrarya]; // arg2, loadlibraryas - mov rcx, [rbx + dllbase]; // arg1, dllbase value - call [rbx + membindiat]; + mov rcx, [rbx + dllrva]; + add rcx, rdi; // arg1, dllbase value + mov rax, [rbx + membindiatrva]; + add rax, rdi + call rax; // bind tls xor rdx, rdx; inc rdx; // argc, reason for tls - mov rcx, [rbx + dllbase] // arg1, dllbase - call [rbx + membindtls] + mov rcx, [rbx + dllrva] + add rcx, rdi; // arg1, dllbase + mov rax, [rbx + membindtlsrva]; + add rax, rdi; + call rax; // call dll oep, for dll entry xor r8, r8; // lpvReserved xor rdx, rdx; inc rdx; // fdwReason, DLL_PROCESS_ATTACH - mov rcx, [rbx + dllbase]; // hinstDLL - call [rbx+dlloepva]; + mov rcx, [rbx + dllrva]; + add rcx, rdi; // hinstDLL + mov rax, [rbx + dlloeprva]; + add rax, rdi; + call rax; // jmp to origin oep add rsp, 0x28; @@ -107,18 +169,20 @@ def gen_oepinit_code64(): pop r8; pop rdx; pop rcx; - jmp [rbx+exeoepva]; + mov rax, [rbx+exeoeprva]; + add rax, rdi; + jmp rax; - geteip: + getip: mov rax, [rsp] ret - exeoepva: nop;nop;nop;nop;nop;nop;nop;nop; - dllbase: nop;nop;nop;nop;nop;nop;nop;nop; - dlloepva: nop;nop;nop;nop;nop;nop;nop;nop; - memreloc: nop;nop;nop;nop;nop;nop;nop;nop; - membindiat: nop;nop;nop;nop;nop;nop;nop;nop; - membindtls: nop;nop;nop;nop;nop;nop;nop;nop; + exeoeprva: nop;nop;nop;nop;nop;nop;nop;nop; + dllrva: nop;nop;nop;nop;nop;nop;nop;nop; + dlloeprva: nop;nop;nop;nop;nop;nop;nop;nop; + memrelocrva: nop;nop;nop;nop;nop;nop;nop;nop; + membindiatrva: nop;nop;nop;nop;nop;nop;nop;nop; + membindtlsrva: nop;nop;nop;nop;nop;nop;nop;nop; findloadlibrarya: nop;nop;nop;nop;nop;nop;nop;nop; findgetprocaddress: nop;nop;nop;nop;nop;nop;nop;nop; """ @@ -194,4 +258,5 @@ def main(): v0.3, x86 and x64 no need to use exe's LoadLibraryA v0.3.1, fix x64 attach dll crash by align stack with 0x10 v0.3.2, add support for ordinal iat and tls +v0.3.3, add support for aslr """ \ No newline at end of file diff --git a/util b/util index 9960529..c51dea9 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 9960529f7e61f364f9714199ee8f142dbf6ac6b0 +Subproject commit c51dea91c23946987bcdc6510d8bcd3dbd05f64c