Skip to content

Commit

Permalink
v0.3.3, add support for aslr
Browse files Browse the repository at this point in the history
  • Loading branch information
devseed committed Mar 28, 2022
1 parent 1c171b4 commit bf022c6
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 76 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
* ~~support ASLR~~ finished
3 changes: 3 additions & 0 deletions src/memdll/libwinpe.def
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 32 additions & 28 deletions src/memdll/win_injectmemdll.c
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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);
Expand All @@ -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 ,
Expand Down Expand Up @@ -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;
Expand All @@ -123,14 +122,13 @@ int injectdll_mem(const char *exepath,
winpe_appendsecth(mempe_exe, &secth);

// 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");
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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];
Expand Down
153 changes: 109 additions & 44 deletions src/memdll/win_injectmemdll_shellcodestub.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
"""
Expand All @@ -68,57 +102,87 @@ 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;
push r8;
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;
pop r9;
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;
"""
Expand Down Expand Up @@ -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
"""
2 changes: 1 addition & 1 deletion util
Submodule util updated from 996052 to c51dea

0 comments on commit bf022c6

Please sign in to comment.