dumpmemory window

    xiaoxiao2022-06-24  23

    utility.h

    // // Visual Leak Detector - Various Utility Definitions // Copyright (c) 2005-2006 Dan Moulding // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See COPYING.txt for the full terms of the GNU Lesser General Public License. // #pragma once #include <cstdio> #include <windows.h> #ifdef _WIN64 #define ADDRESSFORMAT L"0x%.16X" // Format string for 64-bit addresses #else #define ADDRESSFORMAT L"0x%.8X" // Format string for 32-bit addresses #endif // _WIN64 #define BOM 0xFEFF // Unicode byte-order mark. #define MAXREPORTLENGTH 511 // Maximum length, in characters, of "report" messages. // Architecture-specific definitions for x86 and x64 #if defined(_M_IX86) #define SIZEOFPTR 4 #define X86X64ARCHITECTURE IMAGE_FILE_MACHINE_I386 #define AXREG Eax #define BPREG Ebp #define IPREG Eip #define SPREG Esp #elif defined(_M_X64) #define SIZEOFPTR 8 #define X86X64ARCHITECTURE IMAGE_FILE_MACHINE_AMD64 #define AXREG Rax #define BPREG Rbp #define IPREG Rip #define SPREG Rsp #endif // _M_IX86 #if defined(_M_IX86) || defined (_M_X64) #define FRAMEPOINTER(fp) __asm {mov fp, BPREG} // Copies the current frame pointer to the supplied variable. #else // If you want to retarget Visual Leak Detector to another processor // architecture then you'll need to provide an architecture-specific macro to // obtain the frame pointer (or other address) which can be used to obtain the // return address and stack pointer of the calling frame. #error "Visual Leak Detector is not supported on this architecture." #endif // _M_IX86 || _M_X64 // Miscellaneous definitions #define R2VA(modulebase, rva) (((PBYTE)modulebase) + rva) // Relative Virtual Address to Virtual Address conversion. #define BYTEFORMATBUFFERLENGTH 4 #define HEXDUMPLINELENGTH 58 // Reports can be encoded as either ASCII or Unicode (UTF-16). enum encoding_e { ascii, unicode }; // Utility functions. See function definitions for details. VOID dumpmemorya (LPCVOID address, SIZE_T length); VOID dumpmemoryw (LPCVOID address, SIZE_T length); VOID report (LPCWSTR format, ...); VOID setreportencoding (encoding_e encoding); VOID setreportfile (FILE *file, BOOL copydebugger); VOID str_append (LPWSTR *dest, LPCWSTR source); // // Visual Leak Detector - Various Utility Functions // Copyright (c) 2005-2009 Dan Moulding // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See COPYING.txt for the full terms of the GNU Lesser General Public License. // #include <cassert> #include <cstdio> #include <windows.h> #if _WIN32_WINNT < 0x0600 // Windows XP or earlier, no GetProcessIdOfThread() #include <winternl.h> #endif #ifndef __out_xcount #define __out_xcount(x) // Workaround for the specstrings.h bug in the Platform SDK. #endif #define DBGHELP_TRANSLATE_TCHAR #include <dbghelp.h> // Provides portable executable (PE) image access functions. #define VLDBUILD // Declares that we are building Visual Leak Detector. #include "utility.h" // Provides various utility functions and macros. // Global variables. static BOOL reportdelay = FALSE; // If TRUE, we sleep for a bit after calling OutputDebugString to give the debugger time to catch up. static FILE *reportfile = NULL; // Pointer to the file, if any, to send the memory leak report to. static BOOL reporttodebugger = TRUE; // If TRUE, a copy of the memory leak report will be sent to the debugger for display. static encoding_e reportencoding = ascii; // Output encoding of the memory leak report. // dumpmemorya - Dumps a nicely formatted rendition of a region of memory. // Includes both the hex value of each byte and its ASCII equivalent (if // printable). // // - address (IN): Pointer to the beginning of the memory region to dump. // // - size (IN): The size, in bytes, of the region to dump. // // Return Value: // // None. // VOID dumpmemorya (LPCVOID address, SIZE_T size) { WCHAR ascdump [18] = {0}; SIZE_T ascindex; BYTE byte; SIZE_T byteindex; SIZE_T bytesdone; SIZE_T dumplen; WCHAR formatbuf [BYTEFORMATBUFFERLENGTH]; WCHAR hexdump [HEXDUMPLINELENGTH] = {0}; SIZE_T hexindex; // Each line of output is 16 bytes. if ((size % 16) == 0) { // No padding needed. dumplen = size; } else { // We'll need to pad the last line out to 16 bytes. dumplen = size + (16 - (size % 16)); } // For each byte of data, get both the ASCII equivalent (if it is a // printable character) and the hex representation. bytesdone = 0; for (byteindex = 0; byteindex < dumplen; byteindex++) { hexindex = 3 * ((byteindex % 16) + ((byteindex % 16) / 4)); // 3 characters per byte, plus a 3-character space after every 4 bytes. ascindex = (byteindex % 16) + (byteindex % 16) / 8; // 1 character per byte, plus a 1-character space after every 8 bytes. if (byteindex < size) { byte = ((PBYTE)address)[byteindex]; _snwprintf_s(formatbuf, BYTEFORMATBUFFERLENGTH, _TRUNCATE, L"%.2X ", byte); formatbuf[3] = '\0'; wcsncpy_s(hexdump + hexindex, HEXDUMPLINELENGTH - hexindex, formatbuf, 4); if (isgraph(byte)) { ascdump[ascindex] = (WCHAR)byte; } else { ascdump[ascindex] = L'.'; } } else { // Add padding to fill out the last line to 16 bytes. wcsncpy_s(hexdump + hexindex, HEXDUMPLINELENGTH - hexindex, L" ", 4); ascdump[ascindex] = L'.'; } bytesdone++; if ((bytesdone % 16) == 0) { // Print one line of data for every 16 bytes. Include the // ASCII dump and the hex dump side-by-side. report(L" %s %s\n", hexdump, ascdump); } else { if ((bytesdone % 8) == 0) { // Add a spacer in the ASCII dump after every 8 bytes. ascdump[ascindex + 1] = L' '; } if ((bytesdone % 4) == 0) { // Add a spacer in the hex dump after every 4 bytes. wcsncpy_s(hexdump + hexindex + 3, HEXDUMPLINELENGTH - hexindex - 3, L" ", 4); } } } } // dumpmemoryw - Dumps a nicely formatted rendition of a region of memory. // Includes both the hex value of each byte and its Unicode equivalent. // // - address (IN): Pointer to the beginning of the memory region to dump. // // - size (IN): The size, in bytes, of the region to dump. // // Return Value: // // None. // VOID dumpmemoryw (LPCVOID address, SIZE_T size) { BYTE byte; SIZE_T byteindex; SIZE_T bytesdone; SIZE_T dumplen; WCHAR formatbuf [BYTEFORMATBUFFERLENGTH]; WCHAR hexdump [HEXDUMPLINELENGTH] = {0}; SIZE_T hexindex; WORD word; WCHAR unidump [18] = {0}; SIZE_T uniindex; // Each line of output is 16 bytes. if ((size % 16) == 0) { // No padding needed. dumplen = size; } else { // We'll need to pad the last line out to 16 bytes. dumplen = size + (16 - (size % 16)); } // For each word of data, get both the Unicode equivalent and the hex // representation. bytesdone = 0; for (byteindex = 0; byteindex < dumplen; byteindex++) { hexindex = 3 * ((byteindex % 16) + ((byteindex % 16) / 4)); // 3 characters per byte, plus a 3-character space after every 4 bytes. uniindex = ((byteindex / 2) % 8) + ((byteindex / 2) % 8) / 8; // 1 character every other byte, plus a 1-character space after every 8 bytes. if (byteindex < size) { byte = ((PBYTE)address)[byteindex]; _snwprintf_s(formatbuf, BYTEFORMATBUFFERLENGTH, _TRUNCATE, L"%.2X ", byte); formatbuf[BYTEFORMATBUFFERLENGTH - 1] = '\0'; wcsncpy_s(hexdump + hexindex, HEXDUMPLINELENGTH - hexindex, formatbuf, 4); if (((byteindex % 2) == 0) && ((byteindex + 1) < dumplen)) { // On every even byte, print one character. word = ((PWORD)address)[byteindex / 2]; if ((word == 0x0000) || (word == 0x0020)) { unidump[uniindex] = L'.'; } else { unidump[uniindex] = word; } } } else { // Add padding to fill out the last line to 16 bytes. wcsncpy_s(hexdump + hexindex, HEXDUMPLINELENGTH - hexindex, L" ", 4); unidump[uniindex] = L'.'; } bytesdone++; if ((bytesdone % 16) == 0) { // Print one line of data for every 16 bytes. Include the // ASCII dump and the hex dump side-by-side. report(L" %s %s\n", hexdump, unidump); } else { if ((bytesdone % 8) == 0) { // Add a spacer in the ASCII dump after every 8 bytes. unidump[uniindex + 1] = L' '; } if ((bytesdone % 4) == 0) { // Add a spacer in the hex dump after every 4 bytes. wcsncpy_s(hexdump + hexindex + 3, HEXDUMPLINELENGTH - hexindex - 3, L" ", 4); } } } } // report - Sends a printf-style formatted message to the debugger for display // and/or to a file. // // Note: A message longer than MAXREPORTLENGTH characters will be truncated // to MAXREPORTLENGTH. // // - format (IN): Specifies a printf-compliant format string containing the // message to be sent to the debugger. // // - ... (IN): Arguments to be formatted using the specified format string. // // Return Value: // // None. // VOID report (LPCWSTR format, ...) { va_list args; size_t count; CHAR messagea [MAXREPORTLENGTH + 1]; WCHAR messagew [MAXREPORTLENGTH + 1]; va_start(args, format); _vsnwprintf_s(messagew, MAXREPORTLENGTH + 1, _TRUNCATE, format, args); va_end(args); messagew[MAXREPORTLENGTH] = L'\0'; if (reportencoding == unicode) { if (reportfile != NULL) { // Send the report to the previously specified file. fwrite(messagew, sizeof(WCHAR), wcslen(messagew), reportfile); } if (reporttodebugger) { OutputDebugStringW(messagew); wprintf(messagew); } } else { if (wcstombs_s(&count, messagea, MAXREPORTLENGTH + 1, messagew, _TRUNCATE) == -1) { // Failed to convert the Unicode message to ASCII. assert(FALSE); return; } messagea[MAXREPORTLENGTH] = '\0'; if (reportfile != NULL) { // Send the report to the previously specified file. fwrite(messagea, sizeof(CHAR), strlen(messagea), reportfile); } if (reporttodebugger) { OutputDebugStringA(messagea); printf(messagea); } } if (reporttodebugger && (reportdelay == TRUE)) { Sleep(10); // Workaround the Visual Studio 6 bug where debug strings are sometimes lost if they're sent too fast. } } // setreportencoding - Sets the output encoding of report messages to either // ASCII (the default) or Unicode. // // - encoding (IN): Specifies either "ascii" or "unicode". // // Return Value: // // None. // VOID setreportencoding (encoding_e encoding) { switch (encoding) { case ascii: case unicode: reportencoding = encoding; break; default: assert(FALSE); } } // setreportfile - Sets a destination file to which all report messages should // be sent. If this function is not called to set a destination file, then // report messages will be sent to the debugger instead of to a file. // // - file (IN): Pointer to an open file, to which future report messages should // be sent. // // - copydebugger (IN): If true, in addition to sending report messages to // the specified file, a copy of each message will also be sent to the // debugger. // // Return Value: // // None. // VOID setreportfile (FILE *file, BOOL copydebugger) { reportfile = file; reporttodebugger = copydebugger; } // str_append - Appends the specified source string to the specified destination // string. Allocates additional space so that the destination string "grows" // as new strings are appended to it. This function is fairly infrequently // used so efficiency is not a major concern. // // - dest (IN/OUT): Address of the destination string. Receives the resulting // combined string after the append operation. // // - source (IN): Source string to be appended to the destination string. // // Return Value: // // None. // VOID str_append (LPWSTR *dest, LPCWSTR source) { SIZE_T length; LPWSTR temp; temp = *dest; length = wcslen(*dest) + wcslen(source); *dest = new WCHAR [length + 1]; wcsncpy_s(*dest, length + 1, temp, _TRUNCATE); wcsncat_s(*dest, length + 1, source, _TRUNCATE); delete [] temp; } typedef struct Person{ int id; int age; char name[10]; char city[10]; } Person; struct Student:Person{ int score; char classroom[10]; } Student; struct Teacher:Person{ int level; char subject[10]; } Teacher; void test_a() { FILE* fp=fopen("log_a.txt","w+"); setreportfile(fp,TRUE); setreportencoding(ascii); Person p; p.id=1024; p.age=26; strcpy(p.name,"yunshouhu"); strcpy(p.city,"shenzhen"); cout << "==========Person============" << endl; dumpmemorya(&p,sizeof(p)); cout << "======Student================" << endl; struct Student stu; stu.id=1048; stu.age=27; strcpy(stu.name,"yunshouhu001"); strcpy(stu.city,"北京"); stu.score=99; strcpy(stu.classroom,"一年级二班"); dumpmemorya(&stu,sizeof(stu)); struct Teacher teacher; teacher.id=p.id; teacher.age=p.age; strcpy(teacher.name,p.name); strcpy(teacher.city,p.city); strcpy(teacher.subject,"chinese"); teacher.level=3; cout << "==========teacher============" << endl; dumpmemorya(&teacher,sizeof(teacher)); int a=512; cout << "==========int============" << endl; dumpmemorya(&a,sizeof(a)); int* aa=&a; cout << "==========int aa============" << endl; dumpmemorya(aa,sizeof(aa)); int aaa=*aa; cout << "==========int aaa============" << endl; dumpmemorya(&aaa,sizeof(aaa)); float b=33.3f; cout << "==========float============" << endl; dumpmemorya(&b,sizeof(float)); char c='c'; cout << "==========char============" << endl; dumpmemorya(&c,sizeof(char)); } void test_b() { FILE* fp=fopen("log_w.txt","w+"); setreportfile(fp,TRUE); setreportencoding(unicode); Person p; p.id=1024; p.age=26; strcpy(p.name,"yunshouhu"); strcpy(p.city,"shenzhen"); cout << "==========Person============" << endl; dumpmemoryw(&p,sizeof(p)); cout << "======Student================" << endl; struct Student stu; stu.id=1048; stu.age=27; strcpy(stu.name,"yunshouhu001"); strcpy(stu.city,""); stu.score=99; strcpy(stu.classroom,""); dumpmemoryw(&stu,sizeof(stu)); struct Teacher teacher; teacher.id=p.id; teacher.age=p.age; strcpy(teacher.name,p.name); strcpy(teacher.city,p.city); strcpy(teacher.subject,"chinese"); teacher.level=3; cout << "==========teacher============" << endl; dumpmemoryw(&teacher,sizeof(teacher)); int a=512; cout << "==========int============" << endl; dumpmemoryw(&a,sizeof(a)); int* aa=&a; cout << "==========int aa============" << endl; dumpmemoryw(aa,sizeof(aa)); int aaa=*aa; cout << "==========int aaa============" << endl; dumpmemoryw(&aaa,sizeof(aaa)); float b=33.3f; cout << "==========float============" << endl; dumpmemoryw(&b,sizeof(float)); char c='c'; cout << "==========char============" << endl; dumpmemoryw(&c,sizeof(char)); }

    转载请注明原文地址: https://ju.6miu.com/read-1123795.html

    最新回复(0)