动态调试与静态反汇编合一,运用虚拟机技术创建可逆向运行的调试器

标 题: 【原创】动态调试与静态反汇编合一,运用虚拟机技术创建可逆向运行的调试器
作 者: hjonline
时 间: 2010-08-22,21:00:53
链 接: http://bbs.pediy.com/showthread.php?t=119020


动态调试与静态反汇编合一,运用虚拟机技术创建可逆向运行的调试器

    现在的软件保护越来越厉害,从早先的加压缩壳、加密,发展到加密壳,虚拟机保护,以及扭曲变换等一系列的混淆手段,使得逆向一个软件的难度越来越大。究其根本原因,是人类天生不适合处理复杂的程序,在看过《代码大全2》之后,我发现作者一直在强调好的程序架构实际是在努力降低程序在管理上的复杂度,一个程序在运行时,至少在三个方面发生着变化,一个是空间:寄存器,内存的值在不断的变化;一个是时间,程序的运行顺序随时间推移而变化;第三个是语义上的变化,到底一段程序干了什么?它的目的是什么?它的实现机制是什么?看一行行的反汇编出来的代码都是很难搞懂的,更何况还有加壳加密这样的混淆手段在作怪,一段程序的二进制代码,再加上哪怕最简单的花指令混淆,都大大增加了复杂度,使得人脑理解它的原理变成一个艰巨的任务。
    
    混淆手段之所以成了逆向道路上的拦路虎,是在于人脑无法把许许多多条枯燥乏味的指令变成一个完整的概念,哪怕就是把两个数相加这样简单的事,编译成二进制代码,再加上花指令混淆,都很难理解它的本意,这就是加壳软件厉害的地方,许多恶意软件借助壳的帮助,逃脱了反病毒人员的逆向分析,在用户的电脑中为非作歹。(下面我把“壳”和混淆代码不加区分的使用了,少打几个字,读起来也简单。)
还有很多软件是用Java,VB这样以虚拟机为基础写的,要想在没有源代码的情况下移植到别的机器上,也是很难的事。而实际上如果能把这些二进制的程序先翻译成一种通用的中间语言,再把这种中间语言翻译成高级语言,就可以很好的利用它们来生产出更多的软件。

    为了达到更有效率的逆向以上这些软件的目的,首先要讨论的是能不能开发出这样一种程序,它能把程序中被混淆的东西暴露出来,去掉那些垃圾代码,把程序原始的面貌展现出来?
    
    我认为是可以的,因为一个很简单的事实:一个加了壳的软件,不论它的代码如何被混淆,它原有的功能不能变化,既不能多做,也不能少做,更不能做错。换句话说,从时间和空间上来看,原来这个程序的执行过程是一根线,加上壳,就多了壳这条线,两条线就像两根有塑料外皮的导线一样,再怎么交织在一起,两根电线中的电流是不会流到一起的,当线与线交织运行一定阶段后,一定要分开来各管各走,这样程序原来的功能才不会被破坏,无论是虚拟机还是扭曲变换,这条基本的定律是不会变的。
    
    然后我从上面这点推导出第二个观点是,壳这条线既然不影响程序的功能,那就是多余的东西,而多余的东西是可以被拿掉的。就是说程序在执行过程中,是可以不去走壳的这条线,也能行得通,而且走起来还快一点,事实上在我看了《编译原理》后发现编译器的代码优化就是起到去除冗余代码的作用的,随便多复杂的混淆代码,只要反汇编出来的汇编语句没有错误,把它放到编译器中优化一下,估计这些冗余代码都活不下去了。而逆向分析人员甚至都没必要去看。这样就大大节省了逆向的工作量。

    上面的这段话中有一个非常重要的条件,就是交给编译器去优化的代码必须是反汇编的时候没有错误的,而很多混淆代码使用了花指令这样的手段,使得静态反汇编出来的东西都是一团乱码,静态反编译因为不能再现程序中真实的变量值的变化,遇上跳转,CALL指令,搞不清是真是假,因为参数是未知的,比如"jmp eax"什么的,这样就大大影响了反汇编的质量,现今为止,没有什么方法能百分之百的静态反汇编成功。

    那么就让我们试试像OD这样的动态调试手段吧,动态调试可以真实地观察程序的运行情况,只要某个程序的片断跟踪过一次,基本上就得到了正确的反汇编代码,但是有三个问题,一是每个程序都有许多的分支,就像一棵树有许多的树梢,而调试器没办法一次走完所有的地方,所以反汇编出来的代码不完整;关于这个问题,可以把程序看成是一棵二叉树之类的东西,反正用个遍历算法,强制遍历一遍所有可用的分支,整个程序的反汇编就出来了吧。

    二是这些代码中有很多的循环,一个循环如果执行了1000遍,OD直接保存代码的话,就把这个循环体重复了1000遍,反汇编出来的代码又很多余。关于这个问题就要一边跟踪调试,一边在反汇编的基础上进行分析,建立基本块,循环体,子过程的结构,初步整理好代码。准备进一步的分析。

    三是OD还有一个很大的问题,就是它跟踪程序的过程不可逆的,我希望在调试程序时,程序运行到哪里,发现了问题,就反过来倒推,这要求保存程序每一步的状态,随时可以退回到前面任意的一个点上。这个问题也许可以试试建立一个数据库来保存相关信息,比如一个寄存器开始是什么值,后来这个值起了什么变化,放到了什么地方,又从什么地方取得了一个什么值,往往这些值是固定的,其实在程序中的各种变量值往往是固定的,从系统初始化开始,一步一步地搬动,加减运算什么的,一路上再怎么变,其实都是固定的数值关系,有些时候看上去好像每次运行都不一样的值,其实处理的方式是一样的,数据流是一样的,控制流也是一样的,要不然这个程序就有毛病了,好端端地运行它两次,结果第一次点“文件”菜单,出来的是“文件”菜单,第二次点变成“帮助”了,每次加减运算的结果都不一样,这样的程序没法用了,不等别人来逆向,自己先被用户抛弃了。所以,即使是系统调用,或者是用户输入,只要我们的调试器模拟输入的参数对路,那么一路上的流程是固定的,变量值的变化也是很容易计算的,关键是要能有个数据库来保存,来随时调用进行推算。

    综上所述,我们必须用动态跟踪的方法,获得跳转的间接路径,还要即时的反汇编出来,还要保存程序的运行状态,还要调用编译器优化来清除混淆代码。这里最好试试虚拟机的技术,在虚拟机中让程序运行,可以把程序和系统隔离开来,防止某些软件发现被调试后恶意地破坏我们的系统。

    这个“动态调试+静态反汇编优化”以去除混淆代码的设想背后是一个巨大的系统工程,想法本身不新鲜,网络上,论坛里,相关的资料和软件都有不少,比如虚拟机脱壳,比如可逆的调试器,但关键是它们没有拧成一股绳,没有在一个高层次的视野下统一起来。当然我只是个业余的编程爱好者,一个人做这样的事肯定是力所不能及的,但既然爱因斯坦那么看重人的想象力,所以我就先幻想一下,然后再一块砖一块砖的去搭建,这里先抛第一块砖吧。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么要学JVM1、一切JAVA代码都运行在JVM之上,只有深入理解虚拟机才能写出更强大的代码,解决更深层次的问题。2、JVM是迈向高级工程师、架构师的必备技能,也是高薪、高职位的不二选择。3、同时,JVM又是各大软件公司笔试、面试的重中之重,据统计,头部的30家互利网公司,均将JVM作为笔试面试的内容之一。4、JVM内容庞大、并且复杂难学,通过视频学习是最快速的学习手段。课程介绍本课程包含11个大章节,总计102课时,无论是笔试、面试,还是日常工作,可以让您游刃有余。第1章 基础入门,从JVM是什么开始讲起,理解JDK、JRE、JVM的关系,java的编译流程和执行流程,让您轻松入门。第2章 字节码文件,深入剖析字节码文件的全部组成结构,以及javap和jbe可视化反解析工具的使用。第3章 类的加载、解释、编译,本章节带你深入理解类加载器的分类、范围、双亲委托策略,自己手写类加载器,理解字节码解释器、即时编译器、混合模式、热点代码检测、分层编译等核心知识。第4章 内存模型,本章节涵盖JVM内存模型的全部内容,程序计数器、虚拟机栈、本地方法栈、方法区、永久代、元空间等全部内容。第5章 对象模型,本章节带你深入理解对象的创建过程、内存分配的方法、让你不再稀里糊涂。第6章 GC基础,本章节是垃圾回收的入门章节,带你了解GC回收的标准是什么,什么是可达性分析、安全点、安全区,四种引用类型的使用和区别等等。第7章 GC算法与收集器,本章节是垃圾回收的重点,掌握各种垃圾回收算法,分代收集策略,7种垃圾回收器的原理和使用,垃圾回收器的组合及分代收集等。第8章 GC日志详解,各种垃圾回收器的日志都是不同的,怎么样读懂各种垃圾回收日志就是本章节的内容。第9章 性能监控与故障排除,本章节实战学习jcmd、jmx、jconsul、jvisualvm、JMC、jps、jstatd、jmap、jstack、jinfo、jprofile、jhat总计12种性能监控和故障排查工具的使用。第10章 阿里巴巴Arthas在线诊断工具,这是一个特别小惊喜,教您怎样使用当前最火热的arthas调优工具,在线诊断各种JVM问题。第11章 故障排除,本章会使用实际案例讲解单点故障、高并发和垃圾回收导致的CPU过高的问题,怎样排查和解决它们。课程资料课程附带配套项目源码2个159页高清PDF理论篇课件1份89页高清PDF实战篇课件1份Unsafe源码PDF课件1份class_stats字段说明PDF文件1份jcmd Thread.print解析说明文件1份JProfiler内存工具说明文件1份字节码可视化解析工具1份GC日志可视化工具1份命令行工具cmder 1份学习方法理论篇部分推荐每天学习2课时,可以在公交地铁上用手机进行学习。实战篇部分推荐对照视频,使用配套源码,一边练习一遍学习。课程内容较多,不要一次性学太多,而是要循序渐进,坚持学习。      

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值