VC编译Release程序,如何在不生成debug信息(pdb文件)情况下处理崩溃

玄冬Wong 2012-08-15 01:13:51
如题,VC编译Release程序,如果生成debug信息,就可以获取dump文件,如何在不生成debug信息(pdb文件)、并进行优化的情况下处理崩溃呢,先说声谢谢!!
...全文
696 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
玄冬Wong 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]

转储堆栈就是把 异常时 ESP 附近的内容全保存下来, 比如保存 [ ESP , ESP + 64K ] 的内容, 有这些东西, 找保存下异常时后的 CONTEXT, 即使编译的时候木有用 -Oy- 选项, 也可以手工恢复栈帧, 就是比较麻烦的说, 也可以恢复出异常时各个局部变量的值...

转储模块信息就是 保存异常时候全部的DLL模块的基址, 不然不好恢复DLL里函数栈帧...

一……
[/Quote]
喔,小弟我有空去研究下,非常感谢!!
mLee79 2012-08-15
  • 打赏
  • 举报
回复
转储堆栈就是把 异常时 ESP 附近的内容全保存下来, 比如保存 [ ESP , ESP + 64K ] 的内容, 有这些东西, 找保存下异常时后的 CONTEXT, 即使编译的时候木有用 -Oy- 选项, 也可以手工恢复栈帧, 就是比较麻烦的说, 也可以恢复出异常时各个局部变量的值...

转储模块信息就是 保存异常时候全部的DLL模块的基址, 不然不好恢复DLL里函数栈帧...

一般有下面的出错信息, 基本就可以恢复异常时候的程序状态:

1: 当前全部的寄存器值
2: 堆栈的转储信息
3: 全部模块加载的基地址

backtrace都可以直接用1,2的信息拿回来以后再做....
星星眼 2012-08-15
  • 打赏
  • 举报
回复
加上VMP,加大破解难度。
玄冬Wong 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

引用 8 楼 的回复:

引用 4 楼 的回复:

引用 2 楼 的回复:
引用 1 楼 的回复:

不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断


喔,我不想生成pdb是想防止程序被别人反编译,有没其他更好的办法?

生成pdb,你别把pdb文件给最终用……
[/Quote]

非常感谢mLee79,再请教下什么是“转储堆栈+转储模块信息”,能否再点拨下
mLee79 2012-08-15
  • 打赏
  • 举报
回复
一个最简单的例子, linux下的就不写了, 比这个方便一些..

比如最简单的个测试:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define STACK_FRAME_MAXSIZE 0x40000

struct i386_stack_frame
{
struct i386_stack_frame* next;
void* fret;
};

int i386_backtrace_( void* sym[] , int n , struct i386_stack_frame* frame )
{
int i = 0;
struct i386_stack_frame *frame_begin = frame , *frame_end = frame_begin + STACK_FRAME_MAXSIZE;

while( 1 )
{
if( i >= n || NULL == frame || frame < frame_begin || frame > frame_end || ((int)frame & 3) != 0 )
break;
sym[i++] = frame->fret;
frame = frame->next;
}
return i;
}

void foobar( int* nil )
{
*nil = 0;
}

int except_filter( PEXCEPTION_RECORD rcd , PCONTEXT ctx , void* callstack[] , int* n , struct _EXCEPTION_POINTERS* info )
{
memcpy( rcd , info->ExceptionRecord , sizeof( *rcd ) );
memcpy( ctx , info->ContextRecord , sizeof( *ctx ) );
*n = i386_backtrace_( callstack , *n , (void*)ctx->Ebp );
return 1;
}

int main()
{
void* callstack[100] = {0} ;
int n = 100;
EXCEPTION_RECORD rcd;
CONTEXT ctx;

__try
{
foobar( NULL );
}
__except( except_filter( &rcd , &ctx , callstack , &n , GetExceptionInformation() ) )
{
int i;
printf( "Load addr: %p\n" , GetModuleHandle(NULL) );
printf( "callstack:\n\t%x\n" , ctx.Eip );
for( i = 0; i < n; ++i )
{
printf( "\t%x\n" , callstack[i] );
}
}

return 0;
}

如下编译:

cl -nologo 1.c -link -map
Relase 版本这样子编译 cl -O2 -Oy- -nologo 1.c -link -map

生成的mapfile(部分):
Address Publics by Value Rva+Base Lib:Object

0000:00000000 __except_list 00000000 <absolute>
0000:00000003 ___safe_se_handler_count 00000003 <absolute>
0000:00000000 ___ImageBase 00400000 <linker-defined>
0001:00000000 _i386_backtrace_ 00401000 f 1.obj
0001:00000080 _foobar 00401080 f 1.obj
0001:00000090 _except_filter 00401090 f 1.obj
0001:000000f0 _main 004010f0 f 1.obj
0001:00000230 _memcpy 00401230 f LIBCMT:memcpy.obj
0001:00000591 _printf 00401591 f LIBCMT:printf.obj
0001:00000638 __get_printf_count_output 00401638 f LIBCMT:printf.obj
0001:0000064e @__security_check_cookie@4 0040164e f LIBCMT:secchk.obj
0001:00000660 __except_handler4 00401660 f LIBCMT:chandler4.obj
0001:000007f0 _memset 004017f0 f LIBCMT:memset.obj


运行结果:
Load addr: 01380000
callstack:
1381086
1381161
138199e
746c339a
76fa9ef2
76fa9ec5
0

把这些输出地址 - 01380000 + 00400000 然后到mapfile里去查对应的函数, 得到 callstack 为:
_foobar + 0006
_main + 0071

如果你还想分析出 dll 里的函数名, 先把全部的dll模块枚举出来.

这VS2010咋这么破, mapfile 里有些函数地址咋个是错误的, 与我在IDA里看的对不上.


mLee79 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

引用 4 楼 的回复:

引用 2 楼 的回复:
引用 1 楼 的回复:

不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断


喔,我不想生成pdb是想防止程序被别人反编译,有没其他更好的办法?

生成pdb,你别把pdb文件给最终用户不就行了?


若没有p……
[/Quote]

谁说没有pdb就没法dump了, 你自己在程序里backtrace+转储堆栈+转储模块信息就是, 只是不能自动的定位到函数,行号, 有了地址, 你还不能查pdb,查map确定崩溃时的栈帧么....
赵4老师 2012-08-15
  • 打赏
  • 举报
回复
让用户将dump文件发给你,你在本地加载dump文件和pdb文件
或者
你从自己公司网站下载pdb文件到用户机器上,用ntsd或其它调试器加载dump和pdb。调试完毕后从用户机器上删除pdb文件。
xunxun 2012-08-15
  • 打赏
  • 举报
回复
我只想说有没有pdb的逆向难度是相同的
nice_cxf 2012-08-15
  • 打赏
  • 举报
回复
dump重要还是反编译重要你自己权衡就是了,而且就算有pdb文件,对反编译又有多大影响呢?
玄冬Wong 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 5 楼 的回复:

引用 3 楼 的回复:

有pdb也没法反编译啊, 在程序里SEGV的时候做backtrace + 堆栈转储, 结合mapfile人肉恢复callstack是没有问题的, 就是麻烦点, 编译的时候得加上 -Oy- 禁止优化函数栈帧...


你这个mapfile是link出来的那个?


嗯, link加 /map 参数.
有了 pdb 也就读……
[/Quote]
有了pdb不是可以看到所有函数名,这样可以帮助反编译的人提供信息吧
玄冬Wong 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

引用 2 楼 的回复:
引用 1 楼 的回复:

不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断


喔,我不想生成pdb是想防止程序被别人反编译,有没其他更好的办法?

生成pdb,你别把pdb文件给最终用户不就行了?
[/Quote]

若没有pdb就没办法生成dump了吧,但我必须从用户那里收集dump信息
mLee79 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 3 楼 的回复:

有pdb也没法反编译啊, 在程序里SEGV的时候做backtrace + 堆栈转储, 结合mapfile人肉恢复callstack是没有问题的, 就是麻烦点, 编译的时候得加上 -Oy- 禁止优化函数栈帧...


你这个mapfile是link出来的那个?
[/Quote]

嗯, link加 /map 参数.
有了 pdb 也就读汇编的时候多点符号信息, 对反编译没啥帮助.
xunxun 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

引用 2 楼 的回复:
引用 1 楼 的回复:

不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断


喔,我不想生成pdb是想防止程序被别人反编译,有没其他更好的办法?

生成pdb,你别把pdb文件给最终用户不就行了?
[/Quote]

即使给最终用户,也很难反编译

Windows的dll的pdb可都是公开的
xunxun 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

有pdb也没法反编译啊, 在程序里SEGV的时候做backtrace + 堆栈转储, 结合mapfile人肉恢复callstack是没有问题的, 就是麻烦点, 编译的时候得加上 -Oy- 禁止优化函数栈帧...
[/Quote]

你这个mapfile是link出来的那个?
赵4老师 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
引用 1 楼 的回复:

不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断


喔,我不想生成pdb是想防止程序被别人反编译,有没其他更好的办法?
[/Quote]
生成pdb,你别把pdb文件给最终用户不就行了?
mLee79 2012-08-15
  • 打赏
  • 举报
回复
有pdb也没法反编译啊, 在程序里SEGV的时候做backtrace + 堆栈转储, 结合mapfile人肉恢复callstack是没有问题的, 就是麻烦点, 编译的时候得加上 -Oy- 禁止优化函数栈帧...
玄冬Wong 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断
[/Quote]

喔,我不想生成pdb是想防止程序被别人反编译,有没其他更好的办法?
xunxun 2012-08-15
  • 打赏
  • 举报
回复
不生成pdb?

那么要看反汇编猜

为啥不用pdb,想不通你要干啥


其他用手动传统调试亦可,比如用printf/cout输出信息来判断

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧