TMD/WL 的脱壳并不难,难的是 VM JMP(TMD的代码替代、偷取功能) 的修复,通常加壳者会在OEP或者关键位置偷取代码,以保证你即使脱掉了壳也无法让你正常运行,那么我今天要讲的就是如何修复。
修复是一件体力活儿,同时也是考验你对汇编、反汇编能力,在这里我们主要通过观察寄存器、堆栈的状态,其中堆栈就是为了保证CALL in/out的平衡,这样才能让程序走正确。而寄存器就是在VM中运行的每一步的状态,通过寄存器完全可以逆向成汇编语言。
这一节主要来讲讲如何简单的进行指令修复,讲之前我先讲下 CALL 指令,当运行到CALL会PUSH出下一条指令的内存地址,当运行到CALL的RETN指令时,会返回这个地址,然后POP掉,有些花指令就是用了这个原则,修改这个地址可以让EP返回指定地址。好,知道了以后我们进入
正题,如图1看到 当前EIP为 03508334(处于CODE段) 这是一个典型的 VM JMP,而指令下面的都是加密过的代码,直到返回,036643F7(处于VM段),具体可对照图2。当运行到这里时,我们第一步就是要在CODE段设置内存访问断点,执行 F9,当然F9之前可以记录下寄存器和堆栈的状态。
执行以后有2种状态第一种就是进入CODE段领空,处于一个VM所要保护的CALL的位置,直接进入说明CALL之前没有寄存器操作,而观察堆栈主要用于了解是否执行过 PUSH 指令,可以进行执行前后的对比观察,然后做记录。我这里由于是DLL的代码修复,所以要在DLL的代码段进行断点,EXE的修复在401000处,来到CALL以后可以删除断点直接返回(CTRL+F9),或者单步运行到返回,这时又进入VM段领空,如图3所示就是典型的VM代码保护的虚拟指令区,此时依然记录好寄存器和堆栈,在CODE段设置内存访问断点,执行 F9,你如果发现VM没有直接进入CODE领空,而是继续处于VM中,如图4,信息框中提示 DS:[03510280]=03519C50 (SystemMo.03519C50) 然后对照寄存器变化,就可以分析出此时的指令应该为 MOV EAX,DWORD PTR DS:[03510280],然后继续F9执行,依然在VM段信息提示 DS:[03519C50]=00000000 说明 VM执行 MOV EAX, DWORD PTR DS:[EAX]具体是不是EAX 你可以继续执行F9,直到进入CODE段,在此过程中严格记录下寄存器和堆栈变化,确保无误。这就是一个典型的VM JMP的指令修复,这里要着重注意堆栈情况。今天就讲到这了,下一节讲解一下段寄存器(DS SS 数据段和堆栈段寄存器)的操作与修复方法。
图1
图2
图3
图4
- 标 题:TMD/WL 代码修复讲解
- 作 者:lofullen
- 时 间:2010-09-30 22:36:04
- 链 接:http://bbs.pediy.com/showthread.php?t=121433