令人崩溃抓狂的错误,怎么才能抓到它?

阿呆_ 2010-12-21 02:07:42
为公司项目写了一个加壳工具,加壳后的程序使用自我调试的方法实现运行时动态加密解密代码页。

壳的思路也很简单:
当加壳后的程序运行时首先解密壳代码的IAT表和真正壳入口地址然后跳转到壳入口继续执行, 壳入口处判断用户权限, 如果是非Administrator, 则判断是否正被调试器调试, 如果是则随机跳到任意内存地址执行(引起程序或系统崩溃), 否则用CreateProcess启动自身另一副本并调试执行它, 并在需要的时候动态解密/加密副本进程中的代码块。
如果是Administrator权限, 则判断当前系统是32位还是64位, 根据不同系统解密/解压壳中保存的32位或64位exe程序并保存到当前目录下一个临时文件中并运行它然后等待。 这个exe的功能非常简单, 它列出当前session中已经运行并且可以被访问的相应32位或64位进程, 然后随机挑选一个进程打开, 解密/解压/重定向exe中保存的调试器代码到目的进程空间, 然后创建一个远程线程并退出。 退出后exe文件会由主程序删除。 而远程线程的32位或64位代码则开始调试主程序,并在需要的时候动态加密/解密主程序代码块。

加壳基本上可以说成功了, 用debug版的壳代码加壳的程序运行非常流畅, 不管是普通win32程序还是service程序都没有错误, 如果用的是release版的壳代码, 对service程序加壳后在64bit win7下会出现非常令人抓狂的错误, 即第一次运行成功, stop后再start则超时失败, 如果再start又成功, 再次stop->start又失败,... , 测试几十次后发现加壳后的service程序非常精确地呈现50%成功率, 而且是第1,3,5,7...次启动肯定成功,第2,4,6,8...次启动必然失败。

为了找到哪里出现问题我在壳代码中加入了log功能, 输出一些关键信息到c:\logs\下的某个文件中, 再次编译后发觉不管加壳哪种程序, 运行就没失败过, 次次成功。 而一旦移去log代码后release版壳代码加壳后的service程序又呈现那种精确的50%成功率。

崩溃...

到底该如何找到这个该死的错误? 跪求思路...
...全文
184 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿呆_ 2010-12-22
  • 打赏
  • 举报
回复
又机械反复测试了半天,估计尝试了30多次,终于带log的代码失败了三次,初步可以确定问题出在RemoteThread这块,失败的三次中有一次是创建线程失败, lasterror显示系统资源不足--我原本代码中创建的线程时指定分配1M堆栈, 估计太大? 正好插入的那个进程没那么大空间? 我将其改为0(使用原进程默认堆栈)后,多次测试又发现失败2次,而这2次的log显示则是CreateRemoteThread成功返回了线程句柄但线程代码显然没有执行(用WaitForSingleObject(ThreadHandle, 100)返回的是TIMEOUT, 说明线程并没有结束--可能根本就没有开始) 实在无法确定到底哪里出了问题, 如果是线程代码的问题那么不可能只失败2次吧? 而且线程入口第二句就是log调用, 失败的那两次却根本没有这块的log生成(我的log是按线程分文件的,不同线程中的log存到不同文件中)。
按逻辑分析那么出错的地方可能就是远程线程第一句调用,但这句是调用一个子过程loadlibrary所有线程需要的dll, 反复研究了这段代码,可实在找不出出错的地方, 另外如果其中任何一个dll加载失败的话该调用会返回FALSE, 那么后续语句都不会执行就直接结束线程了。 如果是由于DLL加载失败导致线程结束, 那么外面的那个WaitForSingleObject()就应该返回WAIT_OBJECT_0而不应该是目前LOG到的WAIT_TIMEOUT, 这完全不符合逻辑呀?

还在抓瞎中...
手机写程序 2010-12-21
  • 打赏
  • 举报
回复
release版可以用OutputDebugString和工具debugview配合使用,别用log文件.
whq_0413 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xumaojun 的回复:]
日志不要全去掉,先去掉一部分试试,再慢慢定位。
[/Quote]

我严重支持此观点.
bai_shou 2010-12-21
  • 打赏
  • 举报
回复
数组越界?
hzy694358 2010-12-21
  • 打赏
  • 举报
回复
对楼主表示杯具……
zyyoung 2010-12-21
  • 打赏
  • 举报
回复
REALEASE版本跟DEBUG版本的变量的默认初始值好像有不同

release下变量使用前,确保初始化
kirainstorm 2010-12-21
  • 打赏
  • 举报
回复
变量初始化的问题吧,看下有没有变量没有给定值就使用。REALEASE版本跟DEBUG版本的变量的默认初始值好像有不同
手机写程序 2010-12-21
  • 打赏
  • 举报
回复
可能有东西没释放干净?
xumaojun 2010-12-21
  • 打赏
  • 举报
回复
日志不要全去掉,先去掉一部分试试,再慢慢定位。
快乐鹦鹉 2010-12-21
  • 打赏
  • 举报
回复
难道是需要延时?你增加了写日志代码,正好满足了延时的需求?间隔着成功,好像也有类似延时的需求。
只是猜测。
大蓝头 2010-12-21
  • 打赏
  • 举报
回复
这么有规律的话,应该比较好找了,加油!
yihandrensunyong 2010-12-21
  • 打赏
  • 举报
回复
看下REALEASE版本下面的工程属性里面跟DEBUG版本里哪里有不同

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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