Pufferüberlaufproblemen
-
Ah, ich hab die Definition weiter unten übersehen; dachte, du nimmst noch die alte.
Folgendes:
ostream os(&m_fb);wird vermutlich danebengehen; std::ostreams Konstruktor nimmt als Parameter nur einen Streambuffer. Aber da m_fb schon ein std::ostream ist, kannst du einfach
m_fb << Text << "\n";schreiben. Kompiliert der Konstruktoraufruf oben überhaupt?
-
m_fb ist ein filebuf. Deshalb kann folgendes:
m_fb << Text << "\n";nicht gehen
-
va_list sind nicht typsicher und sind eigentlich C Code.
Wie wäre es mit etwas C++0x:
namespace variadic { void print() { std::cout << std::endl; } template<typename Arg, typename ... Remains> void print(const Arg& arg, const Remains&... remains) { std::cout << arg; print(remains...); } }Sollte so passen. Erfordert aber ein --std=c++0x beim Kompilieren.
Und so tust du's anwenden:
variadic::print("Test ", 1, 2, 3, " okay es funktioniert!");
-
Ja das ist zum anzeigen in der Konsole sehr schön, aber ich möchte den Kram in eine Datei schreiben.
-
ok..
-
Das war jetzt nicht böse gemeint.
Habe die Funktion mit den Argument entfernt. Habe jetzt nur noch eine ganz einfach Funktion die einen String über ostream in eine Datei schreibt. Nur kommt es irgendwo, zu einem Pufferüberlauf, den ich mir nicht erklären kann.
-
Keiner mehr eine Idee?
-
Und der Überlauf kommt beim Schreiben in die Datei ?
-
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[]inBYTE*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/deletemitmalloc()/free()mischen**!**
In C++ solltest du primär
new/deletebzw.new[]/delete[]verwenden. Noch besser wäre natürlich automatische Speicherverwaltung mittels RAII. Gut möglich, dass hier auch dein Fehler liegt.#define MD5LEN 16Ziehe für Konstanten
const typeinem#definevor.
-
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::arraynehmen (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 wiesize(), sodass die Grösse nicht immer separat abgespeichert werden muss. Für dynamische Puffer kannst du statt mitnew[]unddelete[]selbst was zu basteln Containerklassen wiestd::vectornehmen. Die Schnittstelle ist beiarrayundvectorweitgehend 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 vielleichtstd::stringetwas 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
Sizemindestens 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 dersource-String zu gross ist. Der Grund, wieso der Code hier vergleichsweise kompliziert ist, besteht darin, dassstd::tr1::arraynicht auf Strings (schon gar nicht die aus C) ausgelegt wurde. Dafür wäre vielleicht wie gesagtstd::stringkomfortabler.
-
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:167Expression: 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?