GetProcAddress im Eigenbau...
-
Guten Abend,
ich bin dabei GetProcAddress nachzubauen.
Um das ganze abzukürzen, hier der Code:void* getProcAddress(void* DllBase, char* FunctionName){ PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)DllBase; PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)((BYTE*)DllBase + dos_header->e_lfanew); IMAGE_OPTIONAL_HEADER opt_header = (IMAGE_OPTIONAL_HEADER)nt_header->OptionalHeader; PIMAGE_DATA_DIRECTORY data_header = (PIMAGE_DATA_DIRECTORY)opt_header.DataDirectory; if(!data_header->VirtualAddress) return 0; PIMAGE_EXPORT_DIRECTORY expDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)DllBase + data_header->VirtualAddress); UINT32 expRange = data_header->Size + data_header->VirtualAddress; UINT32* addressOfNames = (UINT32*)((BYTE*)DllBase + expDir->AddressOfNames); //char* str; UINT32 index = 0; for(; index < expDir->NumberOfNames; ++index){ UINT32* nameOfFunction = (UINT32*)((BYTE*)DllBase + addressOfNames[index]); if(strComp((char*)nameOfFunction, (char*)FunctionName)){ //str = (char*)nameOfFunction; break; } } //UINT16* addressOfNameOrdinals = (UINT16*)((BYTE*)DllBase + expDir->AddressOfNameOrdinals); //UINT16 ordinale = addressOfNameOrdinals[index]; UINT32* addressOfFunctions = (UINT32*)((BYTE*)DllBase + expDir->AddressOfFunctions); UINT32 function = addressOfFunctions[index]; return (void*)((BYTE*)DllBase + function); }
Nun ist es aber so, dass ich nicht immer die korrekte Funktion erhalte.
Teste ich es mit z.B. "LoadLibraryA" ist alles okay, teste ich jedoch mit "GetNativeSystemInfo", bekomme ich die Addresse von "GetNamedPipeServerSessionId", also 1 daneben... woran liegt das, bzw. versuche ich das ganze mit einem falschen/schlechten Ansatz zu lösen?
Und am Rande noch die Frage: Wie kann ich am besten herausfinden, ob die gesuchte Funktion in der Dll exportiert, bzw. weitergeleitet wird?Viele Grüße.
PS: Bitte gnädig sein, ist "Debug Code"
-
Na weil du den Zwischenschritt über AddressOfNameOrdinals ausgelassen hast.
- Index des Namens in AddressOfNames[] suchen
- Mit diesem Index den Ordinal aus AddressOfNameOrdinals[] lesen
- Mit dem Ordinal die Export-Adresse aus AddressOfFunctions[] lesen
BTW: wozu die ganzen Casts nach UINT32*, nur damit danach gleich wieder zurück nach char* castest?
-
Ohje, wo ist der peinliche Smilie
Danke dir vielmals!hustbaer schrieb:
BTW: wozu die ganzen Casts nach UINT32*, nur damit danach gleich wieder zurück nach char* castest?
Wie gesagt, Debug-Code
Soll heißen, habe die ganze Zeit herumgewerkelt und dann bleiben solche "unnötigen" Dinge übrig, aber vielleicht sollte ich wirklich zwischendurch mal "aufräumen"
-
Ach, ganz vergessen, da gab´s noch eine offene Frage zum Thema Forwarding.
Hab das jetzt so gelöst, scheint zu funktionieren.if((function >= data_header->VirtualAddress) || (function > expRange)) return 0; // forwarding
Gruß!
-
gpa schrieb:
Wie gesagt, Debug-Code
Soll heißen, habe die ganze Zeit herumgewerkelt und dann bleiben solche "unnötigen" Dinge übrig, aber vielleicht sollte ich wirklich zwischendurch mal "aufräumen"
Guter Vorsatz!
Könntest Du das funktionierende aufgeräumte Codefragment noch posten ?
-
Wenn es so genehm ist?
void* getProcAddress(void* DllBase, char* FunctionName){ PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)DllBase; PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)((BYTE*)DllBase + dos_header->e_lfanew); IMAGE_OPTIONAL_HEADER opt_header = (IMAGE_OPTIONAL_HEADER)nt_header->OptionalHeader; PIMAGE_DATA_DIRECTORY data_header = (PIMAGE_DATA_DIRECTORY)opt_header.DataDirectory; if(!data_header->VirtualAddress) return 0; PIMAGE_EXPORT_DIRECTORY expDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)DllBase + data_header->VirtualAddress); UINT32 expRange = data_header->Size + data_header->VirtualAddress; UINT32* addressOfNames = (UINT32*)((BYTE*)DllBase + expDir->AddressOfNames); for(UINT32 index = 0; index < expDir->NumberOfNames; ++index){ char* nameOfFunction = (char*)((BYTE*)DllBase + addressOfNames[index]); if(strComp(nameOfFunction, FunctionName)){ UINT16* addressOfNameOrdinals = (UINT16*)((BYTE*)DllBase + expDir->AddressOfNameOrdinals); UINT16 ordinale = addressOfNameOrdinals[index]; UINT32* addressOfFunctions = (UINT32*)((BYTE*)DllBase + expDir->AddressOfFunctions); UINT32 function = addressOfFunctions[ordinale]; if((function >= data_header->VirtualAddress) || (function > expRange)) return 0; // forwarding return (void*)((BYTE*)DllBase + function); } } return 0; }
Btw: Jemand eine Idee, wie ich herausfinde, in welche Dll die entsprechende Funktion weitergeleitet wird?
Dachte das in diesem Fall hinter dem Namen der Funktion noch die Dll stehen würde, also z.B. so:// kernel32.dll, addressOfNames // so dachte ich es FlushProcessWriteBuffers.NTDLL.NtFlushProcessWriteBuffers // so ist es FlushProcessWriteBuffers.FlushViewOfFile.FoldStringA...
Und ich meine das auch schon einmal so gesehen zu haben, aber in diesem Fall ist es nicht so. Was kann ich tun?
-
Zunächst entschuldigung für die Doppelposts...
Whatever, hier auch für das letzte Problem die Lösung, war wieder ein wenig drucheinander.Wenn die Funktion weitergeleitet wird, findet man so den Namen der entspr. Dll:
char* rawStr = (char*)((BYTE*)DllBase + function); // rawStr = DLL_NAME_OHNE_ENDUNG + "." + NAME_DER_FUNKTION
Gruß
-
TripplePost, sorry:
Korrektur
if((function > data_header->VirtualAddress) && (function < expRange)) { // redirected }
Vielleicht ist ein Moderator so nett, und modifiziert meinen ersten Post und löscht die beiden darauf folgenden?
-
Aber die Doku hast Du schon gelesen, oder?
http://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx
-
Nein... diese Doku nicht, habe ich etwas übersehen?
-
Wie schreibst Du denn Deinen Code, wenn Du Dich nur auf 3. Informationen verlässt... Nimm die Doku von MS, dann hast Du eine sichere Quelle wie die DLL aufgebaut ist. Such dort nach "forward" dann siehst Du was Du machen musst...
-
Hm... aber dann stimmt es doch was ich gemacht habe, oder nicht?
// expRange = data_header->Size + data_header->VirtualAddress if((function > data_header->VirtualAddress) && (function < expRange)) { // redirected }
Hiermit teste ich doch, ob die Funktion innerhalb der ExportSection liegt...
Verstehe ich dich also falsch?Gruß