学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1157

主题

[转载图文] 谈谈vmp的还原(1)

发表于 2020-9-18 14:00:09 | 查看: 1808| 回复: 1
0x00 前言看到有朋友提前发相关文章了,没办法我也只能提前发了。

首先文章不同于其他的文章,从vmp是如何vm opcode入手,看完以后不说还原,相信爆破,静态分析也应该有所帮助。
主要是vmp3.x以下。


0x01 简介vmp的流程
大体如下:

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)




直接定位到流程:

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)



首先读了vmp_opcode_begin_block end_block
然后计算_vm_opcode_size

谈谈vmp的还原(1)

谈谈vmp的还原(1)



没错,之前的帖子有提到,vmp作者设计了4套handle,就是这4套了。

谈谈vmp的还原(1)

谈谈vmp的还原(1)




注意到上上图113行之后,同时我们也可以看出早期版本的构造

谈谈vmp的还原(1)

谈谈vmp的还原(1)




下面这个,之前也有提到

谈谈vmp的还原(1)

谈谈vmp的还原(1)




注意到+8,之后会说

先允许我跳过esi的构造以及修复,继续讲下去

谈谈vmp的还原(1)

谈谈vmp的还原(1)



可以看到vmp通过这样方式实现jmp vm_entry,所以有些vm插件会通过这种方式来定位到入口
68 xx xx xx xx e9 xx xx xx xx
之后,创建区段vmp0


谈谈vmp的还原(1)

谈谈vmp的还原(1)


set jmp_entry

谈谈vmp的还原(1)

谈谈vmp的还原(1)



之后写之前的push esi jmp vm_entry了

谈谈vmp的还原(1)

谈谈vmp的还原(1)


然后写完之后写vmp1区段,流程大概就这个样子,当然我跳过了构造esi以及对esi的修正



0x10 反汇编引擎
之所以会先谈谈这个,因为如果不看懂这个,后面的vm流程肯定看不懂
为了逆出这个反汇编引擎,我看了几遍opcode的构造方式以及一份开源的反汇编引擎(libudis86)。不过正因为如此,我才大概猜测出来一部分,vmp作者是如何构造这套vm的。

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)




这个函数大概3000+行
这下面通过这两条指令来看看是怎么反汇编的,当然需要一些基础知识。
1
2
817D FC 33020000   cmp dword ptr ss:[ebp-0x4],0x233//563
75 09                         jnz short zf.0040D7E2


读取opcode

谈谈vmp的还原(1)

谈谈vmp的还原(1)


然后通过switch跳转

谈谈vmp的还原(1)

谈谈vmp的还原(1)


先判断类型

谈谈vmp的还原(1)

谈谈vmp的还原(1)


注意到*(a2-10)其实是对应的这个东西

谈谈vmp的还原(1)

谈谈vmp的还原(1)



再上个图就明白为什么是 (xx & 2 ) == 2了

谈谈vmp的还原(1)

谈谈vmp的还原(1)



然后读modrm 0x7D进行查找mnemonic

谈谈vmp的还原(1)

谈谈vmp的还原(1)



对应的mnemonic

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)




之后就是解析modrm了挺精妙的,看图就好

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)






先对modrm.mod进行分析
判断是否行如[base+disp]
如果是   判断是否有address size override prefix
判断是否包含sib
读取disp
之后再读取immediate

谈谈vmp的还原(1)

谈谈vmp的还原(1)




创建下一个结构体,读取opcode 0x75

谈谈vmp的还原(1)

谈谈vmp的还原(1)



其他的没啥好说的看一看,_vmp_SetJccIndex

谈谈vmp的还原(1)

谈谈vmp的还原(1)



是不是感觉很有意思把hex & 0xf然后switch
可能这样不是很明白
那么我们先看看0x70~0x7f这些opcode是什么

谈谈vmp的还原(1)

谈谈vmp的还原(1)


那么对照一下就明白了
Vmp作者为了区分溢不溢出 低于不低于做了一个很有意思的事情
初始化了一个
0x11
然后把不溢出不低于的,也就是形如jnx 带n的这样做了
0x11|2

谈谈vmp的还原(1)

谈谈vmp的还原(1)


那么理解了之后就得到反汇编引擎的结构了

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)


对应内存中:

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)

谈谈vmp的还原(1)



0x11 结束语
写得有点仓促,也懒得整理了
下一贴主要是讲vmp是如何膨胀指令的


温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

    发表于 2020-10-14 15:22:39
    mark,是不是先得学习VT才看得懂.

    小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

    GMT+8, 2024-4-27 03:22 , Processed in 0.094208 second(s), 43 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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