flat assembler
Message board for the users of flat assembler.

Index > Windows > Get address function GetProcAddress

Author
Thread Post new topic Reply to topic
bcdsys



Joined: 04 Aug 2008
Posts: 41
bcdsys 30 Oct 2008, 03:27
I'm having problems determining address GetProcAddress. I write program that determines all imports dynamically and without imports. source code:
Code:
;displays "Hello World" without importing anything
;note kernel32.dll always present, but not found in import table
;should work on all windows except some version 2000
format PE GUI

section '.code' code executable readable
entry $

mov eax, [fs:0x30] ;PEB BASE
mov eax, [eax+0xC] ;PEB_LDR_DATA
mov esi, [eax+0x1C]
lodsd
mov ebx, [eax+0x8] ;kernel32 base memory
mov esi, [ebx+0x3C] ;PE header
add esi, ebx
mov esi, [esi+0x78] ;export table
add esi, ebx
mov edi, [esi+0x20] ;export name table
add edi, ebx
mov ecx, [esi+0x14] ;number of exported functions
xor eax, eax ;counter
;ebx=kernel32 base, esi=export name table, ecx=number exported functions, eax=counter
mov edx, esi
.next:
push eax esi edi
mov esi, edx
mov edi, str_GetProcAddress
call strcmp
test eax, eax
jz .done
pop edi esi eax
add edx, 4
inc eax
jmp .next
;ProcAddr = (((counter * 2) + Ordinal) * 4) + AddrTable + Kernel32Base
.done:
pop edi esi eax
mov edx, [esi+0x24] ;export ordinals table
;shl eax, 1
;add eax, edx
shl eax, 2
;add eax, edx
add eax, esi
int3
call beep
ret

;strcmp: compare null terminated string pointed to esi and edi
;return 0 if same, else nonzero
strcmp:
.next:
mov al, [esi]
mov ah, [edi]
cmp al, ah
jnz .nomatch
test al, al
jz .match
test ah, ah
jz .match
inc esi
inc edi
jmp .next
.match:
xor eax, eax
.nomatch: ;since al != ah, eax cannot be 0
ret


beep:
push 1000
push 1000
mov eax, 0x7C837A8F ;Beep
call eax
ret

msg_hello db 'Hello World!', 0
str_Beep db 'Beep', 0
str_GetProcAddress db 'GetProcAddress', 0
str_GetModuleHandle db 'GetModuleHandleA', 0
    


By put int3 and test with debugger I verify that ascii string GetProcAddress was found. However, how determine address function once have address ascii name and index of function in list. I know it can be done, I heard algo ProcAddr = (((counter * 2) + Ordinal) * 4) + AddrTable + Kernel32Base but didn't seem to work, not sure why (prob should, just I did something wrong). I verify if it works if result is 0x7C80AE30 since that is address GetProcAddress on xp system.
Post 30 Oct 2008, 03:27
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 30 Oct 2008, 16:05
bcdsys,

Export name table address is in edi after
Code:
mov edi, [esi+0x20] ;export name table
add edi, ebx    
This table contains RVAs, so you must
Code:
;ebx=kernel32 base, esi=export name table, ecx=number exported functions, eax=counter
;;; ATTN bcdsys
mov edx, edi ;;; NOT esi, it points to export directory table
.next:
push eax esi edi
;;; ATTN bcdsys
mov esi, [edx] ;;; edx points to RVA of the name
add esi, ebx ;;; RVA to VA
mov edi, str_GetProcAddress    
Please read MS PE & COFF specification carefully, it's crucial for such kind of tricks. When you have index into export name pointer table (RVA @ esi+20), the rest is trivial: index export address table (RVA @ esi+1C) with the result. This is the working code sample:
Code:
        format PE GUI

        entry $

        mov     eax, [fs:0x30] ;PEB BASE
        mov     eax, [eax+0xC] ;PEB_LDR_DATA
        mov     esi, [eax+0x1C]
        lodsd
        mov     ebx, [eax+0x8] ;kernel32 base memory
        mov     esi, [ebx+0x3C] ;e_lfanew
        add     esi, ebx        ;esi => PE header
        mov     esi, [esi+0x78] ;export table RVA
        add     esi, ebx        ;esi => export table
        mov     edi, [esi+0x20] ;export name table RVA
        add     edi, ebx        ;edi => export name table
        mov     ecx, [esi+0x14] ;number of exported functions
        xor     eax, eax ;counter
;ebx=kernel32 base, esi=export name table, ecx=number exported functions, eax=counter
        mov     edx, edi
.next:
        push    eax esi edi
        mov     esi, [edx]
        add     esi, ebx
        mov     edi, str_GetProcAddress
        call    strcmp
        test    eax, eax
        pop     edi esi eax
        jz      .done
        add     edx, 4
        inc     eax
        jmp     .next
;ProcAddr = (((counter * 2) + Ordinal) * 4) + AddrTable + Kernel32Base
.done:
        mov     edx, [esi+0x1C]
        add     edx, ebx
        mov     edx, [edx+eax*4]
        add     edx, ebx
        ret     ;;;here edx points to GetProcAddress

;strcmp: compare null terminated string pointed to esi and edi
;return 0 if same, else nonzero
strcmp:
.next:
mov al, [esi]
mov ah, [edi]
cmp al, ah
jnz .nomatch
test al, al
jz .match
test ah, ah
jz .match
inc esi
inc edi
jmp .next
.match:
xor eax, eax
.nomatch: ;since al != ah, eax cannot be 0
ret


beep:
push 1000
push 1000
mov eax, 0x7C837A8F ;Beep
call eax
ret

msg_hello db 'Hello World!', 0
str_Beep db 'Beep', 0
str_GetProcAddress db 'GetProcAddress', 0
str_GetModuleHandle db 'GetModuleHandleA', 0    
By the way, my kernel32.dll, 5.1.2600.3119 (xpsp_sp2_gdr.070416-1301) has it at RVA 0xADA0...
Post 30 Oct 2008, 16:05
View user's profile Send private message Reply with quote
bcdsys



Joined: 04 Aug 2008
Posts: 41
bcdsys 30 Oct 2008, 23:44
Thanks baldr, following hello world code works:
Code:
;displays "Hello World" without importing anything
;note kernel32.dll always present, but not found in import table
;should work on all windows except some version 2000
format PE GUI

section '.code' code executable readable
entry $

mov eax, [fs:0x30] ;PEB BASE
mov eax, [eax+0xC] ;PEB_LDR_DATA
mov esi, [eax+0x1C]
lodsd
mov ebx, [eax+0x8] ;kernel32 base memory
mov esi, [ebx+0x3C] ;PE header
add esi, ebx
mov esi, [esi+0x78] ;export table
add esi, ebx
mov edi, [esi+0x20] ;export name table
add edi, ebx
mov ecx, [esi+0x14] ;number of exported functions
xor eax, eax ;counter
;ebx=kernel32 base, esi=export name table, ecx=number exported functions, eax=counter
mov edx, edi
.next:
push eax esi edi
mov esi, [edx]
add esi, ebx
mov edi, str_GetProcAddress
call strcmp
test eax, eax
jz .done
pop edi esi eax
add edx, 4
inc eax
jmp .next
;ProcAddr = (((counter * 2) + Ordinal) * 4) + AddrTable + Kernel32Base
.done:
pop edi esi eax
mov edx, [esi+0x1C]
add edx, ebx
mov edx, [edx+eax*4]
add edx, ebx
mov ebp, edx
push str_LoadLibrary
push ebx
call edx ;get address LoadLibrary
push str_user32
call eax ;LoadLibrary user32
push str_MessageBox
push eax
call ebp
push 0
push msg_title
push msg_caption
push 0
call eax
ret

;strcmp: compare null terminated string pointed to esi and edi
;return 0 if same, else nonzero
strcmp:
.next:
mov al, [esi]
mov ah, [edi]
cmp al, ah
jnz .nomatch
test al, al
jz .match
test ah, ah
jz .match
inc esi
inc edi
jmp .next
.match:
xor eax, eax
.nomatch: ;since al != ah, eax cannot be 0
ret

msg_title db 'Message Box', 0
msg_caption db 'Hello World!', 0
str_GetProcAddress db 'GetProcAddress', 0
str_GetModuleHandle db 'GetModuleHandleA', 0
str_LoadLibrary db 'LoadLibraryA', 0
str_MessageBox db 'MessageBoxA', 0
str_user32 db 'USER32.DLL', 0
    


>By the way, my
kernel32.dll, 5.1.2600.3119 (xpsp_sp2_gdr.070416-1301) has it at RVA 0xADA0...

It's system dependent, I made util that finds address of proc in module, for my xp sp3 system GetProcAddress is 0x7C80AE30 (and its verified, I used hardcoded address in working shellcode) This is why I want find address in kernel32 and not hardcoded address, since hardcoded change from versions and service packs.
Post 30 Oct 2008, 23:44
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 21 Nov 2008, 02:31
bcdsys wrote:

following hello world code works:
;should work on all windows except some version 2000
mov esi, [eax+0x1C] ; <<<--- PF here Sad


It doesn't Sad
Post 21 Nov 2008, 02:31
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.