AddressOfEntryPoint bekommen?



  • Hallo,

    Ich bin gerade dabei einen kleinen Win32 EXE-binder zu schreiben.
    Jetzt wollte ich entweder direkt im IMAGE_OPTIONAL_HEADER die AddressOfEntryPoint bearbeiten oder aber einen JMP zu meinem stub an den EntryPoint schreiben.

    Naja, egal auf jeden Fall fragte ich mich, wie ich die an IMAGE_OPTIONAL_HEADER rankommen soll. Diesen Weg benutze ich momentan:

    int main()
    {
    	const char* szFileName = "bind.exe";
    
    	HANDLE hFile;
    	if( !( hFile = CreateFile( szFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL )) )
    	{
    		cout << "File couldn't be opened!";
    		return 0;
    	}
    
    	LARGE_INTEGER lFileSize;
    	DWORD dwFileSize;
    	if( GetFileSizeEx( hFile, &lFileSize ) == 0 )
    	{
    		cout << "Filesize not retrievable!";
    		return 0;
    	}
    	dwFileSize = (DWORD) lFileSize.QuadPart;
    
    	cout << "File opened, size: " << lFileSize.QuadPart << endl
    		<< "DWORD: " << dwFileSize << endl;
    
    	BYTE* pArray = new BYTE[ (UINT) dwFileSize ];
    
    	DWORD dwBytesRead;
    	if( !ReadFile( hFile, (LPVOID) pArray, dwFileSize, &dwBytesRead, NULL ))
    	{
    		cout << "File couldn't be read.";
    		return 0;
    	}
    
    	if( dwBytesRead != dwFileSize )
    		cout << "WARNING! Didn't read whole file, this could lead to errors while binding!" << endl;
    
    	IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*) pArray /*+0*/;
    	IMAGE_NT_HEADERS* pNTHeader =  (IMAGE_NT_HEADERS*) pArray + pDOSHeader->e_lfanew;
    	if( pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE  || pNTHeader->Signature != IMAGE_NT_SIGNATURE )
    	{
    		cout << "Not a valid PE file!";
    		return 0;
    	}
    
    	IMAGE_OPTIONAL_HEADER pHeader = pNTHeader->OptionalHeader;
    	DWORD dwEntryPoint = pHeader.AddressOfEntryPoint;
    
    	cout << "AddressOfEntryPoint: " << dwEntryPoint << endl;
    
    }
    

    Und hier happert es:

    IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*) pArray /*+0*/;
    	IMAGE_NT_HEADERS* pNTHeader =  (IMAGE_NT_HEADERS*) pArray + pDOSHeader->e_lfanew;
    	if( pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE  || pNTHeader->Signature != IMAGE_NT_SIGNATURE )
    	{
    		cout << "Not a valid PE file!";
    		return 0;
    	}
    

    Kriege immer ein "Not a valid PE file!", außer ich kommentiere

    || pNTHeader->Signature != IMAGE_NT_SIGNATURE
    

    aus.

    Also, mache ich etwas bei der Addresse zum NT Header falsch? Ich dachte e_lfanew wäre ein Offset vom Anfang der Datei zum NT Header?

    Übrigens, ich weiß nicht ob sowas nicht auch eher ins assembler Forum passt, fand aber das hier besser. 😉


  • Mod

    Deine Kalkulation ist vollkommen falsch. Der cast bindet näher.
    Nimm einen C++ cast und das wäre nicht passiert.

    reinterpret_cast<IMAGE_NT_HEADERS*>(pArray + pDOSHeader->e_lfanew);
    

    oder eben C-cast

    (IMAGE_NT_HEADERS*)(pArray + pDOSHeader->e_lfanew);
    


  • 🙂

    Danke, du hattest recht 🙂



  • Hey,
    sry das ich diesen alten Thread pushe. Ich habe aber zu diesem Thema noch eine Frage. Wie kann ich den den Entry Point neu definieren. Wie finde ich freie Bytes in dem Programm auf das ich meine neuen Entry Point legen kann und dann von dort aus mit einem JMP zu meinen alten Entry Point springen kann? Das ist zwar nicht beonders hilfreich, aber es intressiert mich wie man sowas ändern kann.
    Ich habe den Entry Point gefunden.

    DWORD MyEntryPoint = Header.AddressOfEntryPoint;
    
    	DWORD MyImageBase = Header.ImageBase;
    
    	DWORD MyEntry = MyImageBase + MyEntryPoint;
    

    Wie kann ich jetz am Besten weitermachen? Danke 🙂


Anmelden zum Antworten