Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f224b08

Browse files
+ 32bit ntdll-only shellcode
1 parent 8bcb3bb commit f224b08

File tree

4 files changed

+85
-20
lines changed

4 files changed

+85
-20
lines changed

‎src/handler.cpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ NTSTATUS on_create_proc_status(HANDLE parent_pid, HANDLE pid, BOOLEAN create) {
8181

8282
// get entrypoint va
8383
if (a.b == bit::x32) {
84-
return status;
8584
auto nt = addroffset(IMAGE_NT_HEADERS32, base, base->e_lfanew);
8685
entrypoint = addroffset(void, base, nt->OptionalHeader.AddressOfEntryPoint);
8786
}

‎src/hook.cpp‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,19 @@ void hook32(void* func, void* target) {
4747
target = addroffset(void, target, STUB_SIZE32);
4848

4949
void* module_file = target;
50-
const char module_file_str[] = "gi_agent.dll";
51-
write_str(&target, module_file_str);
50+
const wchar_t module_file_str[] = L"gi_agent.dll";
51+
write_wstr(&target, module_file_str);
52+
53+
// write UNICODE_STRING for module_file
54+
void* module_file_unicode = target;
55+
UNICODE_STRING32 module_file_unicode_str;
56+
// length (not including null terminator)
57+
module_file_unicode_str.Length = sizeof(module_file_str) - sizeof(module_file_str[0]);
58+
// maximum length (including null terminator)
59+
module_file_unicode_str.MaximumLength = sizeof(module_file_str);
60+
// buffer; ptr to actual wstr
61+
module_file_unicode_str.Buffer = towow64(module_file);
62+
write_type<UNICODE_STRING32>(&target, module_file_unicode_str);
5263

5364
// overwrite original code
5465
// jmp shellcode
@@ -63,8 +74,9 @@ void hook32(void* func, void* target) {
6374
write_type<UINT32>(&target, STUB_SIZE32);
6475

6576
write_bytes(&target, { 0x68 }); // push
66-
write_type<UINT32>(&target, towow64(module_file));
77+
write_type<UINT32>(&target, towow64(module_file_unicode));
6778

79+
// not needed anymore but im keeping it so i dont have to change the shellcode :p
6880
write_bytes(&target, { 0x68 }); // push
6981
write_type<UINT32>(&target, sizeof(module_file_str));
7082

@@ -93,14 +105,14 @@ void hook64(void* func, void* target) {
93105

94106
// write UNICODE_STRING for module_file
95107
void* module_file_unicode = target;
96-
UNICODE_STRING module_file_unicode_str;
108+
UNICODE_STRING64 module_file_unicode_str;
97109
// length (not including null terminator)
98110
module_file_unicode_str.Length = sizeof(module_file_str) - sizeof(module_file_str[0]);
99111
// maximum length (including null terminator)
100112
module_file_unicode_str.MaximumLength = sizeof(module_file_str);
101113
// buffer; ptr to actual wstr
102-
module_file_unicode_str.Buffer = reinterpret_cast<PWCH>(module_file);
103-
write_type<UNICODE_STRING>(&target, module_file_unicode_str);
114+
module_file_unicode_str.Buffer = reinterpret_cast<ULONGLONG>(module_file);
115+
write_type<UNICODE_STRING64>(&target, module_file_unicode_str);
104116

105117
// shellcode stub
106118
void* shellcode_stub = target;

‎src/shellcode/shellcode32.asm‎

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ push ebp
2626
movebp,esp ; frame pointer points to start of args
2727
addebp, ptrsz
2828
pushad ; we dont know what the target exe might expect from the windows loader environment
29+
; so just save the entire environment
2930

3031
; traverse the teb/peb to get the kernel32 base address
3132

@@ -38,11 +39,12 @@ mov ebx, [ecx] ; first entry is the exe image itself
3839
movebx,[ebx+ listentry.flink] ; next entry is ntdll
3940
cmpebx,ecx ; found end of list?
4041
je .exit
41-
movebx,[ebx+ listentry.flink] ; and now kernel32
42-
cmpebx,ecx ; end of list?
43-
je .exit
42+
; mov ebx, [ebx + listentry.flink] ; and now kernel32
43+
; cmp ebx, ecx ; end of list?
44+
; je .exit
45+
4446
; difference between dllbase field and flink (where we land)
45-
; so ebx now holds the kernel32 base address
47+
; so ebx now holds the ntdll base address
4648
movebx,[ebx+ ldrentry.base - ldrentry.links]
4749

4850
; eip relative access on x86-32asm
@@ -55,18 +57,32 @@ call resolve_export
5557

5658
pusheax ; save virtualprotect addr for second call
5759

60+
; save original func ptr (modified in vprotect call)
61+
push dword [ebp]
62+
; save original code size
63+
push dword [ebp+ ptrsz *3]
64+
5865
; make original func writable
5966
push0 ; space for old protect
6067
pushesp ; old protect ptr
6168
push4 ; PAGE_READWRITE
62-
push dword [ebp+ ptrsz *3] ; original code size (param)
63-
push dword [ebp] ; original func
69+
leaedx,[ebp+ ptrsz *3] ; original code size *
70+
pushedx
71+
pushebp ; original func *
72+
push-1 ; current process pseudo-handle
6473
calleax
6574

6675
testeax,eax
6776
popedx ; old protect
77+
; restore original code size
78+
popeax
79+
mov dword [ebp+ ptrsz *3],eax
80+
; restore original func ptr
81+
popeax
82+
mov dword [ebp],eax
6883
popeax ; saved virtual protect addr
69-
jz .exit
84+
85+
jnz .exit
7086

7187
; restore original code (memcpy)
7288
movecx,[ebp+ ptrsz *3] ; original code size (param)
@@ -77,17 +93,47 @@ rep movsb ; memcpy
7793

7894
; restore previous protection
7995

96+
; save original func ptr (modified in vprotect call)
97+
push dword [ebp]
98+
; save original code size
99+
push dword [ebp+ ptrsz *3]
100+
80101
push0 ; space for old protect
81102
pushesp ; old protect ptr
82103
pushedx ; new protect (previous value)
83-
push dword [ebp+ ptrsz *3] ; original code size (param)
84-
push dword [ebp] ; original func
104+
leaedx,[ebp+ ptrsz *3] ; original code size *
105+
pushedx
106+
pushebp ; original func *
107+
push-1 ; current process pseudo-handle
85108
calleax
86109

87110
addesp, ptrsz ; remove old page protection
88111

89112
testeax,eax
90-
jz .exit
113+
114+
; restore original code size
115+
popeax
116+
mov dword [ebp+ ptrsz *3],eax
117+
; restore original func ptr
118+
popeax
119+
mov dword [ebp],eax
120+
121+
jnz .exit
122+
123+
; check if k32 is loaded
124+
; if not: exit
125+
movedx,fs:[teb.peb] ; PEB from TEB
126+
movedx,[edx+ peb.ldr] ; LDR from PEB
127+
; the address of the pointer to the first entry
128+
; last entry will point to this so we can check if the list is exhausted
129+
leaecx,[edx+ ldr.modules + listentry.flink] ; addressof modules pointer
130+
movedx,[ecx] ; first entry is the exe image itself
131+
movedx,[edx+ listentry.flink] ; next entry is ntdll
132+
cmpedx,ecx ; found end of list?
133+
je .exit
134+
movedx,[edx+ listentry.flink] ; and now kernel32
135+
cmpedx,ecx ; end of list?
136+
je .exit
91137

92138
; load library
93139

@@ -101,9 +147,15 @@ push ebx
101147
call resolve_export
102148

103149
movecx,[ebp+ ptrsz *2]
150+
push0
151+
pushesp ; return base address
104152
pushecx ; dllname
153+
push0 ; characteristics
154+
push0 ; search path
105155
calleax ; loadlibrarya
106156

157+
popeax ; dump return base addr
158+
107159
.exit:
108160
popad
109161
popebp
@@ -168,8 +220,8 @@ pop esp
168220
ret3* ptrsz ; cleanup arguments
169221

170222
; static data "segment"
171-
load_lib_str db "LoadLibraryA",0
223+
load_lib_str db "LdrLoadDll",0
172224
sz_load_lib_str equ $ - load_lib_str
173225

174-
vprotect_str db "VirtualProtect",0
226+
vprotect_str db "NtProtectVirtualMemory",0
175227
sz_vprotect_str equ $ - vprotect_str

‎src/shellcode/shellcode64.asm‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ test rax, rax
115115
jnz .exit
116116

117117
; check if k32 is loaded
118-
; if not; exit
118+
; if not: exit
119119
movrdx,gs:[teb.peb] ; PEB from TEB
120120
testrdx,rdx
121121
jz .exit
@@ -138,6 +138,8 @@ mov rdx, [rdx + listentry.flink] ; kernel32
138138
cmprdx,rcx ; end of list?
139139
je .exit
140140

141+
; load library
142+
141143
movrcx, sz_load_lib_str
142144
leardx,[load_lib_str]
143145
movr8,rbx ; base addr

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /