[调试器的设计]第五章 指令记录

5.1 问题的提出与分析
5.1.1 问题的分析
  当初听到这个的时候,觉得无从下手,而且也想到了很多极端的问题,比如运行的时候不停的修改原来的指令来达到往下运行的效果。然后进到API里面去 了,那个记录量是非常之大的,而且当时A1Pass的测试结果是每秒只能跑7条指令.于是花了很多时间在想着效率提升这块.后来和岳磊讨论一下,他叫我学 习一下OD的这个功能.
5.2 问题的解决
5.2.1 数据的组织
  因为可能记录的数据量非常之大,所以要采用一种合理的数据结构,比如用户可以按指令跑的顺序记下来,也可以按地址的高低来记录,程序在运行中,可能某 个地址的指令要跑很多次,但是我们不能重复记录很多次,所以这需要一种特定的数据结构,在程序中,我使用的是带头尾指针的链表与红黑树的结合,首先是将指 令加到链表尾部,然后再插到红黑树里面去,这样查找起来的话,速度非常快的(因为我们每跑一条指令,都要先判断一下树中有没有,没有的话才插到树中去), 而且体积只是比单单的红黑树多一个指针域。
名称:  1.jpg 查看次数: 432 文件大小:  11.8 KB

结合后的数据结构:这样就可以把链表与树的优点结合起来了,而补了链表的查找效率的不足。
名称:  2.jpg 查看次数: 430 文件大小:  11.6 KB

5.2.2 指令记录实现
  在第一个解决方案中,采用的是置单步记录,但是经过测试这个效率不高,而且处理起来也很复杂,比如对于每个call之类的指令,判断是不是调用API之类的,而且经常会出现一些小问题,兼容性也不太好!
  在第二个解决方案中,采用的是内存断点的方法,这个实现起来方便快捷,也不用判断是不是调用API,而且可以指定要记录的部分,不过内存断点的开销还是挺大的。

5.2.3 效率的优化
  假定计算机访问寄存器需要花费一个单位时间片,访问cache可能要花费几个单位时间片,或许现代计算机已经可以像访问寄存器那样高速了,但是访问内存却要花费一百多的单位时间,则访问磁盘则更慢了!
  为了充分的利用计算机时间,让写入磁盘与处理同时进行,在树节点中,我们直接记录指令的十六进制的值,而不直接记录反汇编结果,这样最大的节省空间, 如果对于调用API的话,在节点JmpConst中记录,如果没有的话,这个值为零。然后在写入磁盘的时间,调用反汇编引擎将Dump的内容解析出来,如 果JmpConst有值的话,再转成相应的DLL名和函数名。这样就可以并发处理了,从而充分的利用了CPU的时间以及节省了内存空间。

结点内存图:
点击图片以查看大图  图片名称: 3.jpg 查看次数: 431 文件大小: 8.7 KB 文件 ID : 42983


补充:
程序实现了脚本的功能,因为很简单,所以没有写在里面了!
用一个标志判断当前是从脚本输入还是从键盘输入,如果从脚本输入,则去脚本中取一行命令,如果遇到文件尾部,将标置位清零!

 

附件:

第五章节.pdf

转载于:https://www.cnblogs.com/DreamOfGalaxy/articles/4491924.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值