过VMP加壳程序的自效验
2010-11-03 14:07

VMP加壳的选项中,有个内存效验选项,默认是勾上的,于是,默认的加壳后的程序,只要修改1个字节,程序就会报错。比如,我把加了VMP2.06后的记事本程序,用Hexworkshop打开,把最后一个字节,修改成90,如图:

然后保存后,打开程序,就会报如下错:

下面就来分析下,如何过这个效验。

VMP中,进行效验,都是由handler VM_CRC来进行的,大致的过程可以描述如下:

if(VM_CRC(dwCheckStartAddr,dwLen)==Orien_hash)
{
//继续执行
}
else
{
MessageBox("File corrupted!");
}

于是,过这个效验的方法就是:

法1.把修改后文件的效验值patch成原始的,也就是未修改程序的值

法2,强行修改跳转

下面先来看下VM_CRC:

Address Thread   Command                                   ; Registers and comments
010520C7 Main     setne dl                                  ; EDX=00840101
010520CA Main     bsf cx,di                                 ; ECX=01050003
010520CE Main     mov edx,dword ptr ss:[ebp]                ; EDX=0084013C //取效验的开始地址
010520D1 Main     pushfd
010520D2 Main     push esp
010520D3 Main     inc ch                                    ; ECX=01050103
010520D5 Main     cmp sp,bx
010520D8 Main     add ebp,4                                 ; EBP=0006F794
010520DB Main     ror ch,cl                                 ; ECX=01052003
010520DD Main     ror ch,cl                                 ; ECX=01050403
010520DF Main     rcl cx,3                                  ; ECX=01052018
010520E3 Main     add ch,86                                 ; ECX=0105A618
010520E6 Main     sub eax,eax                               ; EAX=00000000
010520E8 Main     add esp,8
010520EB Main     bt esp,0D
010520EF Main     mov ecx,eax                               ; ECX=00000000
010520F1 Main     push ecx
010520F2 Main     bt cx,8
010520F7 Main     jmp NOTEPAD_.010513F9
010513F9 Main     shl eax,7
010513FC Main     mov byte ptr ss:[esp],0AA
01051400 Main     shr ecx,19
01051403 Main     stc
01051404 Main     call NOTEPAD_.01052238
01052238 Main     stc
01052239 Main     cmp bl,al
0105223B Main     or eax,ecx
0105223D Main     call NOTEPAD_.010524E9
010524E9 Main     mov word ptr ss:[esp+4],si
010524EE Main     stc
010524EF Main     jmp NOTEPAD_.01050828
01050828 Main     xor al,byte ptr ds:[edx]                  ; EAX=00000002 //计算
0105082A Main     pushad
0105082B Main     inc edx                                   ; EDX=0084013D
0105082C Main     jmp NOTEPAD_.010513F0
010513F0 Main     mov byte ptr ss:[esp],23
010513F4 Main     jmp NOTEPAD_.010519AB
010519AB Main     pushfd
010519AC Main     dec dword ptr ss:[ebp]   //长度递减
010519AF Main     jmp NOTEPAD_.0104FFB1
0104FFB1 Main     mov byte ptr ss:[esp],0CE
0104FFB5 Main     push dword ptr ss:[esp]
0104FFB8 Main     call NOTEPAD_.01050DF8
01050DF8 Main     lea esp,dword ptr ss:[esp+38]
01050DFC Main     jnz NOTEPAD_.010520EB

......

01050E02 Main     pushfd
01050E03 Main     mov dword ptr ss:[ebp],eax //保存计算后的hash值
01050E06 Main     pushfd
01050E07 Main     push dword ptr ss:[esp+4]
01050E0B Main     mov byte ptr ss:[esp+8],bl
01050E0F Main     lea esp,dword ptr ss:[esp+C]
01050E13 Main     jmp NOTEPAD_.01052455
01052455 Main     jl NOTEPAD_.010512B1

从这条handler里,可以得到如下关键的信息:

1.效验的起始地址:CheckStartAddr

2.效验的长度:Len

3.计算后的效验值:CrcValue

说明:对于VM_CRC这条handler的获取,其实很简单,脱过VMP壳的应该都遇到过:
在VirtualProtectEx下好断,F9运行,一直到程序解码,然后在.text段下F2断点,F9运行,往往都会中断在xor al,byte ptr ds:[edx] 指令处,这就是VM_CRC了。接着就向上早这条handler的头就行了,小技巧就是:在OD中,右键---查找---常量,一步一步往上递归查找,就到handler的头了。

下面,写个脚本,来记录下VMP外壳到底在效验哪些地方,脚本如下:

var addr
var hash
var len
var logfile
var info
var end
var ref

var GetAddr
var GetLen
var GetHash
var stop

mov logfile,"log.txt"

bphwcall
bpmc
bc

///配置,根据程序自行修改

mov GetAddr,010520ce //获取效验开始地址
mov GetLen,010519ac   //获取长度
mov GetHash,01050e02 //获取计算后的效验值
mov stop,0100739d     //设置个脚本停止地址

bphws stop,"x"
bphws GetAddr,"x"
bphws GetHash,"x"

loop:
run
cmp eip,stop
je Exit
mov addr,[ebp]
bphws GetLen,"x"

run
mov len,[ebp]
bphwc GetLen

run
mov hash,eax
mov ref,dx

info:
mov end,addr
add end,len

eval "Check Addr:{addr}----{end}     VM_CRC:{hash}     ref:{ref}"
mov info,$RESULT
wrta logfile,info
jmp loop

Exit:
ret

记录后的效果如下:

Check Addr:84013C----840178       VM_CRC:6BE8626      ref:178
Check Addr:840180----8513B6       VM_CRC:4FAEC4C8     ref:13B6
Check Addr:8513E6----86EA00       VM_CRC:FCD461CC     ref:EA00
Check Addr:840000----840138       VM_CRC:A2031BDE     ref:138
Check Addr:104EB50----104EDB4     VM_CRC:9EEE9611     ref:EDB4
Check Addr:103B264----103B280     VM_CRC:44A10069     ref:B280
Check Addr:10523DE----105261F     VM_CRC:9571C843     ref:261F
Check Addr:100013C----1000178     VM_CRC:6BE8626      ref:178
Check Addr:1036129----1036A63     VM_CRC:CBEF3424     ref:6A63
Check Addr:102C904----102D74C     VM_CRC:12396730     ref:D74C
Check Addr:103B200----103B20C     VM_CRC:94966AA1     ref:B20C
Check Addr:103B250----103B25C     VM_CRC:98CB8F21     ref:B25C
Check Addr:103B283----104EB50     VM_CRC:5065D528     ref:EB50
Check Addr:103A2F6----103B194     VM_CRC:EFC06876     ref:B194
Check Addr:103B1D8----103B1E4     VM_CRC:92B333A1     ref:B1E4
Check Addr:103B23C----103B248     VM_CRC:97FB8F21     ref:B248
Check Addr:1000118----1000138     VM_CRC:49C882       ref:138
Check Addr:105138F----1051697     VM_CRC:D5374579     ref:1697
Check Addr:103B214----103B220     VM_CRC:159E05A1     ref:B220
Check Addr:1051FCB----10523C7     VM_CRC:F5C3B314     ref:23C7
Check Addr:1051036----105138B     VM_CRC:AD5AAA1A     ref:138B
Check Addr:102D750----102DDFF     VM_CRC:3EAD397E     ref:DDFF
Check Addr:10507A8----1050DA2     VM_CRC:FC7A3CF4     ref:DA2
Check Addr:103550E----1036125     VM_CRC:C1206AA9     ref:6125
Check Addr:104EF5A----1050790     VM_CRC:22A05033     ref:790
Check Addr:103B228----103B234     VM_CRC:16F1C6E2     ref:B234
Check Addr:103B1EC----103B1F8     VM_CRC:93BAC921     ref:B1F8
Check Addr:103A2B6----103A2F2     VM_CRC:56D8AA3B     ref:A2F2
Check Addr:1050DA6----1051032     VM_CRC:D7A929AE     ref:1032
Check Addr:103B1B0----103B1BC     VM_CRC:914D2621     ref:B1BC
Check Addr:1050794----10507A4     VM_CRC:7AC87546     ref:7A4
Check Addr:105169B----1051FA5     VM_CRC:89B75DFD     ref:1FA5

....下面略

下面来分析下这份日志:

由于我修改的文件是文件最后个字节,offset=2E9FF,转化成RVA=2E9FF,日志的前几行地址为84XXXX,显然,这个地址是内存中新申请的,下个bp MapViewOfFile看看,返回后可知,eax=00840000,于是,修改的地址,在内存映射中的地址=lpBase+RVA=00840000+2E9FF=0086E9FF

然后看日志的第三行:

Check Addr:8513E6----86EA00       VM_CRC:FCD461CC     ref:EA00

发现,这行记录的信息正好是效验了我们修改的地方。于是,我们只要手动patch这个效验值,就能使程序正常的运行起来。但是如何要使保存后的程序也能正常运行呢?于是得找个地方,去放patch的代码。

最好的思路就是找个没在上面日志中的效验的范围内的handler内,但是这个值往往不好找,省事点,直接在CRC计算的出口处进行patch,这个地址:

01050E02    9C                           pushfd   //这里patch
01050E03    8945 00                      mov dword ptr ss:[ebp],eax
01050E06    9C                           pushfd
01050E07    FF7424 04                    push dword ptr ss:[esp+4]
01050E0B    885C24 08                    mov byte ptr ss:[esp+8],bl
01050E0F    8D6424 0C                    lea esp,dword ptr ss:[esp+C]

但是,这个地址也正好存在在效验的范围内,看日志:

Check Addr:1050DA6----1051032     VM_CRC:D7A929AE     ref:1032

01050E02正好在这个效验的范围内,于是,这次效验值,我们也得进行patch。

当然,VMP并未对程序的空白区进行效验,于是,可以在程序最后的空数据区,随便patch。

如何patch呢?这个就自由发挥,我也不知道如何patch最佳,提供一种自己的挫patch代码:(说明下,脚本中记录的ref值,是为了进行patch对照用的,也就是一个参照数)

01050E02   /E9 A6180000                  jmp 修改.010526AD //放个跳转去进行patch
01050E07   |FF7424 04                    push dword ptr ss:[esp+4]
01050E0B   |885C24 08                    mov byte ptr ss:[esp+8],bl
01050E0F   |8D6424 0C                    lea esp,dword ptr ss:[esp+C]
01050E13   |E9 3D160000                  jmp 修改3.01052455
01050E18   |8B4C24 4C                    mov ecx,dword ptr ss:[esp+4C]

010526AD    66:81FA 00EA                 cmp dx,0EA00
010526B2    75 07                        jnz short 修改.010526BB
010526B4    B8 CC61D4FC                  mov eax,FCD461CC
010526B9    EB 0C                        jmp short 修改.010526C7
010526BB    66:81FA 3210                 cmp dx,1032
010526C0    75 05                        jnz short 修改.010526C7
010526C2    B8 AE29A9D7                  mov eax,D7A929AE
010526C7    9C                           pushfd
010526C8    8945 00                      mov dword ptr ss:[ebp],eax
010526CB    9C                           pushfd
010526CC ^ E9 36E7FFFF                  jmp 修改.01050E07

如此patch后,保存文件,即可正常运行。

当然,你也可以修改跳转的地方,来到过效验的目的。方法就是HOOK VM_Add32,0和4互换,这个上次的文章中提过了,就不赘述了。

附件为试练品,patch后的,以及脚本跟日志

http://u.115.com/file/t040893ff3

过VMP加壳程序的自效验相关推荐

  1. 加壳软件测试,VMProtect2.04加壳程序从入门到精通

    类型:加壳脱壳大小:13.5M语言:中文 评分:4.2 标签: 立即下载 第 7 页 虚拟执行环境与调试器检测 3.3.虚拟执行环境与调试器检测 在前面所有的节里面的内容全部都是贯穿的,没有一个地方遗 ...

  2. 第一课时(下):破解基础之常见加壳程序特征

    文章目录 一.压缩壳 1.1 UPX 1.1.a 使用查壳工具 1.1.b 分析区段信息 1.2 ASPack 1.2.a 使用查壳工具 1.2.b 分析区段信息 1.2.c 分析入口特征 二.保护壳 ...

  3. 【Android 逆向】加壳技术识别 ( 函数抽取 与 Native 化加壳的区分 | VMP 加壳与 Dex2C 加壳的区分 )

    文章目录 一.加壳特征识别 1.函数抽取 与 Native 化加壳的区分 2.VMP 加壳与 Dex2C 加壳的区分 一.加壳特征识别 1.函数抽取 与 Native 化加壳的区分 函数抽取 与 Na ...

  4. C#下的Windows服务通用壳程序(二)

    配置文件 (1)配置文件必须是固定的名称,这是为了方便壳程序读取. 1 <?xml version="1.0" encoding="utf-8" ?> ...

  5. 【原创】Android VMP加壳 POC

    介绍 这个壳的核心--字节码解释器,它参考了dalvik虚拟机的解释器.不需要hook.注入.目前只支持算数运算指令. 我个人把dalviki指令分为这么几类: 算数运算指令. 引用类指令.如cons ...

  6. 知物由学 | SO VMP 加壳与混淆,为移动应用提供函数级保护

    导读:VMP 是一种用于软件保护的软件,对软件进行加壳,加固厂商都有自己的 VMP 方案,但值得注意的是,native 层的 VMP 方案并不成熟,兼容性只是其中一个影响因素,性能更是导致该方案无法普 ...

  7. Map根据Key值进行排序(升序加降序)

    Map根据Key值进行排序 如果这篇文章对你有帮助的话,希望可以给博主点个赞,感谢!! 今天在写一个功能的时候,需要根据日期进行分组,于是我从数据库查找的时候就使用order by create_ti ...

  8. java 的 exe脱壳_[已解决]求教如何使用java编写加壳程序对PE文件进行加壳

    20 2017-5-8 15:15 这个问题就需要来谈谈壳的架构问题了. 壳的三大架构 1.最早的壳几乎都是virus演化来的,大部分都是汇编直接写的. 好处就是直接可以把汇编代码复制出来当作壳的lo ...

  9. 代码保护壳的设计--(3生成壳程序 )

    首先利用反汇编引擎解析并传入 壳数据 void PEProtecter::PushCode(unsigned va, unsigned len, unsigned _base) {char* buff ...

  10. 个人总结的一个VMP脱壳步骤

    个人总结的一个VMP脱壳步骤     个人在学习脱VMP加壳的过程中总结的一个步骤.按照这个步骤,包括VMP1.6-2.0在内应该有70%-80%能脱壳.脱不了的也别问我,我也刚开始学习.我还想找人问 ...

最新文章

  1. ASP.NET实现身份模拟
  2. 手把手教你搭建智能合约测试环境、开发、编译、部署以及如何通过JS调用合约方法
  3. Ubuntu下Astro Pro配置openni踩坑小记
  4. TypeError: 'stepUp' called on an object that does not implement interface HTMLInputElement.
  5. PHP将excel文件中的数据批量导入到数据库中
  6. 基于Hyper-V3.0搭建XenDesktop7之九 部署虚拟应用之模板准备
  7. 解决通过vue-router打开tab页,下次进入还是上次history缓存的界面状态的问题
  8. msp430中如何连续对位进行取反_四元数数控:如何保养视觉对位平台?
  9. 大数据建模,eBay的一个牛人
  10. python整数运算定律_PHP 操作redis 详细讲解
  11. 华为软挑2019总结
  12. 韩顺平JAVA学习笔记(入门自用)
  13. 人工鱼群算法解决TSP问题
  14. 由入门C语言题目浅析gets()函数的用法
  15. JS new一个对象的过程
  16. 空降如何快速融入接管团队
  17. ubuntu系统开机显示BusyBox v1.22.1(Ubuntu 1:1.22.0-15ubuntu1) built-in shell(ash) 问题的解决办法
  18. [转]Java咖啡馆---叹咖啡
  19. 关于计算机合成图像的应用中,数字图像合成技术综述
  20. Java语言程序设计基础篇原书第十版第二章编程练习题答案

热门文章

  1. Eclipse离线安装包官方下载地址
  2. 抖音快手无水印视频下载教程解析
  3. 海康威视 摄像头 RTMP 转 FLV
  4. 串口数据的抓取与监视
  5. html中optition默认类型,射频微电子学概论.PDF
  6. 最好用的HDR图像处理器——Photomatix Pro新功能介绍及使用教程
  7. linux设置定时重启任务
  8. 基本知识 100136
  9. 虚幻4 ai蓝图_高效AI自我监督学习的迷人蓝图
  10. 通信原理教程chapter1