Pufferüberlaufproblemen



  • Der Pufferüberlauf kommt am Ende des Programms, wenn alles erledigt ist. Erst kommt 10sec Sleep und wenn ich den 10sec Sleep das Programm per Alt + F4 oder einfach mit X beende kommt kein Pufferüberlauf, aber wenn es sich selbst beendet entsteht ein Pufferüberlauf.



  • Update: Problem hat sich verschoben
    ausschnitt aus 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);
    
    			char hash[32];
    			MD5Hash((BYTE*)ReadBuffer,BufferSize,hash);
    			free(ReadBuffer);
    			if ( iExistQuestion == 1)
    			sDriverFileName.insert( 0, "\\??\\");
    
    			g_pLogfile->Textout (sDriverBaseName + " : " + sDriverFileName + " : " + hash);
    
    		}
        }
    

    MD5.cpp

    #include <iostream>
    #include <windows.h>
    #include <wincrypt.h>
    #include <fstream>
    
    using namespace std;
    
    #define MD5LEN  16
    
    void MD5Hash(BYTE hash[],int sz,char sec[])
    {
        HCRYPTPROV hProv = 0,hHash = 0;
        BYTE rgbHash[MD5LEN];
        DWORD cbHash = 0;
        char finalhash[32], 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;
        strcpy_s(sec, 33, finalhash);
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
    }
    

    DLL_LoadFunction.h

    #include <windows.h>
    
    typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
    typedef BOOL (WINAPI *LPFN_WOW64DISABLEWOW64FSREDIRECTION) (PVOID*);
    typedef BOOL (WINAPI *LPFN_WOW64REVERTWOW64FSREDIRECTION) (PVOID);
    
    BOOL IsWow64();
    BOOL WOW64DisableFsRedirection(PVOID *OldValue);
    BOOL WOW64RevertFsRedirection(PVOID OldValue);
    

    DLL_LoadFunction.cpp

    #include "DLL_LoadFunction.h"
    
    LPFN_ISWOW64PROCESS fnMyIsWow64Process;
    LPFN_WOW64DISABLEWOW64FSREDIRECTION fnMyWow64DisableWow64FsRedirection;
    LPFN_WOW64REVERTWOW64FSREDIRECTION fnMyWow64RevertWow64FsRedirection;
    
    BOOL IsWow64()
    {
        BOOL bIsWow64 = FALSE;
    
        //IsWow64Process is not available on all supported versions of Windows.
        //Use GetModuleHandle to get a handle to the DLL that contains the function
        //and GetProcAddress to get a pointer to the function if available.
    
        fnMyIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
            GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
    
        if(NULL != fnMyIsWow64Process)
        {
            if (!fnMyIsWow64Process(GetCurrentProcess(),&bIsWow64))
            {
                //handle error
            }
        }
        return bIsWow64;
    }
    
    BOOL WOW64DisableFsRedirection(PVOID *OldValue)
    {
    	fnMyWow64DisableWow64FsRedirection = (LPFN_WOW64DISABLEWOW64FSREDIRECTION) GetProcAddress(
    		GetModuleHandle(TEXT("kernel32")),"Wow64DisableWow64FsRedirection");
    
    	if(NULL != fnMyWow64DisableWow64FsRedirection)
    	{
    		if (!fnMyWow64DisableWow64FsRedirection(OldValue))
    		{
    			// handel error
    			return false;
    		}
    		else
    		{
    			return true;
    		}
    	}
    	return false;
    }
    
    BOOL WOW64RevertFsRedirection(PVOID OldValue)
    {
    	fnMyWow64RevertWow64FsRedirection = (LPFN_WOW64REVERTWOW64FSREDIRECTION) GetProcAddress(
    		GetModuleHandle(TEXT("kernel32")),"Wow64RevertWow64FsRedirection");
    
    	if(NULL != fnMyWow64RevertWow64FsRedirection)
    	{
    		if (!fnMyWow64RevertWow64FsRedirection(OldValue))
    		{
    			// handel error
    			return false;
    		}
    		else
    		{
    			return true;
    		}
    	}
    	return false;
    }
    

    Wenn wer Fehler oder Optimierungsbedarf sieht immer her damit 🙂



  • Der ganze Code ist mir zu gross, aber ein paar Dinge:

    LPVOID* pImageBaseAddrArray = (LPVOID*)new BYTE[ dwBufferLen ];
    

    Wo gibst du den Speicher frei? Vergiss nicht, ihn vor dem delete[] in BYTE* zu casten.

    int iFindIdxMD5Win = sDriverFileName.find( "\\Windows\\System32" );
    if ( iFindIdxMD5Win != -1 ) 
                sDriverFileName.replace( iFindIdxMD5Win, 17, sSysDir ); 
    // [Noch 5 Mal Codeduplikation]
    

    Auslagern in Funktionen wäre angebracht.

    char* ReadBuffer = new char [BufferSize];
    // [...]
    free(ReadBuffer);
    

    Das resultiert in undefiniertem Verhalten. Niemals new / delete mit malloc() / free() mischen**!** ⚠

    In C++ solltest du primär new / delete bzw. new[] / delete[] verwenden. Noch besser wäre natürlich automatische Speicherverwaltung mittels RAII. Gut möglich, dass hier auch dein Fehler liegt.

    #define MD5LEN  16
    

    Ziehe für Konstanten const typ einem #define vor.



  • Hi

    Vielen Dank für deine Hilfe, Nexus 🙂

    Jetzt bekomme ich folgende Fehlermeldung:

    Run-Time Check Failure #2 - Stack around the variable 'finalhash' was corrupted.

    #include <iostream>
    #include <windows.h>
    #include <wincrypt.h>
    #include <fstream>
    
    using namespace std;
    
    const int MD5LEN = 16;
    
    void MD5Hash(BYTE hash[],int sz,char sec[])
    {
        HCRYPTPROV hProv = 0,hHash = 0;
        BYTE rgbHash[MD5LEN];
        DWORD cbHash = 0;
        char finalhash[32], 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;
        strcpy_s(sec, 33, finalhash);
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
    }
    

    Ich hoffe hier kann mir auch nochmal wer auf die Sprünge helfen 🙂



  • Das sieht doch stark danach aus als würdest du irgendwo über das charArray finalhash rausschreiben. Wäre zumindest ein typischer Grund für die Fehlermeldung.



  • Die ganzen rohen Arrays und C-Strings sind eben schon fehleranfällig. Ein etwas idiomatischeres C++ könnte dir nicht schaden. 😉

    Für Arrays konstanter Grösse könntest du z.B. std::tr1::array nehmen (falls du TR1 hast, sonst gäbe es das auch in Boost). Ist im Release-Modus genauso schnell wie ein C-Array, aber prüft im Debug-Modus Indizes und spart viel Debugzeit. Hat auch nützliche Methoden wie size() , sodass die Grösse nicht immer separat abgespeichert werden muss. Für dynamische Puffer kannst du statt mit new[] und delete[] selbst was zu basteln Containerklassen wie std::vector nehmen. Die Schnittstelle ist bei array und vector weitgehend einheitlich.

    // std::vector für dynamisches Array, als Beispiel
        std::vector<BYTE> hash;
    
        // std::tr1::array für statisches Array
        std::tr1::array<char, 32> finalhash;
    
        hash[index]; // zugreifen auf Elemente (beide Container)
        &hash[0]; // erhalten eines C-Strings für WinAPI-Interoperabilität
    
        // Statt deiner Schleife, nimm sowas (hat auch nicht quadratische Laufzeit):
        // Variablen wie l erst wenn nötig deklarieren!
        for(unsigned int l = 0; l < finalhash.size(); ++l)
    		finalhash[l] = 0;
    
        // Oder gleich so:
        std::fill(finalhash.begin(), finalhash.end(), 0);    
    
        // Statt strcpy_s kannst du z.B. std::copy() nehmen
        std::copy(finalhash.begin(), finalhash.end(), sec.begin());
    
        // Oder meinetwegen auch so, ohne hardgecodete Literale wie 33
        strcpy_s(&sec[0], sec.size(), finalhash);
    

    Lies dich vielleicht auf www.cplusplus.com in die Dokumentation der STL-Container und -Algorithmen etwas ein. Einen schönen Artikel findest du auch hier.



  • Hi

    wie bekomme ich denn ein char in ein std::tr1::array?
    Habe das mal gegooglt aber nichts zu gefunden.



  • Analog wie beim herkömmlichen Array. Statt

    char array[32];
    array[7] = 'h';
    

    schreibst du

    std::tr1::array<char, 32> array;
    array[7] = 'h';
    

    Und im Debug-Modus sollte Folgendes in einer Assertion enden:

    array[32] = 'h';
    

    Falls du allerdings einen voll funktionsfähigen String und nicht nur einen char -Puffer suchst, ist vielleicht std::string etwas komfortabler, da diese Klasse auch zur Laufzeit die Grösse ändern oder direkt von einem C-String konstruiert werden kann.



  • oh. Da ist mir wohl ein Fehler unterlaufen. Ich meine wie ich ein char array in einen std::tr1::array kopieren kann.



  • Initialisierung, wobei das Template-Argument Size mindestens der Länge des Stringliterals entsprechen muss (hier 6):

    std::tr1::array<char, Size> array = {"hallo"};
    

    Nachträglich:

    std::tr1::array<char, Size> array;
    const char* cString = "hallo";
    
    std::copy(cString, cString + std::strlen(cString) + 1, array.begin());
    

    Du könntest auch strcpy() benutzen, allerdings würdest du so den Vorteil geprüfter Iteratoren im Debug-Modus verlieren. Oder wenn du das öfter brauchst, kannst du selbst eine Funktion schreiben:

    typedef std::tr1::array<char, 32> CharArray;
    
    void AssignString(CharArray& array, const char* source)
    {
    	// Setze Iterator dest auf Anfang des Ziel-Arrays array
    	CharArray::iterator dest = array.begin();
    
    	// Kopiere solange noch Platz in dest und Nullterminierung noch nicht erreicht
    	while (dest != array.end() && *source != '\0')
    		*dest++ = *source++;
    
    	// Füge neue Nullterminierung hinzu
    	*(dest-1) = '\0';
    }
    
    int main()
    {
    	CharArray array;	
    	AssignString(array, "hallo");
    }
    

    Wenn der übergebene String zu lang ist, wird er abgeschnitten. Die Nullterminierung ist entweder gleich wie beim source -String oder sie steht im letzten Element des Arrays, falls der source -String zu gross ist. Der Grund, wieso der Code hier vergleichsweise kompliziert ist, besteht darin, dass std::tr1::array nicht auf Strings (schon gar nicht die aus C) ausgelegt wurde. Dafür wäre vielleicht wie gesagt std::string komfortabler.



  • OK Code sieht jetzt wie folgt aus gibt aber ein:

    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

    Hört sich so an als ob er auf Speicher außerhalb seiner Berechtigung schreibt.

    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);
    

    MD5.h

    #include <string>
    void MD5Hash(BYTE hash[],int sz,std::string cString);
    

    MD5.cpp

    #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;
    	copy(cString.begin(), cString.end() + 1, sec.begin());	
        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);
    }
    


  • 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. 😉


Anmelden zum Antworten