在程序崩溃后用于打印出错环境的一个C++类,使用它在程序出错后更快得找出出错的位置和原因。
打印内容的一个例子
----------------------------------------------------------------------------
System details:
-----------
Operating System: Microsoft Windows XP Professional (Version 5.1, Build 2600)
CPU Information: Type: Intel Pentium compatible, Number Of Processors: 2, Architecture: Intel, Level: Unknown 15, Stepping: 10-25
Memory Information: Memory Used 72%, Total Physical Memory 1048048KB, Physical Memory Available 286664KB, Total Virtual Memory 2097024KB, Available Virtual Memory 2054620KB, Working Set Min: 200KB Max: 1380KB .
Process details:
-----------
线程数:1, 句柄数:22
内存使用(K):3540, 内存使用峰值(K):3540, 页面缓冲池(K):20, 页面缓冲池峰值(K):20, 非页面缓冲池(K):2
非页面缓冲池峰值(K):2, 虚拟内存(K):3052, 虚拟内存峰值(K):3052, 页面错误:883
Exception details:
-----------
FirstChance:00000001, ExceptionCode:C0000005, ExceptionFlags:00000000, ExceptionAddress:004014B9
ExceptRem: STATUS_ACCESS_VIOLATION
Module: G:\testdump1.exe, Section: 01, Offset: 000004B9
Context details:
-----------
EFlags:00010206
EIP:004014B9
Ebp:0012FEF4
Esp:0012FEDC
Edi:00000000
Esi:0041A028
Ebx:7FFDE000
Edx:00000000
Ecx:00000009
Eax:00000009
Call stack:
-----------
Address Frame Function SourceFile
004014B9 0012FEF4 testexp1+49 testdump1.cpp line 37
Parameter struct TestClass* _pclass = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
Parameter int* _pint = [0x00000000]
Parameter int _int = 79
Local double t_double = 79.000000
Local char* t_pchar = "787878789"
Local int** t_ppint = [0x0012FF00]
Local enum TEnum t_Enum = 2
Local int t_Tmpint2 = 9
00401516 0012FF8C main+56 testdump1.cpp line 53
Parameter int argc = 1
Parameter char** argv = [0x00F4A680]
Local int t_int = 78
Local int* t_pint = [0x00000000]
Local struct TestClass t_class = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
Local char[60] command = ""
00414D83 0012FFB8 __startup+16F
Assembler Information:
-----------
testdump1.cpp
-------Line 25---------
00401470 push ebp
00401471 mov ebp, esp
00401473 add esp, -18
-------Line 27---------
00401476 mov dword ptr [ebp-4], 2
-------Line 29---------
0040147D mov eax, [ebp+8]
00401480 mov edx, [ebp-4]
00401483 mov [eax+4], edx
-------Line 31---------
00401486 lea ecx, [ebp+C]
00401489 mov [ebp-8], ecx
-------Line 32---------
0040148C mov dword ptr [ebp-C], 41A0C0
-------Line 33---------
00401493 fild dword ptr [41A0B8]
00401499 fstp qword ptr [ebp-14]
-------Line 34---------
0040149C fld qword ptr [ebp-14]
0040149F call 00411FD0
004014A4 mov [ebp+10], eax
-------Line 36---------
004014A7 push dword ptr [ebp-C]
004014AA call 0040C740
004014AF pop ecx
004014B0 mov [ebp-18], eax
-------Line 37---------
004014B3 mov edx, [ebp+C]
004014B6 mov ecx, [ebp-18]
004014B9 mov [edx], ecx ; <-- EXCEPTION
-------Line 39---------
004014BB mov esp, ebp
004014BD pop ebp
004014BE retn
------------------------用来产生异常的代码-----------------------------
int g_int = 0;
struct TestBaseClass
{
public:
char Memchar;
};
struct TestClass: public TestBaseClass
{
public:
int Mem1;
int Mem2;
TestClass* Mem3;
};
enum TEnum
{
EnumIdx1 = 1,
EnumIdx2 = 2,
};
void testexp1(TestClass* _pclass, int* _pint, int _int)
{
TEnum t_Enum = EnumIdx2;
{
_pclass->Mem1 = t_Enum;
}
int** t_ppint = &_pint;
char* t_pchar = "787878789";
double t_double = g_int;
_int = t_double;
{
int t_Tmpint2 = strlen(t_pchar);
*_pint = t_Tmpint2;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char command[60];
gets(command);
TestClass t_class;
t_class.Mem1 = 7;
t_class.Mem2 = 8;
t_class.Mem3 = NULL;
int* t_pint = NULL;
int t_int = 78;
g_int = 79;
__try
{
testexp1(&t_class, t_pint, t_int);
}
__except(1)
{
t_int++;
}
return 0;
}
----------------------------------------------------------------------------------------
主要用到的库有MS的DBGHELP库,Borland的Borland Debug Hook库.
前者网上的资料不少,但是后者网上基本找不到范例。
反汇编用的是OD主页上提供的反汇编引擎。
使用方法:需要在程序里自己写代码SetUnhandledExceptionFilter。然后使用这个类。
支持MS的PDB符号表和Borland的TDS符号表。把符号表文件放在EXE同目录下就可以。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: