I was tried this code:
HMODULE hModule = LoadLibrary(argv[1]);
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)hModule + dosHeader->e_lfanew);
PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)hModule + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* addressOfFunctions = (DWORD*)(hModule + exportDirectory->AddressOfFunctions);
DWORD* addressOfNames = (DWORD*)(hModule + exportDirectory->AddressOfNames);
WORD* addressOfNameOrdinals = (WORD*)((DWORD_PTR)hModule + exportDirectory->AddressOfNameOrdinals);
printf("******* DLL EXPORTS *******\n");
printf("\t%i of functions\n\t%i of names\n",(int)exportDirectory->NumberOfFunctions,(int)exportDirectory->NumberOfNames);
printf("\tordinal\t\thint\t\tRVA\t\tattribute\t\tname\n");
for (DWORD i = 0; i < exportDirectory->NumberOfFunctions; i++)
{
DWORD functionRVA = addressOfFunctions[i];
const char* functionName = NULL;
for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++)
{
if (addressOfNameOrdinals[j] == i)
{
functionName = ((const char*)hModule + addressOfNames[j]);
break;
}
}
if (functionName != NULL)
{
FARPROC functionAddress = GetProcAddress(hModule, functionName);
for (; importDescriptor->Name != 0; importDescriptor++) {
// imported dll modules
printf("\t%s\n", rawOffset + (importDescriptor->Name - importSection->VirtualAddress));
thunk = importDescriptor->OriginalFirstThunk == 0 ? importDescriptor->FirstThunk : importDescriptor->OriginalFirstThunk;
thunkData = (PIMAGE_THUNK_DATA)(rawOffset + (thunk - importSection->VirtualAddress));
// dll exported functions
for (; thunkData->u1.AddressOfData != 0; thunkData++) {
//a cheap and probably non-reliable way of checking if the function is imported via its ordinal number ¯\_(ツ)_/¯
if (!(thunkData->u1.AddressOfData > 0x80000000)) {
char* libname1=(char*)(rawOffset + (importDescriptor->Name - importSection->VirtualAddress));
const char* libname=libname1;
char* importfunctionname1=(char*)(rawOffset + (thunkData->u1.AddressOfData - importSection->VirtualAddress + 2));
const char* importfunctionname=importfunctionname1;
HMODULE module=LoadLibrary(libname);
if (((DWORD)functionAddress-(DWORD)hModule)==((DWORD)GetProcAddress(module,importfunctionname)-(DWORD)module))
printf("\t%i\t\t%02X\t\t%0002X\t\tforwarded\t\t%s\t\t (forwarded to %s.%s)\n", i + exportDirectory->Base,i,functionRVA,functionName,libname,importfunctionname);// (forwarded to %s.%s)
else
printf("\t%i\t\t%02X\t\t%0002X\t\tnormal\t\t%s\n", i + exportDirectory->Base,i,functionRVA,functionName);
}
printf("\t%i\t\t%02X\t\t%0002X\t\t \t\t%s\n", i + exportDirectory->Base,i,functionRVA,functionName);
}
}
}
}
FreeLibrary(hModule);
But it output this:
******* DLL EXPORTS *******
1608 of functions
1608 of names
ordinal hint RVA attribute name
It should output this instead:
******* DLL EXPORTS *******
1608 of functions
1608 of names
ordinal hint RVA attribute name
4 01 forwarded AcquireSRWLockExclusive (forwarded to NTDLL.RtlAcquireSRWLockExclusive)
What I'm doing wrong and how can I get the forwarded function name?
P/S: My compiler was MinGW (installed on Windows).
(DWORD)functionAddresswill do exactly what you wrote, which possibly does not coincide with what you meant.addressOfFunctionsandaddressOfNames, you are not castinghModuletoDWORD_PTRbefore performing arithmetic on it, like you do with your other uses ofhModule, so you are performing pointer arithmetic instead of integer arithmetic, using the wrong pointer type.