Pufferüberlaufproblemen



  • Wo genau tritt der Fehler auf?



  • Debug Modus :
    Wenn ich es richtig lokalisiert habe ich folgender Zeile:

    copy(cString.begin(), cString.end() + 1, sec.begin());
    

    Fehler gefunden 🙂 Es muss so heißen:

    copy(cString.begin(), cString.end(), sec.begin());
    


  • Bekommt nun kein Ergebnis von MD5Hash zurück.

    #include <iostream>
    #include <windows.h>
    #include <wincrypt.h>
    #include <fstream>
    #include <array>
    #include "MD5.h"
    
    using namespace std;
    
    const int MD5LEN = 16;
    
    void MD5Hash(BYTE hash[], int sz, string cString)
    {
    	tr1::array<char, 32> sec,finalhash;
        HCRYPTPROV hProv = 0,hHash = 0;
        BYTE rgbHash[MD5LEN];
        DWORD cbHash = 0;
        //char finalhash[32], dig[] = "0123456789abcdef";
    	char dig[] = "0123456789abcdef";
        unsigned int l = 0;
    
        CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
        CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
        CryptHashData(hHash, hash, sz, 0);
        cbHash = MD5LEN;
        CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0);
    
        for(DWORD i = 0; i < cbHash; i++)
    	{
            finalhash[l] = dig[rgbHash[i] >> 4];
            l++;
            finalhash[l] = dig[rgbHash[i] & 0xf];
            l++;
        }
    
        //for(l = 32; l < strlen(finalhash); l++) finalhash[l] = 0;
    	fill(finalhash.begin(), finalhash.end(), 0);
        copy(finalhash.begin(), finalhash.end(), sec.begin()); 
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
    	copy(sec.begin(), sec.end(), cString.begin());	
    }
    

    main.cpp

    // Überschrift erzeugen
    	g_pLogfile->WriteTopic ("Test");
    
    	// Allocate array for getting ImageBase addresses of
        // all drivers present in system.
        DWORD dwBufferLen = GetImageBaseAddrArrayLen();
        LPVOID* pImageBaseAddrArray = (LPVOID*)new BYTE[ dwBufferLen ];
    
        DWORD dwBytesReturned = 0;
        // Get the ImageBaseAddresses of all drivers.
        EnumDeviceDrivers( pImageBaseAddrArray,  // array of load addresses
                           dwBufferLen,  // size of array as 0.
                           &dwBytesReturned );
    
        // Get the total number of drivers. calculate it by
        // total size in bytes/sizeof(void*)
        DWORD nDrivers = dwBufferLen / sizeof(LPVOID);
    
    	PVOID OldValue = NULL;
    
    	for( DWORD Index = 0; Index < nDrivers; ++Index )
        {
            // Get Device Driver informations.
            string sDriverBaseName;
            string sDriverFileName;
            GetDriverInfo( pImageBaseAddrArray[ Index], sDriverBaseName, sDriverFileName );
    
    		// \??\ /
    		int iFindIdxMD5Question = sDriverFileName.find( "\\??\\" );
    		int iExistQuestion = 0;
    		if ( iFindIdxMD5Question != -1 )
    		{
    			sDriverFileName.erase( 0, 4 );
    			iExistQuestion = 1;
    		}
    		// \Windows\System32
    		int iFindIdxMD5Win = sDriverFileName.find( "\\Windows\\System32" );
    		if ( iFindIdxMD5Win != -1 )
    			sDriverFileName.replace( iFindIdxMD5Win, 17, sSysDir );
    		// \WINDOWS\System32
    		int iFindIdxMD5Win2 = sDriverFileName.find( "\\WINDOWS\\System32" );
    		if ( iFindIdxMD5Win2 != -1 )
    			sDriverFileName.replace( iFindIdxMD5Win, 17, sSysDir );
    		// \SystemRoot\System32
    		int iFindIdxMD5SysRoot = sDriverFileName.find( "\\SystemRoot\\System32" );
    		if ( iFindIdxMD5SysRoot != -1 )
    			sDriverFileName.replace( iFindIdxMD5SysRoot, 20, sSysDir );
    		// \SystemRoot\system32
    		int iFindIdxMD5SysRoot2 = sDriverFileName.find( "\\SystemRoot\\system32" );
    		if ( iFindIdxMD5SysRoot2 != -1 )
    			sDriverFileName.replace( iFindIdxMD5SysRoot2, 20, sSysDir );
    		// \SystemRoot\SysWOW64
    		int iFindIdxMD5SysWOW64 = sDriverFileName.find( "\\SystemRoot" );
    		if ( iFindIdxMD5SysWOW64 != -1 )
    			sDriverFileName.replace( iFindIdxMD5SysWOW64, 11, sWinDir );
    		// C:\Windows\SysWOW64
    		int iFindIdxMD5C = sDriverFileName.find( "C:\\" );
    		if ( iFindIdxMD5C == -1 )
    			sDriverFileName.insert( 0, "C:\\" );
    
    		// calculating MD5
    		HANDLE hFile;
    		DWORD dwNumRead = -1;
    
    		if(IsWow64())
    			if (!WOW64DisableFsRedirection(&OldValue))
    				printf("WOW64DisableFsRedirection doesn´t work\n");
    
    		hFile = CreateFile(sDriverFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    
    		if (!WOW64RevertFsRedirection(OldValue))
    			printf("WOW64RevertFsRedirection doesn´t work\n");
    
    		if(hFile == INVALID_HANDLE_VALUE)
    		{
    			g_pLogfile->Textout ("ERROR: INVALID_HANDLE_VALUE" + sDriverFileName);
    		}
    		else
    		{
    			//GetFileSize to determine size of buffer for ReadFile
    			DWORD BufferSize = GetFileSize(hFile,NULL);
    
    			cout << "Buffer: " << BufferSize <<endl;
    
    			char* ReadBuffer = new char [BufferSize];// create a new char * to hold the buffer using the filesize
    
    			//Read from the file:
    			if(!ReadFile(hFile, ReadBuffer, BufferSize+1, &dwNumRead,NULL))
    			{
    				printf ("ReadFile Fail");
    				return 1;
    			}
    
    			//To close the file:
    			CloseHandle(hFile);
    
    			string hash;
    			MD5Hash((BYTE*)ReadBuffer, BufferSize, hash);
    			delete ReadBuffer;
    			if ( iExistQuestion == 1)
    			sDriverFileName.insert( 0, "\\??\\");
    
    			g_pLogfile->Textout (sDriverBaseName + " : " + sDriverFileName + " : " + hash);
    
    		}
        }
    	cout << "done";
    	delete (BYTE*)pImageBaseAddrArray;
    	// Logfile schließen
    	g_pLogfile->Del ();
    	Sleep(5000);
    


  • Als erstes würde ich nur C-Strings cString nennen. std::string ist ein C++-String... 😉

    Du darfst nicht über den end() -Iterator hinaus zugreifen. Was geht, ist der Zugriff per operator[] mit dem Index size() – sofern die const -Version aufgerufen wird.

    tr1::array<char, 32> sec,finalhash;
     copy(cString.begin(), cString.end(), sec.begin())
    

    Hier hast du auch ein Problem, falls cString mehr als 32 Elemente enthält. Die Nullterminierung musst du zudem selbst schreiben.

    Statt des end() -Iterators könntest du Folgendes schreiben:

    cString.begin() + std::min(32u, cString.size())
    


  • pc-jedi schrieb:

    Bekommt nun kein Ergebnis von MD5Hash zurück.

    Nächstes Mal bitte das Problem genauer beschreiben...

    Dein std::string muss als Referenz übergeben werden, falls er als Output-Parameter benutzt werden soll.



  • Warum geht folgende Zeile nicht?

    copy(finalhash.begin(), finalhash.end(), cString->begin());
    


  • Nexus schrieb:

    Nächstes Mal bitte das Problem genauer beschreiben...

    🙄



  • Oh, ja 🙂
    Also ich bekomme folgende Fehlermeldung:

    Debug Assertation Failed!

    Programm C:\Users\***\test.exe
    File: C:\program files(x86)\mircosoft visual studio 10.0\vc\include\xstring
    Line:167

    Expression: string interator + offset out of range

    in folgender Zeil:

    copy(finalhash.begin(), finalhash.end(), cString->begin());
    

    finalhash ist ein std::tr1::array<char, 32>
    cString ist ein Zeiger auf ein std::string

    Wenn ich die Fehlermeldung richtig deute, dann wird hier irgendwie in undefinierten Bereich geschrieben.



  • Ist cString zu diesem Zeitpunkt leer (oder zu klein)? Falls ja, und du lediglich hinten einfügen möchtest, könntest du std::back_inserter() aus dem <iterator> -Header benutzen.

    std::copy(finalhash.begin(), finalhash.end(), std::back_inserter(*cString));
    

    Oder einfach std::string::assign() , um den kompletten String zu überschreiben:

    cString->assign(finalhash.begin(), finalhash.end());
    

    Gibt es eigentlich einen Grund, wieso du Zeiger auf std::string verwendest? Und ich würde immer noch einen anderen Namen als cString wählen. 😉



  • Hi

    Alles geht.
    Vielen Dank 🙂

    Gibt es eigentlich einen Grund, wieso du Zeiger auf std::string verwendest?

    Nein eigendlich nicht hätte das auch einfach über einen Rückgabewert machen können.

    Und ich würde immer noch einen anderen Namen als cString wählen.

    Habe den einfach noch nicht umbenannt.


Anmelden zum Antworten