吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9907|回复: 11
收起左侧

[分享] 学习继续和谐VMP2.0X~

[复制链接]
zjlsjz 发表于 2010-8-14 19:11
我们主要来看看IAT是如何修复的,首先看看修复的脚本.
   以下代码引用自Vmprotect 2.0x Unpacker脚本
  首先看看视频里的那5个变量mov first,0044CA98
mov write,004B5B72
mov getapi,004B372E
mov begin,0012F7FC
mov end,0012FB98
first : 是OEP,在这个脚本里OEP就是代表一个出口,代表在VM里执行解码IAT的函数已经执行完了.
   write :004B5B72   8910             MOV DWORD PTR DS:[EAX],EDX
这个其实是VMP的一个数据输出指令,相当于汇编里的mov dword ptr ds:[xxxxxxxx],reg32
   IAT是一组全局变量,而这个指令就是负责写入全局变量的.我们可以知道最终函数保存的地址,视频里下的写入断点就是为了快速地定位这条输出指令,这种方法在其它虚拟机里应该也是通用的.
   在VM里追踪数据,hook住数据的输入和输出指令是很常见的方法,以我个人的理解,这个和hook函数的思想是一样的.
   hook住这个指令后,可以得到些什么东西呢,答案就是函数的地址和key,在虚拟机里,数据的流动是很频繁的,那么如何确定是输出到IAT呢,就要靠下面的几个变量了.
   
   getapi :004B372E   36:8B00          MOV EAX,DWORD PTR SS:[EAX]
这个又是什么东东呢,看到这个指令使用SS前缀想到了吧,没错,这个就是VMP里的堆栈输入指令,这里可以把它看成汇编的mov reg32,dword ptr ss:[ebp],这条指令用来读取局部变量.
   在我上次的扫盲贴里已经说过了,VMP使用了随机指令表,每次的handle和指令的关系都是不一样的,因此每次分析时都需要修正指令表,而在视频里并没有分析指令表,而是直接定位指令,定位这个指令
的过程非常有趣,我们来看一下定位的过程.
   通常的情况下,解码IAT都是在一个循环里进行的,"读取key-->解密-->填充IAT"这样的流程,通过内存断点,我们找到了循环的尾部填充部分,只要不是最后一个函数,那么就会在下一轮再次命中输出断
点的,视频里的run trace就是追踪了一个循环的过程.因为这个循环解密了一个函数,所以必定要通过输入指令来读取key,在追踪的数据中查找输入指令的特征码就可以定位到指令了.
   
   光hook住输入指令和输出指令还不够,这两个指令会很频繁地调用,因此还要去除垃圾数据,用什么方法来去除垃圾数据呢,就靠下面的那两个变量了.
   begin和end光看名字就知道是IAT数据的界限了,VM掉的函数应该是VMP对IAT进行二次加密的函数,这时真正的数据是通过堆栈来传递的,用的是局部变量的数组,如何准确地查找这个表估计就只有凭经
验了.
   好了,修正完这些变量后,我们来看看脚本是如何工作的,脚本前面的部分是用来获取当前环境各段的基址和大小,用处在后面可以看到.
   接下来断VirtualProtect跳过解码.sub end,4
bphws end,"w"
esto
bphwc
bphws first
add end,4
在指令表尾部下一个写入断点,跳过解码过程,直接到二次加密.loopfix:
eval "eax>{begin}&&eax<{end}"
bpcnd getapi, $RESULT                //筛选无效的数据,只要不是引用指令表的数据都跳过
esto
cmp eip,first                                 //停下来的地方是OEP,解码过程已经结束了
je exit
bc eip
sti
mov rapi,eax
gn eax                                         //获取地址所对应的函数名
mov dllname,$RESULT_1
mov apiname,$RESULT_2
bp write                                       //断输出指令,记录加密后的地址
esto
cmp eip,first
je exit
bc eip                                          //取消输出断点,因为其他的指令也会调用输出指令,这里不取消的话就有可能杯具了
mov addr,eax                             //记录IAT的地址
mov dword,rapi
sub dword,edx                          //整个脚本最重要的地方,先记下来吧
wrta logfile,addr
wrta logfile,","
wrta logfile,dword
wrta logfile,","
wrta logfile,dllname
wrta logfile,","
wrta logfile,apiname
wrta logfile,"\r\n"
jmp loopfix
好了,脚本到这里就完了,下面我们来看生成的LOG文件
  LOG文件的开头这样的B               //段数,这里估计是用来确定IAT数据的起始
401000              //下面的都是基址和大小,估计是用来进行重定位,这里是带基址的 ,loader检查PE头??
4BAE0
44D000
1124
44F000
BD9
450000
1F2A
452000
10
453000
18
454000
5520
45A000
5400
460000
7190
468000
4DDBB
4B6000
5254
下面就是与IAT相关的数据了,这里举一个函数为例子,来理解戏法是怎么变的~
   和视频里一样,这里用的是456ED4,8ED28660,kernel32,GetModuleHandleA
456ED4是程序存放key的地址,8ED28660是脚本上面用sub计算出来的值,kernel32是DLL文件名,GetModuleHandleA是函数名.
   456ED4是需要重定位的,如果程序不是载入到00400000,那么就会出错,上面的那些数据估计就是用来对这个地址进行重定位了.

   其它都很好理解,关键就是8ED28660这个数值,要明白这个数值,首先要搞明白VMP的二次加密对函数地址做了些什么东西,和视频里一样,我们来看看关键的几条指令.00466171    BD 92E94300     MOV
EBP,delphi7?0043E992
00466180    8BAD 42850100   MOV EBP,DWORD PTR SS:[EBP+18542]
00462BE1    8DAD 6086D28E   LEA EBP,DWORD PTR SS:[EBP+8ED28660]
关键就这三条指令,0043E992+18542=456ED4,就是存放key的地址,看到了吗"8ED28660"这个就是脚本保存的数值,VMP对IAT的二次加密就是减去一个随机数,因为这些代码是分散在程序里,因此脚本直接模
拟这个减法运算,计算出这个随机值.接下来就是对函数进行重定位了,这个就是loader的作用了,loader可以通过GetProcAddress获得当前函数的地址,而随机数8ED28660加上456ED4保存的EDAE3041就可以
得到dump时的函数地址,然后用地址差值来修正456ED4保存的数据就可以了,如果你开始不明白的话,参考一下经典的自定位.        call @f
        @@:
        pop reg32
        sub reg32,@b

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yegeziz 发表于 2010-8-14 19:22
研究是好习惯
Zanker 发表于 2010-8-14 19:22
qq460218711 发表于 2010-8-14 19:22
ldw471427015 发表于 2010-8-14 19:22
看不懂.....
三月初七 发表于 2010-8-14 19:28
膜拜~

牛人、
 楼主| zjlsjz 发表于 2010-8-14 19:32
转载的-.-
fnx5 发表于 2010-8-14 19:44
进来学习下
zxc7754480 发表于 2010-8-14 21:38
来学习一下~~
chinamail 发表于 2010-8-19 08:46
谢谢分享,,,我昨天刚刚看了那录象,这些还真是我不懂的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 10:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表