|
1 | 1 | /* |
2 | 2 | a tool to attach a dll inside a pe file |
3 | | - v0.3, developed by devseed |
| 3 | + v0.3.2, developed by devseed |
4 | 4 |
|
5 | 5 | history: |
6 | | - v0.2, support for x86 |
7 | | - v0.3, add test part, support for x64, optimizing code structure |
| 6 | + see win_injectmemdll_shellcodestub.py |
8 | 7 | */ |
9 | 8 |
|
10 | 9 | #include <stdio.h> |
|
22 | 21 | unsigned char g_oepinit_code[] = {0x90}; |
23 | 22 | unsigned char g_memreloc_code[] = {0x90}; |
24 | 23 | unsigned char g_membindiat_code[] = {0x90}; |
| 24 | +unsigned char g_membindtls_code[] = {0x90}; |
25 | 25 | unsigned char g_findloadlibrarya_code[] = {0x90}; |
26 | | -unsigned char g_memGetProcAddress_code[] = {0x90}; |
| 26 | +unsigned char g_findgetprocaddress_code[] = {0x90}; |
27 | 27 |
|
28 | | -size_t _sectpaddingsize(void *mempe, void *mempe_dll, size_t align) |
| 28 | +void _makeoepcode(void *shellcode, |
| 29 | + size_t shellcodebase, size_t exeimagebase, size_t dllimagebase, |
| 30 | + DWORD exeoeprva, DWORD dlloeprva) |
29 | 31 | { |
30 | | - PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mempe; |
31 | | - PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS) |
32 | | - ((void*)mempe + pDosHeader->e_lfanew); |
33 | | - PIMAGE_FILE_HEADER pFileHeader = &pNtHeader->FileHeader; |
34 | | - PIMAGE_OPTIONAL_HEADER pOptHeader = &pNtHeader->OptionalHeader; |
35 | | - size_t _v = (pOptHeader->SizeOfImage + SHELLCODE_SIZE) % align; |
36 | | - if (_v) return align - _v; |
37 | | - else return 0; |
38 | | -} |
39 | | - |
40 | | -void _oepshellcode(void *mempe_exe, void *mempe_dll, void *shellcode, |
41 | | - size_t shellcodebase, size_t dllimagebase, DWORD orgoeprva) |
42 | | -{ |
43 | | - // PE struct declear |
44 | | - void *mempe; |
45 | | - PIMAGE_DOS_HEADER pDosHeader; |
46 | | - PIMAGE_NT_HEADERS pNtHeader; |
47 | | - PIMAGE_FILE_HEADER pFileHeader; |
48 | | - PIMAGE_OPTIONAL_HEADER pOptHeader; |
49 | | - PIMAGE_DATA_DIRECTORY pDataDirectory; |
50 | | - PIMAGE_DATA_DIRECTORY pImpEntry; |
51 | | - PIMAGE_IMPORT_DESCRIPTOR pImpDescriptor; |
52 | | - PIMAGE_THUNK_DATA pFtThunk = NULL; |
53 | | - PIMAGE_THUNK_DATA pOftThunk = NULL; |
54 | | - LPCSTR pDllName = NULL; |
55 | | - PIMAGE_IMPORT_BY_NAME pFuncName = NULL; |
56 | | - |
57 | 32 | // bind the pointer to buffer |
58 | 33 | size_t oepinit_end = sizeof(g_oepinit_code); |
59 | 34 | size_t memreloc_start = FUNC_SIZE; |
60 | | - size_t memiatbind_start = memreloc_start + FUNC_SIZE; |
61 | | - size_t memfindloadlibrarya_start = memiatbind_start + FUNC_SIZE; |
62 | | - size_t memGetProcAddress_start = memfindloadlibrarya_start + FUNC_SIZE; |
63 | | - size_t *pexeoepva = (size_t*)(g_oepinit_code + oepinit_end - 6*sizeof(size_t)); |
64 | | - size_t *pdllbase = (size_t*)(g_oepinit_code + oepinit_end - 5*sizeof(size_t)); |
65 | | - size_t *pdlloepva = (size_t*)(g_oepinit_code + oepinit_end - 4*sizeof(size_t)); |
66 | | - size_t *pmemiatbind = (size_t*)(g_oepinit_code + oepinit_end - 3*sizeof(size_t)); |
| 35 | + size_t membindiat_start = memreloc_start + FUNC_SIZE; |
| 36 | + size_t membindtls_start = membindiat_start + FUNC_SIZE; |
| 37 | + size_t findloadlibrarya_start = membindtls_start + FUNC_SIZE; |
| 38 | + size_t findgetprocaddress_start = findloadlibrarya_start + FUNC_SIZE; |
| 39 | + |
| 40 | + // fill the address table |
| 41 | + size_t *pexeoepva = (size_t*)(g_oepinit_code + oepinit_end - 8*sizeof(size_t)); |
| 42 | + size_t *pdllbase = (size_t*)(g_oepinit_code + oepinit_end - 7*sizeof(size_t)); |
| 43 | + size_t *pdlloepva = (size_t*)(g_oepinit_code + oepinit_end - 6*sizeof(size_t)); |
| 44 | + size_t *pmemreloc = (size_t*)(g_oepinit_code + oepinit_end - 5*sizeof(size_t)); |
| 45 | + size_t *pmembindiat = (size_t*)(g_oepinit_code + oepinit_end - 4*sizeof(size_t)); |
| 46 | + size_t *pmembindtls = (size_t*)(g_oepinit_code + oepinit_end - 3*sizeof(size_t)); |
67 | 47 | size_t *pfindloadlibrarya = (size_t*)(g_oepinit_code + oepinit_end - 2*sizeof(size_t)); |
68 | | - size_t *pgetprocessaddress = (size_t*)(g_oepinit_code + oepinit_end - 1*sizeof(size_t)); |
69 | | - |
70 | | - // get the information of exe |
71 | | - mempe = mempe_exe; |
72 | | - pDosHeader = (PIMAGE_DOS_HEADER)mempe; |
73 | | - pNtHeader = (PIMAGE_NT_HEADERS)((void*)mempe + pDosHeader->e_lfanew); |
74 | | - pFileHeader = &pNtHeader->FileHeader; |
75 | | - pOptHeader = &pNtHeader->OptionalHeader; |
76 | | - pDataDirectory = pOptHeader->DataDirectory; |
77 | | - pImpEntry = &pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; |
78 | | - pImpDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(mempe + pImpEntry->VirtualAddress); |
79 | | - size_t exeimagebase = pOptHeader->ImageBase; |
80 | | - |
81 | | - // get the information of dll |
82 | | - mempe = mempe_dll; |
83 | | - pDosHeader = (PIMAGE_DOS_HEADER)mempe; |
84 | | - pNtHeader = (PIMAGE_NT_HEADERS)((void*)mempe + pDosHeader->e_lfanew); |
85 | | - pFileHeader = &pNtHeader->FileHeader; |
86 | | - pOptHeader = &pNtHeader->OptionalHeader; |
87 | | - pDataDirectory = pOptHeader->DataDirectory; |
88 | | - DWORD dlloeprva = pOptHeader->AddressOfEntryPoint; |
89 | | - |
90 | | - // fill the address table |
91 | | - *pexeoepva = exeimagebase + orgoeprva; |
| 48 | + size_t *pfindgetprocaddress = (size_t*)(g_oepinit_code + oepinit_end - 1*sizeof(size_t)); |
| 49 | + *pexeoepva = exeimagebase + exeoeprva; |
92 | 50 | *pdllbase = dllimagebase; |
93 | | - *pdlloepva = dllimagebase + pOptHeader->AddressOfEntryPoint; |
94 | | - *pmemiatbind = shellcodebase + memiatbind_start; |
95 | | - *pfindloadlibrarya = shellcodebase + memfindloadlibrarya_start; |
96 | | - *pgetprocessaddress = shellcodebase + memGetProcAddress_start; |
| 51 | + *pdlloepva = dllimagebase + dlloeprva; |
| 52 | + *pmemreloc = shellcodebase + memreloc_start; |
| 53 | + *pmembindiat = shellcodebase + membindiat_start; |
| 54 | + *pmembindtls = shellcodebase + membindtls_start; |
| 55 | + *pfindloadlibrarya = shellcodebase + findloadlibrarya_start; |
| 56 | + *pfindgetprocaddress = shellcodebase + findgetprocaddress_start; |
97 | 57 |
|
98 | 58 | // copy to the target |
99 | | - memcpy(shellcode , g_oepinit_code, sizeof(g_oepinit_code)); |
| 59 | + memcpy(shellcode , |
| 60 | + g_oepinit_code, sizeof(g_oepinit_code)); |
100 | 61 | memcpy(shellcode + memreloc_start, |
101 | 62 | g_memreloc_code, sizeof(g_memreloc_code)); |
102 | | - memcpy(shellcode + memiatbind_start, |
| 63 | + memcpy(shellcode + membindiat_start, |
103 | 64 | g_membindiat_code, sizeof(g_membindiat_code)); |
104 | | - memcpy(shellcode + memfindloadlibrarya_start, |
| 65 | + memcpy(shellcode + membindtls_start, |
| 66 | + g_membindtls_code, sizeof(g_membindtls_code)); |
| 67 | + memcpy(shellcode + findloadlibrarya_start, |
105 | 68 | g_findloadlibrarya_code, sizeof(g_findloadlibrarya_code)); |
106 | | - memcpy(shellcode + memGetProcAddress_start, |
107 | | - g_memGetProcAddress_code, sizeof(g_memGetProcAddress_code)); |
| 69 | + memcpy(shellcode + findgetprocaddress_start, |
| 70 | + g_findgetprocaddress_code, sizeof(g_findgetprocaddress_code)); |
| 71 | +} |
| 72 | + |
| 73 | + |
| 74 | +size_t _sectpaddingsize(void *mempe, void *mempe_dll, size_t align) |
| 75 | +{ |
| 76 | + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mempe; |
| 77 | + PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS) |
| 78 | + ((void*)mempe + pDosHeader->e_lfanew); |
| 79 | + PIMAGE_FILE_HEADER pFileHeader = &pNtHeader->FileHeader; |
| 80 | + PIMAGE_OPTIONAL_HEADER pOptHeader = &pNtHeader->OptionalHeader; |
| 81 | + size_t _v = (pOptHeader->SizeOfImage + SHELLCODE_SIZE) % align; |
| 82 | + if (_v) return align - _v; |
| 83 | + else return 0; |
108 | 84 | } |
109 | 85 |
|
110 | 86 | // memory structure: [exe sections], [shellcode, padding, dll] |
@@ -147,11 +123,13 @@ int injectdll_mem(const char *exepath, |
147 | 123 | winpe_appendsecth(mempe_exe, §h); |
148 | 124 |
|
149 | 125 | // adjust dll addr and append shellcode, iatbind is in runing |
150 | | - DWORD orgoeprva = winpe_oepval(mempe_exe, secth.VirtualAddress); |
151 | 126 | size_t shellcodebase = imgbase_exe + secth.VirtualAddress; |
152 | 127 | size_t dllimagebase = shellcodebase + SHELLCODE_SIZE + padding; |
153 | | - _oepshellcode(mempe_exe, mempe_dll, shellcode, |
154 | | - shellcodebase, dllimagebase, orgoeprva); |
| 128 | + size_t exeimagebase = winpe_imagebaseval(mempe_exe, 0); |
| 129 | + DWORD dlloeprva = winpe_oepval(mempe_dll, 0); |
| 130 | + DWORD exeoeprva = winpe_oepval(mempe_exe, secth.VirtualAddress); |
| 131 | + _makeoepcode(shellcode, shellcodebase, |
| 132 | + exeimagebase, dllimagebase, exeoeprva, dlloeprva); |
155 | 133 | winpe_memreloc(mempe_dll, dllimagebase); |
156 | 134 |
|
157 | 135 | // write data to new exe |
@@ -230,7 +208,7 @@ int main(int argc, char *argv[]) |
230 | 208 | if(argc < 3) |
231 | 209 | { |
232 | 210 | printf("usage: win_injectmemdll exepath dllpath [outpath]\n"); |
233 | | - printf("v0.2, developed by devseed\n"); |
| 211 | + printf("v0.3.2, developed by devseed\n"); |
234 | 212 | return 0; |
235 | 213 | } |
236 | 214 | char outpath[MAX_PATH]; |
|
0 commit comments