![]() |
|
|
|
#1
|
||||
|
||||
|
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
__________________
Ur Best Friend Ahmadmansoor Always My Best Friend: Aaron & JMI & ZeNiX |
|
#2
|
||||
|
||||
|
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
__________________
http://arteam.accessroot.com |
|
#3
|
||||
|
||||
|
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
__________________
Ur Best Friend Ahmadmansoor Always My Best Friend: Aaron & JMI & ZeNiX |
|
#4
|
||||
|
||||
|
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
__________________
http://arteam.accessroot.com |
| The Following User Gave Reputation+1 to Nacho_dj For This Useful Post: | ||
ahmadmansoor (02-25-2011) | ||
|
#5
|
||||
|
||||
|
Quote:
many thanks
__________________
Ur Best Friend Ahmadmansoor Always My Best Friend: Aaron & JMI & ZeNiX |
|
#6
|
||||
|
||||
|
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] A1 | MOV EAX,[virtual address] 8B0D | MOV ECX,[virtual address] 8B15 | MOV EDX,[virtual address] 8B1D | MOV EBX,[virtual address] 8B25 | MOV ESP,[virtual address] 8B2D | MOV EBP,[virtual address] 8B35 | MOV ESI,[virtual address] 8B3D | MOV EDI,[virtual address] FF15 | CALL [virtual address] FF25 | JMP [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 do
if (hndFunc > TableProcess[i].modBaseAddr) AND
(hndFunc < (TableProcess[i].modBaseAddr + TableProcess[i].modBaseSize)) then
begin
GetFunctionNameAndOrdinal(...)
end;
![]() Nacho_dj
__________________
http://arteam.accessroot.com |
| The Following 3 Users Gave Reputation+1 to Nacho_dj For This Useful Post: | ||
ahmadmansoor (02-26-2011), chessgod101 (02-26-2011) | ||
|
#7
|
||||
|
||||
|
Thanks Nacho_dj ,,, very nice explanation .
I will wait the continue .
__________________
Ur Best Friend Ahmadmansoor Always My Best Friend: Aaron & JMI & ZeNiX |
|
#8
|
||||
|
||||
|
This might be useful
http://www.masm32.com/board/index.php?topic=5996.0
__________________
Even as darkness envelops and consumes us, wrapping around our personal worlds like the hand that grips around our necks and suffocates us, we must realize that life really is beautiful and the shadows of despair will scurry away like the fleeting roaches before the light. |
| The Following 2 Users Gave Reputation+1 to D-Jester For This Useful Post: | ||
chessgod101 (02-26-2011) | ||
|
#9
|
||||
|
||||
|
You want custom GetProcAddress?
Code:
PVOID FastGetProcAddress(PCHAR DllBase, PCHAR RoutineName)
{
USHORT OrdinalNumber;
PULONG NameTableBase;
PUSHORT NameOrdinalTableBase;
PULONG Addr;
ULONG High;
ULONG Low;
ULONG Middle;
LONG Result;
ULONG ExportSize;
PVOID FunctionAddress;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
NameTableBase = (PULONG)(DllBase + (ULONG)ExportDirectory->AddressOfNames);
NameOrdinalTableBase = (PUSHORT)(DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
Low = 0;
High = ExportDirectory->NumberOfNames - 1;
while (High >= Low)
{
Middle = (Low + High) >> 1;
Result = strcmp(RoutineName,
(PCHAR)(DllBase + NameTableBase[Middle]));
if (Result < 0)
{
High = Middle - 1;
}
else if (Result > 0)
{
Low = Middle + 1;
}
else
{
break;
};
};
if (High < Low)
{
return NULL;
};
OrdinalNumber = NameOrdinalTableBase[Middle];
if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions)
{
return NULL;
};
Addr = (PULONG)(DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
FunctionAddress = (PVOID)(DllBase + Addr[OrdinalNumber]);
return FunctionAddress;
};
Quote:
|
|
#10
|
||||
|
||||
|
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:
__________________
Ur Best Friend Ahmadmansoor Always My Best Friend: Aaron & JMI & ZeNiX |
|
#11
|
|||
|
|||
|
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 )
{
if ( addr )
{
addr -= peFile->imageBase();
addr = addr;
for ( uint32_t lib = 0; lib < peFile->importLibraryCount(); ++lib )
{
PeFile::ImportLibrary library;
if ( !peFile->importLibrary(&library,lib) )
{
continue;
}
uint32_t offset = addr - library.;
offset /= sizeof(DWORD);
if ( offset < peFile->importAddressCount(&library) )
{
PeFile::ImportAddress address;
if ( peFile->importAddress(&address,&library,offset) )
{
if ( address.name )
{
return QString(library.name).toUpper() + QString(".") + QString(address.name);
}
else // by ordinal
{
return QString(library.name).toUpper() + QString(".#") + QString::number(address.ordinal,16);
}
}
}
}
}
return QString();
}
|
| The Following User Gave Reputation+1 to dila For This Useful Post: | ||
ahmadmansoor (02-28-2011) | ||
|
#12
|
|||
|
|||
|
see attached: proof of concept screenshot
|
| The Following User Gave Reputation+1 to dila For This Useful Post: | ||
ahmadmansoor (02-28-2011) | ||
|
#13
|
||||
|
||||
|
Thanks dila .... I will try it .
and I will back with result . Thanks in adv ..
__________________
Ur Best Friend Ahmadmansoor Always My Best Friend: Aaron & JMI & ZeNiX |
|
#14
|
||||
|
||||
|
Ah but Dila, that only works if the Imports.OrigFirstThunk array is valid
![]() Code:
//-----------------------------------------------------------------------//
// Get Api Name from address .. (Reverse GetProcAddress)
Function GetProcAddressName(Const ApiAddress : DWord) : String;
Var
I,
Base, // Module base address ..
Rva : DWord; // Rva of Api ..
FA, // Pointer to Functions Array ..
NA : PDWord; // Pointer to Names Array ..
Exp : PImageExportDirectory; // Export Table ..
Dos : PImageDosHeader; // Dos Header ..
Nt : PImageNtHeaders; // Nt Headers ..
Begin
Result := 'Error';
// Calc module base address from API address ..
Base := ApiAddress;
Repeat
NT := Nil;
Dec(Base);
Base := Base And $FFFFF000; // Align to page size ..
If (Not IsBadReadPtr(Pointer(Base), 4)) Then Begin
Dos := Pointer(Base);
If (Dos^.Magic = IMAGE_DOS_SIGNATURE) Then Nt := Pointer(Base + Dos^.OffsetPE);
End;
Until (Not IsBadReadPtr(NT, 4)) And (NT^.Signature = IMAGE_NT_SIGNATURE);
// Search for the Rva in the Function Array of the export table ..
Exp := Pointer(Base + NT^.OptionalHeader.DataDirectory[0].Rva);
Rva := ApiAddress - Base;
FA := Pointer(Base + Exp^.RvaOfFunctions);
NA := Pointer(Base + Exp^.RvaOfNames);
For I := 0 To Exp^.NumberOfFunctions-1 Do Begin
If (Rva = FA^) Then Begin
// Return name or ordinal string ..
Result := PAnsiChar(Base + Exp^.Name) + '!';
If (I < Exp^.NumberOfNames) Then Result := Result + PAnsiChar(Base + NA^)
Else Result := Result + '#' + IntToStr(Exp^.Base + I);
Break;
End;
Inc(FA);
Inc(NA);
End;
End;
Code:
Api := DWord(GetProcAddress(KernelBase, 'HeapCreate')); MessageBox(0, PChar(GetProcAddressName(Api)), Nil, MB_OK); Code:
KERNEL32.dll!HeapCreate Excuse any weird code, it's 6:30 am and I need to sleep ![]() BoB Last edited by BoB; 02-28-2011 at 14:44. |
| The Following 2 Users Gave Reputation+1 to BoB For This Useful Post: | ||
ahmadmansoor (02-28-2011) | ||
|
#15
|
|||
|
|||
|
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
|
![]() |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| fake mac address | theGate | General Discussion | 16 | 08-13-2022 10:12 |
| Get real address of api not nt version | Mahmoudnia | General Discussion | 18 | 05-23-2018 00:44 |
| Finding API Address | britedream | General Discussion | 5 | 10-05-2006 21:28 |
| how to get the address of the entry point in an API | Warren | General Discussion | 6 | 08-30-2005 16:18 |