http://hi.baidu.com/ximo2006/blog/item/144661313b85224cac4b5f60.html

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

2010.11.03_ximo_过VMP加壳程序的自效验(vmp 2.06)相关推荐

  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. 神经网络不收敛的 11 个原因,加实践感悟

    神经网络不收敛的 11 个原因,加实践感悟 如果有说法不妥的,还望在评论区留言指点,切磋交流,十分感谢! 网上有朋友的博客:https://blog.csdn.net/lc013/article/de ...

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

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

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

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

  6. GameDev.net日报 2010.11.12 要卖了

    http://www.gamedev.net/community/forums/topic.asp?topic_id=587524 Posted by: Trent Polack at Novembe ...

  7. (转)游戏程序员养成计划 (更新2010.11.6)

    游戏程序员养成计划 (更新2010.11.6) 原文地址:http://www.cnblogs.com/clayman/archive/2009/05/17/1459001.html#2241553 ...

  8. 2010.11.25感恩节

    2010.11.25感恩节 到如今,我的脚步依然沉重,无声的压力挤着心-- 一年时光,一个学年,好似我在高速的列车上前行,时间没有同步上,在我的世界里是一秒种. 我在组装自己的梦想,我在前行. 要我的 ...

  9. 11 怎么给字符串加索引

    11 怎么给字符串加索引 现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引? 用户表定义 mysql> create table SUser( ID bigint uns ...

  10. http://www.searchtb.com/2010/11/protocol-buffers%E7%9A%84%E5%BA%94%E7%94%A8%E4%B

    http://www.searchtb.com/2010/11/protocol-buffers%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%8E%E5%88%86%E6%9E% ...

最新文章

  1. python中如何创建包_如何在Python中创建命名空间包?
  2. Unity3D之主菜单
  3. poj 2528 Mayor's posters (线段树+离散化)
  4. java有any类型吗_Java开发网 - 一个关于CORBA中any类型的问题
  5. 201521123018 《Java程序设计》第3周学习总结
  6. 小米12系列渲染图曝光:双曲面屏+屏下摄像头
  7. 支付,造就金融科技生态契机——保险科技生态建设...
  8. python 使用lxml中的xpath 和 scrpay中的xpath的区别
  9. WampServer中MySQL中文乱码解决
  10. 如何修改阿里云服务器的控制台root密码
  11. [转载]波斯亡国君为何选择大唐避难?
  12. 软测—直播教学 黑盒测试
  13. 豆瓣评论数据词云画像()
  14. 【Astar寻路算法图解】Java实现
  15. linux c 编译 未定义的引用,c – Linux makefile中的未定义引用
  16. 你相信进化吗?探索通用人工智能的重要途径 | 算法观点
  17. 基于thinkphp的开源App商城
  18. java 的新浪oauth_新浪微博OAuth授权的Java实现
  19. 基于eclipse开发源码分享-SSM+Activiti的公文管理系统,
  20. 使用pip安装模块出现:Cannot unpack file /tmp/pip-WY1nQb-unpack/simple.htm

热门文章

  1. 基于互联网的摄像测量系统(D 题)-- 2021 年全国大学生电子设计竞赛
  2. IPVS之Bypass转发模式
  3. java俄罗斯方块程序设计报告_java课程设计实验报告俄罗斯方块
  4. python机器人仿真软件_RoboDK(机器人仿真软件)软件下载_RoboDK(机器人仿真软件)v4.2.3 官方版 - Windows10系统之家...
  5. 计算机网络智能化在铁路通信的发展,浅谈新技术在铁路通信中的应用
  6. GetTickCount() 函数的作用和用法
  7. Nero 软件各种组件简单介绍
  8. VMware ESXi 7.0 SLIC 2.5 macOS Unlocker LegacyCPU MOD iso 百度网盘 下载
  9. Android自带的抓包工具tcpdump
  10. ARTS Share6 miniUI getData(true,false)获取form表单数据问题