experiment: convert dll to exe

来源:互联网 发布:js获取汉字拼音首字母 编辑:程序博客网 时间:2024/05/23 00:43

在调试时, 将dll  转换到 exe 的原因:

  * 在开发阶段, 功能性函数未完成. 如果单靠日志(文件日志或DebugView日志), 效率很低. 特别是比较微妙的地方, 很浪费时间.

  *  在有些应用系统下, 更换文件需要重新启动计算机生效, 换文件一个来回就是5分钟. 非常浪费时间,

  *  因为DLL需要宿主程序, 如果又在线程里. 有时编译的Release版带调试符号的程序根本Attach不上, 千真万确. 我遇上好几次. 不存在调试符号设置的问题, 就是Attach不上.

  *  在有些应用系统中, 因为加了反调试措施, 当vsIDE Attach 上目标DLL时, 程序报错.

  *  在某些应用系统中, 虽然是开发版没加反调试措施. 但是因为应用系统环境复杂,  有时Attach目标DLL后, 单步了几次, vsIDE就不返回了. 我遇到几次了, 很不爽.


在这些场景中, 为了给这个大的应用系统添加DLL中的功能性代码, 比较普遍的做法是: 将功能性代码抠出来, 在应用系统的一个控制台程序中验证完成功能性代码.


但是不好的地方是: 每个组件使用的头文件, 库文件, 都不相同. 有时存在复杂的头文件包含关系, 形成交叉引用, 使挪出来的功能性代码编译不过. 我们都知道, 编译不过, 需要调整头文件包含关系, 调整编译设置, 但这需要时间. 而且已经和我们将代码单独拉出来调试的本意,已经背道相驰.


今天下午也遇到了这种场景, Attach后, 没走一个单步, vsIDE就不返回了:(


突然想到实验一下, 将这个DLL直接编译成exe, 单步一下. 因为单步时, 可以强行设置运行的代码点, 我只想调试完我需要的功能, 其他的不管~.

实验的过程也简单, 几步就搞定了.  我的开发环境是vs2008sp1 + win7x64


步骤如下:

*  将svn控制的工程文件夹改名.

*  添加 对应的main()函数, 屏蔽掉DLL的入口函数

*  将编译选项的子系统改为console

* 将生成的目标类型由DLL改成EXE

* 将生成的目标文件名由xx.dll改成xx.exe

编译成功后, 直接对照工程文件(*.vcproj), 发现有一下不同.


区别:
dll :
ConfigurationType="2"
OutputFile="xx.dll"
SubSystem="2"
 
exe:
ConfigurationType="1"
OutputFile="xx.exe"
SubSystem="1"

我事先已经添加了一小段代码, 使要调试的代码上下文环境正确.
编译成功后, 将断点下到main函数的入口处. 我加了一个空的main 函数~

F5直接运行, 到达Main函数断点处.

然后我强行将下一步的代码运行点设置到我想调试的函数处, 很暴力啊~~


这种调试方法真好使,  因为功能性代码还没码完, 单步时, 发现考虑不周的地方, 马上停掉, 修正实现. 重新开始调试只需要半分钟~~

用这种方法, 很快就完成了我今天的任务~~


调试完成后, 将工程文件夹改成原来svn Checkout时的文件夹名称. 将*.sln, *.vcproj都用svn的revert功能还原, 去掉加入的测试代码和main函数, 恢复注释掉的DLL入口函数.

再次编译通过, svn提交. 大功告成~~


以后我会在功能性编码时, 多多的运用这种暴力的调试方法.


<2012_0720>

今天又运用这种调试方法, 迅速解决了一个DLL功能失效的问题, 仅仅花了10分钟.

DLL的宿主程序是正式打包后的安装程序安装出来的, 有反调试措施. 我也没有宿主程序的SVN权限, 当我将带调试符号的DLL换进系统后, 远程Attach到宿主程序, 马上Attach就断开了. 

我将DLL改版成EXE, 进入空的Main()函数后, 直接将下一步设置到被调试的函数前, 走了几步,就发现, 原来有个逻辑的判断, 由于手误, 将==写成了!=.


我偷偷得意的笑~

不过如果去现场, 就得完全靠日志来判断BUG生成的原因. 这种调试方法, 仅限于在公司内部的开发阶段, 调试功能性的编码.


vs2008IDE下, DLL 转 EXE的工程设置如下:


原创粉丝点击