Hi,
Can anyone tell me what did the GetProcAddress return? I mean the returned value in EAX means what? It really point to what?
Can anyone tell me what did the GetProcAddress return? I mean the returned value in EAX means what? It really point to what?
The address of the function you wanted to get.
this is why i read the manual :lol:
taken from:
MSDN - GetProcAddress
bye
taken from:
MSDN - GetProcAddress
Return Values
If the function succeeds, the return value is the address of the exported function or variable.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
If the function succeeds, the return value is the address of the exported function or variable.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
bye
microstar_top,
Welcome to the forum.
Here is a simple example for you. The application loads user32.dll and gets the address of MessageBoxA
Welcome to the forum.
Here is a simple example for you. The application loads user32.dll and gets the address of MessageBoxA
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.data
user32 db 'user32.dll',0
msgbox db 'MessageBoxA',0
caption db 'GetProcAddress example',0
.code
start:
invoke LoadLibrary,ADDR user32
push eax
invoke GetProcAddress,eax,ADDR msgbox
push MB_OK
push OFFSET msgbox
push OFFSET msgbox
push 0
call eax
pop eax
invoke FreeLibrary,eax
invoke ExitProcess,0
END start
under 9x, due to inconsistencies, GetProcAddress sometimes returns a thunk in the kernel of that particular API - something definitely to watch out for.
Thanks for all of your reply,easpecially Vortex's excellent sample. If I want to inject some code into other process's address space, should I relocate all the calls to these APIs? what should I do. That's the reason why I want to know the secret of GetProcAddress. What did the return value means, if I want to inject API's call into other process's space, how should i modify such codes to ensure they can perform properly?
I'm sorry for my English!
Thanks again for all of yours reply!
I'm sorry for my English!
Thanks again for all of yours reply!
Ok as I understand you wanna insert your code in another process, but
you have some troubles with implementing that... Well there are 2 tehniques that I'm aware of ->>>
First is to code your own win32 shellcode (includes locating kernel32.dll base and writing your own GetProcAddress) and use CreateProcess with SUSPENDED flag, inject code, ResumeThread =)
Second is more simple and it consist of DLL injecting...
2nd tehnique is much better b/c you don't have to play with troubles that come with real shellcode coding... it's boring in Windows, and more fun in Unix =) My smallest execve shellcode for Linux and aslo *BSD systems was 21 bytes, but at windows... huh toooo large =) I hate that =)
Ok DLL ijecting is simple tehnique which consist of injecting your dll in another process memory space...
1. find right process
2. OpenProcess
3. use VirtualAllocEx to alloacte memory for dll name
4. use WriteProcessMemory to write dll name at allocated memory
5. Find LoadLibraryA address
6. CreateRemoteThread
7. DLL is injected...
8. Havefun =)
e =)you can find these codes at http://nonenone.cjb.net/example.zip
you have some troubles with implementing that... Well there are 2 tehniques that I'm aware of ->>>
First is to code your own win32 shellcode (includes locating kernel32.dll base and writing your own GetProcAddress) and use CreateProcess with SUSPENDED flag, inject code, ResumeThread =)
Second is more simple and it consist of DLL injecting...
2nd tehnique is much better b/c you don't have to play with troubles that come with real shellcode coding... it's boring in Windows, and more fun in Unix =) My smallest execve shellcode for Linux and aslo *BSD systems was 21 bytes, but at windows... huh toooo large =) I hate that =)
Ok DLL ijecting is simple tehnique which consist of injecting your dll in another process memory space...
1. find right process
2. OpenProcess
3. use VirtualAllocEx to alloacte memory for dll name
4. use WriteProcessMemory to write dll name at allocated memory
5. Find LoadLibraryA address
6. CreateRemoteThread
7. DLL is injected...
8. Havefun =)
e =)you can find these codes at http://nonenone.cjb.net/example.zip
microstar_top,
Here is a simulation of GetProcAddress
Thanks to Axial for his code:
Here is a simulation of GetProcAddress
Thanks to Axial for his code:
; ebp holds a delta offset
szGetProcAddress db "GetProcAddress",0
GPASIZE = $ - szGetProcAddress
ApiCounter dd 0
GetGetProcAddressAddress proc
and dword ptr [ebp + ApiCounter],0
mov edi,dword ptr [eax+3Ch] ; kernel PE hdr
add edi,eax ; add image base
assume edi:ptr IMAGE_NT_HEADERS
mov edi,[edi].OptionalHeader.DataDirectory.VirtualAddress
add edi,eax
assume edi:ptr IMAGE_EXPORT_DIRECTORY
mov ecx,[edi].NumberOfNames
mov esi,[edi].AddressOfNames
add esi,eax
xchg eax,ebx
MatchLp:
lodsd
add eax,ebx
push ecx
push edi
push esi
push GPASIZE
pop ecx
lea edi,[ebp+szGetProcAddress]
mov esi,eax
repz cmpsb
pop esi
pop edi
jecxz GPA_found
inc dword ptr [ebp + ApiCounter]
pop ecx
dec ecx
jnz MatchLp
xor eax, eax ; error
ret
GPA_found:
mov esi,[edi].AddressOfNameOrdinals
pop ecx
mov ecx,dword ptr [ebp + ApiCounter]
shl ecx,1
add esi,ecx
add esi,ebx
xor eax,eax
lodsw
shl eax,2
add eax,[edi].AddressOfFunctions
mov esi,eax
add esi,ebx
lodsd
add eax,ebx
assume edi :nothing
ret
GetGetProcAddressAddress endp
Posted on 2004-12-04 00:16:05 by microstar_top
no problem man =)
Vortex, what happens if you run that GPA on NT and there's a forwarded export? :)
under 9x, due to inconsistencies, GetProcAddress sometimes returns a thunk in the kernel of that particular API - something definitely to watch out for.
Hi :)
What do you mean by a thunk? When does this happen exactly? :?:
Vortex, what happens if you run that GPA on NT and there's a forwarded export? :)
The solution is very easy, you will fix it if something is going wrong :)
After reading Vorex's post, I've thought a lot . Under Windows NT, GetProcAddress actually return the start address of the specified function. Because dlls in different process may be mapped in different regtion, so we must scan the export data directory to get the real start address. But I found the system dlls such as kernel32,user32 ,the system will always map them into the same address space in the higher memory region. So I wrote a demo to inject code into notepad process in a lazy way . The code run properly under Windows 2000.
I'm a freshman in Assembly language and system functions. If something was wrong with the code, tell me . Or you know other more efficient way, just tell me. Thanks.
Have Fun! :lol:
I'm a freshman in Assembly language and system functions. If something was wrong with the code, tell me . Or you know other more efficient way, just tell me. Thanks.
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.data
lpMessageBox dd ?
lpGetModuleHandle dd ?
dwProcessId dd ?
hProcess dd ?
hKernel dd ?
hUser dd ?
hNotepad dd ?
lpBeginAddress dd ?
.const
szClassName db 'Notepad',0
szKernel db 'kernel32.dll',0
szUser db 'user32.dll',0
szMessageBoxA db 'MessageBoxA',0
szGetModule db 'GetModuleHandleA',0
.code
include injected.asm
Start:
;Get handle of kernel32
invoke GetModuleHandle,offset szKernel
mov hKernel,eax
;Get handle of user32
invoke GetModuleHandle,offset szUser
mov hUser,eax
invoke GetProcAddress,eax,offset szMessageBoxA
mov lpMessageBox,eax
invoke GetProcAddress,hKernel,offset szGetModule
mov lpGetModuleHandle,eax
; Find window(Notepad)
invoke FindWindow,offset szClassName,NULL
mov hNotepad,eax
invoke GetWindowThreadProcessId,eax,offset dwProcessId
; Open notepad process and get process handle
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,dwProcessId
mov hProcess,eax
invoke VirtualAllocEx,eax,NULL,REMOTE_CODE_LEN,MEM_COMMIT,PAGE_EXECUTE_READWRITE
mov lpBeginAddress,eax
invoke WriteProcessMemory,hProcess,eax,offset REMOTE_CODE_START,REMOTE_CODE_LEN,NULL
invoke WriteProcessMemory,hProcess,lpBeginAddress,offset lpMessageBox,sizeof dword * 2,NULL
mov eax,lpBeginAddress
add eax,offset remote - offset REMOTE_CODE_START
invoke CreateRemoteThread,hProcess,NULL,0,eax,NULL,0,NULL
; close thread handle
invoke CloseHandle,eax
; close process handle
invoke CloseHandle,hProcess
invoke ExitProcess,NULL
end Start
REMOTE_CODE_START equ this byte
lpMessageBoxRemote dd ?
lpGetModule dd ?
hInstance dd ?
szCaption db 'Remote',0
szContent db 'The code executed now is injected by another process!',0
remote proc uses esi ebx edi lParam
local @hModule
call @f
@@:
;ebx is the offset between original address and new address
pop ebx
sub ebx,offset @b
push NULL
lea esi,lpGetModule
add esi,ebx
call dword ptr [esi]
lea esi,hInstance
add esi,ebx
; mov [ebx + offset hInstance],eax
mov esi,eax
push MB_OK
lea esi,offset szCaption
add esi,ebx
push esi
lea esi,offset szContent
add esi,ebx
push esi
lea esi,offset hInstance
add esi,ebx
push [esi]
lea esi,lpMessageBoxRemote
add esi,ebx
call dword ptr [esi]
ret
remote endp
REMOTE_CODE_END equ this byte
REMOTE_CODE_LEN equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
Have Fun! :lol:
include injected.asm
Is looks like that this file is missing, am I wrong?
It could be also usefull to check how LSD solved fork()-ing under windows =) Very nice tehnique and it also has a nice explanation of suspend/resume thread and managing thread context... very easy to understand...
http://lsd-pl.net and look for Windows assembly components
http://lsd-pl.net and look for Windows assembly components
The Code from REMOTE_CODE_START to the end is the content of injected.asm. I forgot to write down the file's name.
Ok probably didn't tell you that GetProcAddress is capable of finding APIs by ordinal :
where 238 is ordinal in ntdll.dll for NtQueryInformationProcess at WinXP SP1 =)
So complete engine for rewriting GetProcAddress if you wanna hook it and see when is it used... A really didn't know that this API is called so many times during DLL initialisation... So here is complete code on rewriteing GetProcAddress
invoke GetProcAddress, handle, 238
where 238 is ordinal in ntdll.dll for NtQueryInformationProcess at WinXP SP1 =)
So complete engine for rewriting GetProcAddress if you wanna hook it and see when is it used... A really didn't know that this API is called so many times during DLL initialisation... So here is complete code on rewriteing GetProcAddress
GetProcAddr PROC USES esi edi ebx ecx edx bHandle:DWORD, pApi:DWORD
;Install our Structured Exception Handler
LOCAL handle:DWORD
push bHandle
pop handle
;If handle == 0 we are looking for current module from PEB
;According to IDAs output of GetProcAddress ->>> BasepMapModuleHandle ->>>
; if handle is equal to 0, then get image-base from PEB
cmp handle, 0
jnz @F
mov eax, FS:[30h]
mov eax, [eax+8] ;<---- get Image Base
mov handle, eax
;<---- Locate EXPORT_TABLE!!!!!!
@@:
mov edi, handle
add edi, dword ptr[edi+3ch]
ASSUME EDI : ptr IMAGE_NT_HEADERS32
mov ebx, [edi].OptionalHeader.DataDirectory[0].VirtualAddress
add ebx, handle
ASSUME EDI:NOTHING
ASSUME EBX : ptr IMAGE_EXPORT_DIRECTORY
;Is it ordinal??
mov ecx, 0FFFFh
mov edx, pApi
cmp edx, ecx
jbe @ordinal
;<--- get api len!!!!!
xor eax, eax
mov edi, pApi
mov ecx, 100h
repnz scasb
sub edi, pApi
mov ecx, edi
mov edx, [ebx].AddressOfNames
add edx, handle
xor eax, eax ;<----- eax is counter!!!
@find_name:
mov esi, [edx]
add esi, handle
mov edi, pApi
push ecx ;<----- save API_len
cld
repe cmpsb
jz @find_ordinal
pop ecx
add edx, 4
inc eax
cmp eax, [ebx].NumberOfNames
jbe @find_name
mov eax, 0
jmp @ExitProc
;<--------in eax is Ordinal index * 2 to find right address
@find_ordinal:
mov esi, [ebx].AddressOfNameOrdinals
add esi, handle
xor edx, edx
mov dx, word ptr[esi+eax*2]
@ordinal:
;<---- edx has ordinal number
;<----- Now Find API address
mov esi, [ebx].AddressOfFunctions
add esi, handle
xor eax, eax
mov eax, dword ptr[esi+edx*4]
add eax, handle ;<---------API address
@ExitProc:
add esp, 4
ret
GetProcAddr ENDP
Why use something that is slower than regular GetProcAddress that doesn't handle forwarded exports either?
Just for fun, somebody asked about GetProcAddress so here is complete code on how to rewrite it =)
For educational urpose only =)
For educational urpose only =)