format pe gui 4.0

include 'C:\fasm\include\win32ax.inc'

.data
   _mzKernel dd ? ; Position of Kernel32.dll in memory
   _miGetProcAddres dd ? ; Api GetProcAddress
   _miLoadLibrary dd ?
   _mzUser dd ?
   _MessageBox dd ?
   lpBuffer rb 1024

.code

; Function that return in eax the address of Kernel32.dll
; and in ebx the address of GetProcAddres.
proc LocateAPIs, OriginalEBP
 locals
   mzKernel dd ? ; Direction in memory of kernel32.dll (MZ)
   peKernel dd ? ; Pe signature of kernel32.dll
   etKernel dd ? ; Direction of export table of kernel32.dll
   anKernel dd ? ; AddressOfNames of kernel32.dll
   dirGPA dd ? ; Direction of GetProcAddres
   miGetProcAddres dd ? ; Api GetProcAddress
   miLoadLibrary dd ?
   mzUser dd ?
 endl

	
	;Get dos siganute & pe siganature of kernel32.dll
	;mov esi, dword[esp]
	mov esi, [OriginalEBP]
	and esi, 0xFFFF0000
	DIR_KERNEL:
		sub esi, 0x1000
		cmp word[esi], 'MZ'
		jne DIR_KERNEL
		mov [mzKernel], esi
		mov eax, esi
		add esi, dword[eax+0x3C]
		mov [peKernel], esi

		;Get direction of Export Table (eax=MZ, esi=PE)
		add esi, 0x78
		add eax, dword[esi]
		mov [etKernel], eax

		; Get pointer to fist RVA of api's names (eax=ExporTable)
		mov ebx, [mzKernel]
		add ebx, dword[eax+0x20] ; AddressOfNames
		mov [anKernel], ebx

		; Locate GetProcAddress
		mov edi, [anKernel]
		xor ecx, ecx

	DIR_GPA:
		mov ebx, [mzKernel]
		add ebx, dword[edi]
		cmp dword[ebx], 'GetP'
		je PUEDE_SER
	NO_ES:
		add edi, 4
		inc ecx
		jmp DIR_GPA
	PUEDE_SER:
		cmp dword[ebx+4] , 'rocA'
		jne NO_ES
		cmp dword[ebx+8], 'ddre'
		mov edi, ecx

	; Get the ordinal of GetProcAddress
		mov eax, [etKernel]
		mov ebx, [mzKernel]
		add eax, 0x24 ; AddressOfOrdinals
		add ebx, dword[eax]
		rol ecx, 1 ; ecx*2
		add ebx, ecx

	; Get direction of GetProcAdress
		xor ecx, ecx
		movzx ecx, word[ebx]
		rol ecx, 2 ; ecx*4
		mov eax, [etKernel]
		mov ebx, [mzKernel]
		add eax, 0x1C ; AddressOfFunctions
		add ebx, dword[eax]
		add ebx, ecx ; ebx = Puntero a la dirección de GetProcAddress
		mov eax, dword[ebx]
		add eax, [mzKernel]
		mov [dirGPA], eax
		mov eax, [mzKernel]
		mov ebx, [dirGPA]
		mov [mzKernel], eax
		mov [miGetProcAddres], ebx
		mov   eax, [mzKernel]
		mov   [_mzKernel], eax
		mov   eax, [miGetProcAddres]
		mov   [_miGetProcAddres], eax
		mov	eax, [mzUser]
		mov   [_mzUser],  eax
		mov	eax, [miLoadLibrary]
		mov   [_miLoadLibrary], eax
		ret
endp



Start:
	mov eax,[esp]	      ;get stack 'kernell' value
	mov ecx,050h		   ;page numbers,...-1 could be good too



	stdcall LocateAPIs, eax
	invoke _miGetProcAddres, [_mzKernel], 'LoadLibraryA'
	mov    [_miLoadLibrary], eax
	invoke _miLoadLibrary, "user32.dll"
	mov   [_mzUser], eax
	invoke		 _miGetProcAddres, [_mzUser], 'MessageBoxA'
	mov		 [_MessageBox], eax
	invoke _MessageBox, 0,'this is a test', 'Test Test Test',0
	invoke ExitProcess, 0

.end Start

