![]() |
Get APi from the address
we always do this to get the API addresss
GetAPIAddress = GetProcAddress(GetModuleHandle("Kernel.dll),FunctionName) to get the Address of the API . but what the programmatic way to get the API of the address . like if we have this : Quote:
( I need the reverse way of GetProcAddress ) Thanks in adv |
Since it is a handle in memory and it is linked to the imagebase of its module loaded by the system, you need:
- Getting all processes loaded in memory, thus retrieving their imagebase and size, their module name, and so on... - Determining which process the handle belongs to, getting in this way the module that is exporting it. - Go analyzing export table of that module to find the handle (in RVA), and then get the function name, if this exists in the functions names table. Ordinal can always be retrieved. - If there is forwarding, you should try to find which is the module that is the origin of forward, to get the function name inside it. Cheers Nacho_dj |
Thanks Nacho_dj ....
This idea have come to my mind . but I note that it could make this process take a lot of time .. I have check "Import REConstructor" and "CHimpREC" and I have note that "Import REConstructor" didn't take the time which "CHimpREC" take it . it is more faster . so is there fast way to get this or it will depended on the algorithm of the code it self !! Thanks for replay |
Yeah, it depends strongly of the algo used and the way of accessing files.
I have checked that, for instance, some tools load in memory the content of an entire file, whilst other just load the section of the file needed, so it will get much faster because of managing less memory space. If you need more detailed data I could post it here... Cheers Nacho_dj |
Quote:
many thanks |
How to retrieve every function name in a loaded application (executable or dll) - Part I
I have used Delphi code to implement this, so pseudocode will be near to Delphi... 1. Create an instance of tagMODULEENTRY32: tagMODULEENTRY32.dwSize := SizeOf(MODULEENTRY32); 2. Get process information inside the sanapshot: hSnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPMODULE,lpProcessInformation.dwProcessId); 3. Retrieve first module loaded in your process: Module32First(hSnapShot,tagMODULEENTRY32) If the function succeeds, you have got some module information, like this: tagMODULEENTRY32.modBaseAddr tagMODULEENTRY32.modBaseSize Store it in an struct inside an array, and then, start a loop to get the others processes info: Module32Next(hSnapShot,tagMODULEENTRY32) If the function succeeds, you have got several module information, like this: tagMODULEENTRY32.modBaseAddr tagMODULEENTRY32.modBaseSize The loop ends when the previous function doesn't succeed. 4. For everyone of the modules previously stored in your array, get the export table. This will be used later. You just need to read PE header, and get the export table rva & size from data directories. Get the IMAGE_EXPORT_DIRECTORY structure and store it in an array for every process loaded. 5. Get the import table addresses minimum and maximum bounds. There could be several methods to do it. I prefer reading the entire code section and get all references to imported functions by analyzing every opcode like this table shows: Code:
FF35 | PUSH [virtual address]Mimimum IAT address RVA Maximum IAT address RVA For every iteration, you only need to validate that a handle is valid if the RVA of the handle is out of minimum and maximum RVA previosly computed. To find a valid handle for imported function, first check in a loop that it belongs to any of the processes loaded: Code:
for i := 0 to Length(TableProcess) - 1 doNacho_dj |
Thanks Nacho_dj ,,, very nice explanation .
I will wait the continue . |
This might be useful
http://www.masm32.com/board/index.php?topic=5996.0 |
You want custom GetProcAddress?
Code:
PVOID FastGetProcAddress(PCHAR DllBase, PCHAR RoutineName)Quote:
|
Thanks D-Jester and Fyyre ...
but what i mean that I have the address memory , and I want to know which API related to this address memory . that what I mean . @ Fyyre : thanks for nice code ... easy and can be useful . in ur code it need this too ;) Quote:
|
It sounds like he wants reverse GetProcAddress. Like the sort of code "analysis" you find next to CALL instructions in OllyDbg.
I've been looking at doing this for adding details to beaengine output and it goes like this:
Code:
QString importFromRva( const PeFile *peFile, uint64_t addr ) |
1 Attachment(s)
see attached: proof of concept screenshot ;)
|
Thanks dila .... I will try it .
and I will back with result . Thanks in adv .. |
Ah but Dila, that only works if the Imports.OrigFirstThunk array is valid ;)
Code:
//-----------------------------------------------------------------------//Code:
Api := DWord(GetProcAddress(KernelBase, 'HeapCreate'));Code:
KERNEL32.dll!HeapCreateExcuse any weird code, it's 6:30 am and I need to sleep :) BoB |
1 Attachment(s)
My implementation in CPP, Use VirtualQuery to get module base and check if it's really module then parse export table and get api name or ordinal. PS: Code is old and may contain bugs was fastly coded few years ago :)
|
Quote:
cheers. |
Wow, a lot of participation in this thread, nice :)
Anyway, here is second part... Getting Name of Function and Ordinal value - Part II We enter this routine with the handle and the name of the module that the handle belongs to. Let's work with export table of that module. We compare AddressOfNameOrdinals to AddressOfNames. If they are different, we start a) chapter. Otherwise, go to b) chapter. a) We first start a loop with NumberOfNames iterations. Within the loop, we must go through AddressOfOrdinals array. This array is composed only by Words. Each Word performs a 'number of order' in AddressOfFunction array. We take the content in the i-element of the AddresOfOrdinals array. That content is the number of element in AddressOfFunction array, so we get the value of that component. This comes as RVA. We compare now: handle(our input) to RVA content + BaseAddress of the module If they match: 1. If 'number of order' is not equal to zero, then Ordinal of that handle is: 'number of order'+ nBase(parameter in export table) OR IMAGE_ORDINAL_FLAG32(0x80000000) 2. We go through the AddressOfNameOfFunction array and read the i element. This is an RVA value. Then we read the string at that address and we get the name of the function searched. b) If 'number of order' is zero (there is no names of functions, just ordinals), we start a loop with NumberOfFunction iterations. For every element in the array of AddressOfFunction, we compare: handle(our input) to value of element(RVA) + BaseAddress of the module. If they match, ordinal for that handle is: (i(iteration) + nBase(parameter in export table)) OR IMAGE_ORDINAL_FLAG32(0x80000000) To be continued (solving forwarded functions)... |
Some tips:
1) Don't forget about forwarded exports ( they point inside of export table ) 2) There may be more than one function with same RVA Examples: SetHandleCount = LockResource NtOpenFile = ZwOpenFile 3) Optimization, need to build lookup tables with name of functions and need to sort table with RVA then simply apply binary search by rva but be aware if you sort rva's standard CRT binary search won't return you pointer to the first function( in other words if you have 3 functions with same rva bsearch may return to you any 1 of 3) so you will need to find first and last by going backward and forward increasing pointer in table. Good luck. |
@V0ldemAr and Bob and Nacho_dj's : thanks for nice code .
@V0ldemAr : can u modify ur function so it could accept another parameter Quote:
Thanks in adv |
Hmm, I suspect Bob's IsValidPtr loop would be way to slow for me. I should make some notes of the things V0ldemAr mentioned (two api's with the same address is a major one).
It seems one of the main differences between all these techniques is whether they depend on runtime API's. I was really only interested in static analysis. |
The only Api I used is in the loop to check for imagebase, in fact it's not really needed at all unless you somehow miss the real imagebase address. Originally I had Imagebase as a separate param, using no Apis, but Ahmadmansoor wanted just one input :)
|
Quote:
|
| All times are GMT +8. The time now is 11:44. |
Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2026, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX