Skip to content

Commit 91bf575

Browse files
committed
some pictures
1 parent 76c11ad commit 91bf575

12 files changed

+312
-6
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
/target
2-
shellcodes/

README.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ x86 32bits emulator, for securely emulating shellcodes
99
- 73 instructions implemented
1010

1111

12+
scemu emulates a simple shellcode detecting the execve() interrupt
13+
![exploring basic shellcode](pics/basic_shellcode1.png)
14+
We select the line to stop and inspect the memory
15+
![inspecting basic shellcode](pics/basic_shellcode2.png)
1216

13-
14-
[![IMAGE ALT TEXT](http://img.youtube.com/vi/RV8Q9MBWovQ/0.jpg)](https://www.youtube.com/embed/RV8Q9MBWovQ "mapping in emulation time")
15-
16-
[![IMAGE ALT TEXT](http://img.youtube.com/vi/u12UBNB_5wU/0.jpg)](https://www.youtube.com/embed/u12UBNB_5wU "execution flow")
17-
17+
After emulatin near 2 million instructions of GuLoader win32 in linux, faking cpuid's and other tricks in the way, arrives to a sigtrap to confuse debuggers.
18+
Guloader win32 after
19+
![exception handlers](pics/guloader1.png)

pics/basic_shellcode1.png

58.1 KB
Loading

pics/basic_shellcode2.png

70.6 KB
Loading

pics/guloader1.png

114 KB
Loading

shellcodes/basic-win32.asm

+291
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
BITS 32 ;using x86 architecture
2+
3+
;---------------------------
4+
;definition
5+
%define u16(x) __utf16__(x)
6+
%define IMG_DOS_OFFSET 0x3C ;offset to pe offset
7+
%define IMG_PE_EXP_OFFSET 0x78 ;offset to export directory address
8+
9+
;--------------------------- proc 1
10+
;code block
11+
entry_point:
12+
pushad
13+
sub esp, 4 ;define local var
14+
;calc delta
15+
call get_eip
16+
get_eip:
17+
pop ebx ;pop up virtual address to eax
18+
sub ebx, get_eip - entry_point ;offset normalize
19+
20+
;search ntdll address
21+
mov eax, wphr_ntdll
22+
add eax, ebx
23+
push eax
24+
call find_module_address
25+
test eax, eax
26+
je end_shell
27+
mov [esp], eax
28+
29+
;search ldrloaddll
30+
mov eax, phr_ldrloaddll
31+
add eax, ebx
32+
push eax
33+
mov eax, [esp + 4]
34+
push eax
35+
call search_export_proc
36+
37+
;load user32.dll
38+
sub esp, 12 ;alloc sizeof(UNICODE_STRING) + sizeof(PHANDLE)
39+
40+
xor edx, edx
41+
mov [esp + 8], edx ;set handle = NULL
42+
mov edx, wphr_user32 ;put UNICODE_STRING.Buffer
43+
add edx, ebx
44+
mov [esp + 4], edx
45+
mov dx, 22 ;wcslen(phr_user32) * 2 + 2, UNICODE_STRING.MaximumLength
46+
shl edx, 16
47+
mov dx, 20 ;wcslen(phr_user32) * 2, UNICODE_STRING.Length
48+
mov [esp], edx
49+
50+
mov edx, esp
51+
add edx, 8
52+
push edx
53+
mov edx, esp
54+
add edx, 4
55+
push edx
56+
push 0
57+
push 0
58+
call eax ;call LdrLoadDll
59+
mov eax, [esp + 8]
60+
add esp, 12
61+
test eax, eax
62+
je end_shell
63+
64+
;search messagebox
65+
mov edx, phr_msgbox
66+
add edx, ebx
67+
push edx
68+
push eax
69+
call search_export_proc
70+
test eax, eax
71+
je end_shell
72+
73+
;call messagebox
74+
push 0
75+
mov edx, msg_title
76+
add edx, ebx
77+
push edx
78+
mov edx, msg_string
79+
add edx, ebx
80+
push edx
81+
push 0
82+
call eax
83+
84+
end_shell:
85+
add esp, 4
86+
popad
87+
retn
88+
89+
;------------------ proc 2
90+
find_module_address: ;find_module_address(stack wlib_name)
91+
push ebx ;save context value
92+
;getting PEB
93+
mov ebx, dword [fs:0x30]
94+
test ebx, ebx
95+
js retn_label_2
96+
97+
;getting first LDR_MODULE
98+
mov ebx, dword [ebx + 0x0C]
99+
mov ebx, dword [ebx + 0x1C]
100+
mov ebx, dword [ebx]
101+
push ebx ;save in stack
102+
103+
whiling:
104+
mov eax, dword [ebx + 0x20] ;getting module unicode name
105+
test eax, eax ;if name == NULL continue
106+
je calc_next
107+
108+
;compare stings
109+
push eax
110+
mov eax, dword [esp + 16]
111+
push eax
112+
call wstrcmp
113+
test eax, eax
114+
jne retn_ok_2
115+
116+
;set next module
117+
calc_next:
118+
mov eax, dword [ebx]
119+
mov ecx, dword [esp]
120+
cmp eax, ecx ;if end of list => break
121+
je retn_error_2
122+
mov ebx, eax
123+
jmp whiling
124+
125+
retn_error_2:
126+
xor eax, eax
127+
jmp retn_label_2
128+
retn_ok_2:
129+
mov eax, dword[ebx + 8] ;put return value
130+
retn_label_2:
131+
add esp, 4 ;clear args
132+
pop ebx ;restore context value
133+
retn 4
134+
135+
;------------------ proc 3
136+
wstrcmp: ;wstrcmp(stack wstr1, stack wstr2)
137+
whiling_3:
138+
;put wchar to dx
139+
mov esi, dword [esp + 4]
140+
lodsw
141+
mov dword [esp + 4], esi
142+
mov dx, ax
143+
144+
;put wchar to ax
145+
mov esi, dword [esp + 8]
146+
lodsw
147+
mov dword [esp + 8], esi
148+
149+
;compare
150+
cmp ax, dx
151+
jne retn_error
152+
153+
;break if EOS
154+
cmp ax, 0
155+
je retn_ok
156+
157+
jmp whiling_3
158+
retn_ok:
159+
mov eax, 1
160+
retn 8
161+
retn_error:
162+
xor eax, eax
163+
retn 8
164+
165+
;------------------ proc 4
166+
strcmp: ;strcmp(stack wstr1, stack wstr2)
167+
xor eax, eax
168+
xor edx, edx
169+
strcmp_whiling:
170+
;put wchar to dx
171+
mov esi, dword [esp + 4]
172+
lodsb
173+
mov dword [esp + 4], esi
174+
mov dx, ax
175+
176+
;put wchar to ax
177+
mov esi, dword [esp + 8]
178+
lodsb
179+
mov dword [esp + 8], esi
180+
181+
;compare
182+
cmp ax, dx
183+
jne strcmp_retn_error
184+
185+
;break if EOS
186+
cmp ax, 0
187+
je strcmp_retn_ok
188+
189+
jmp strcmp_whiling
190+
strcmp_retn_ok:
191+
mov eax, 1
192+
retn 8
193+
strcmp_retn_error:
194+
xor eax, eax
195+
retn 8
196+
197+
;------------------ proc 5
198+
search_export_proc: ;search_import_proc(stack lib_addr, stack lib_name)
199+
push ebx ;save context value
200+
sub esp, 12 ;0 - AddressOfNames, 4 - AddressOfNameOrdinals, 8 - AddressOfFunctions, 12 - ebx, 16 - retn addr, 20 - lib_addr, 24 - lib_name
201+
202+
;put to eax PE header VA
203+
mov eax, [esp + 20]
204+
add eax, IMG_DOS_OFFSET
205+
mov eax, [eax]
206+
add eax, [esp + 20] ;RVA -> VA
207+
208+
;put to eax PE export descriptor VA
209+
add eax, IMG_PE_EXP_OFFSET
210+
test eax, eax
211+
je retn_label_5
212+
mov eax, [eax]
213+
add eax, [esp + 20] ;RVA -> VA
214+
215+
;put to ecx NumberOfNames
216+
add eax, 24
217+
mov ecx, [eax]
218+
add eax, 4
219+
;put to stack VA AddressOfFunctions
220+
mov edx, [eax]
221+
add edx, [esp + 20] ;RVA -> VA
222+
mov [esp + 8], edx ;save RVA AddressOfFunctions
223+
add eax, 4
224+
;put to stack VA AddressOfNames
225+
mov edx, [eax] ;put to eax RVA AddressOfNames
226+
add edx, [esp + 20] ;RVA -> VA
227+
mov [esp], edx ;save RVA AddressOfNames
228+
add eax, 4
229+
;put to stack VA AddressOfNameOrdinals
230+
mov eax, [eax]
231+
add eax, [esp + 20] ;RVA -> VA
232+
mov [esp + 4], eax ;save RVA AddressOfNameOrdinals
233+
add eax, 4
234+
;searching procedure name
235+
xor eax, eax
236+
xor edi, edi
237+
whiling_5:
238+
;if count == 0 break
239+
test ecx, ecx
240+
je retn_label_5
241+
dec ecx
242+
243+
;compare
244+
mov eax, [esp]
245+
mov edx, eax ;ptr ++
246+
add edx, 4
247+
mov [esp], edx
248+
mov eax, [eax]
249+
add eax, [esp + 20]
250+
push eax
251+
mov eax, [esp + 28]
252+
push eax
253+
call strcmp
254+
test eax, eax
255+
jne break_5
256+
257+
inc edi ;index ++
258+
jmp whiling_5
259+
break_5:
260+
261+
;searching procedure address
262+
mov eax, 2
263+
mul edi
264+
add eax, [esp + 4]
265+
xor edx, edx
266+
mov dx, [eax]
267+
;add eax, [esp + 20]
268+
mov eax, 4
269+
mul edx
270+
add eax, [esp + 8]
271+
mov eax, [eax]
272+
add eax, [esp + 20]
273+
274+
275+
retn_label_5:
276+
add esp, 12
277+
pop ebx ;restore context value
278+
retn 8
279+
280+
;---------------------------
281+
;internal data block
282+
msg_title: db 'Message', 0
283+
msg_string: db 'Hello Peoplz', 0
284+
wphr_ntdll dw u16('ntdll.dll'), 0, 0
285+
phr_ldrloaddll db 'LdrLoadDll', 0, 0, 0, 0
286+
wphr_user32 db u16('user32.dll'), 0, 0
287+
phr_msgbox db 'MessageBoxA', 0
288+
289+
;---------------------------
290+
;input data block
291+
; not used

shellcodes/basic-win32.bin

584 Bytes
Binary file not shown.

shellcodes/basic_linux.bin

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
�$^�t$1��D$�D$ � ��L$�T$ ̀1ۉ�@̀�����/bin/sh

shellcodes/guloader.bin

84 KB
Binary file not shown.

shellcodes/xloader.bin

1.21 MB
Binary file not shown.

src/emu32.rs

+11
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,17 @@ impl Emu32 {
922922
let addr = u32::from_str_radix(con.cmd().as_str().trim_start_matches("0x"), 16).expect("bad num conversion");
923923
self.maps.dump(addr);
924924
},
925+
"ms" => {
926+
con.print("address");
927+
let addr = u32::from_str_radix(con.cmd().as_str().trim_start_matches("0x"), 16).expect("bad num conversion");
928+
println!("{}", self.maps.read_string(addr));
929+
930+
},
931+
"mw" => {
932+
con.print("address");
933+
let addr = u32::from_str_radix(con.cmd().as_str().trim_start_matches("0x"), 16).expect("bad num conversion");
934+
println!("{}", self.maps.read_wide_string(addr));
935+
},
925936
"eip" => {
926937
con.print("=");
927938
let saddr = con.cmd();

src/emu32/console.rs

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ impl Console {
4545
println!("mr ..................... memory read, speficy ie: dword ptr [esi]");
4646
println!("mw ..................... memory read, speficy ie: dword ptr [esi] and then: 1af");
4747
println!("md ..................... memory dump");
48+
println!("ms ..................... memory string");
49+
println!("mw ..................... memory wide string");
4850
println!("ss ..................... search string");
4951
println!("sb ..................... search bytes");
5052
println!("");

0 commit comments

Comments
 (0)