首页
社区
课程
招聘
vmp2代码还原分享
2022-4-3 17:06 9560

vmp2代码还原分享

2022-4-3 17:06
9560


一般来说还原的话,要先能够像fkvmp这种插件先能从指令流中把虚拟机执行的流程弄出来,

弄出来之后分静态和动态两种方法,静态分析的缺点在于它本身就是堆栈机,堆栈这种本身就是一种动态的思想,静态无法获得堆栈信息,

但是他那个vJcc,也就是分支跳转,是在堆栈中各种运算出来的。如果是动态的话,也就是用unicorn或者triton什么玩意的仿真执行的引擎,

有可能执行的时候堆栈中的数和文件在真机下运行的堆栈情况不同,导致vJcc跳转目的地不对(这个我目前没找到问题在哪)。



```

vm-entry  到vm-exit的流程,这是第一步要获得的。

[vip 14000ace9]SREGQ

[vip 14000ace7]LCONSTDWSXQ

[vip 14000ace2]ADDQ

[vip 14000ace1]SREGQ

[vip 14000acdf]SREGQ

[vip 14000acdd]SREGQ

[vip 14000acdb]SREGQ

[vip 14000acd9]SREGQ

[vip 14000acd7]SREGQ

[vip 14000acd5]SREGQ

[vip 14000acd3]SREGQ

[vip 14000acd1]SREGQ

[vip 14000accf]SREGQ

[vip 14000accd]SREGQ

[vip 14000accb]SREGQ

[vip 14000acc9]SREGQ

[vip 14000acc7]SREGQ

[vip 14000acc5]SREGQ

[vip 14000acc3]SREGQ

[vip 14000acc1]SREGQ

[vip 14000acbf]SREGQ

[vip 14000acbd]SREGQ

[vip 14000acbb]SREGQ

[vip 14000acb9]SREGQ

[vip 14000acb7]LCONSTQ

[vip 14000acae]LREGQ

[vip 14000acac]ADDQ

[vip 14000acab]SREGQ

[vip 14000aca9]LCONSTQ

[vip 14000aca0]LREGQ

[vip 14000ac9e]ADDQ

[vip 14000ac9d]SREGQ

[vip 14000ac9b]LREGQ

[vip 14000ac99]LREGQ

[vip 14000ac97]LREGQ

[vip 14000ac95]LREGQ

[vip 14000ac93]LCONSTQ

[vip 14000ac8a]LREGQ

[vip 14000ac88]ADDQ

[vip 14000ac87]SREGQ

[vip 14000ac85]SREGQ

[vip 14000ac83]LREGDW

[vip 14000ac81]LREGDW

[vip 14000ac7f]LREGQ

[vip 14000ac7d]LCONSTQ

[vip 14000ac74]ADDQ

[vip 14000ac73]SREGQ

[vip 14000ac71]WRITEDW

[vip 14000ac70]SREGDW

[vip 14000ac6e]LCONSTBSXDW

[vip 14000ac6c]SREGDW

[vip 14000ac6a]LREGQ

[vip 14000ac68]LREGQ

[vip 14000ac66]LREGQ

[vip 14000ac64]LREGQ

[vip 14000ac62]LREGQ

[vip 14000ac60]LREGQ

[vip 14000ac5e]LREGQ

[vip 14000ac5c]LREGQ

[vip 14000ac5a]LREGQ

[vip 14000ac58]LREGQ

[vip 14000ac56]LREGQ

[vip 14000ac54]LREGQ

[vip 14000ac52]LREGQ

[vip 14000ac50]LREGQ

[vip 14000ac4e]LREGQ

vm-exit

```


其次为每个handler写lifter,lifter的作用就是生成同样作用的IR,我是用的llvm的ir,git上面有个东西叫vtil,他好像也能生成ir,还有能专门针对堆栈机的优化,最后代码还原的效果直接取决于优化的,但是他的项目没文档,c++新特性还用的多,代码看都看不懂。


比如下面这个lifter,

```

lifters addq

{

vm::handler::ADDQ,

[](_cvmp2& vmp2, std::variant<uint64_t, uint32_t, uint16_t, uint8_t> param1)

{

//mov     rax1, [rbp+0]

auto ptr1 = vmp2.builder.CreateIntToPtr(vmp2.stack,PointerType::getInt64PtrTy(vmp2.context));


auto dqValue1 = vmp2.builder.CreateLoad(Type::getInt64Ty(vmp2.context),ptr1);


//mov rax2,[rbp+8]


auto ptr2 = vmp2.builder.CreateIntToPtr(vmp2.builder.CreateAdd(vmp2.stack, vmp2.builder.getInt64(8)),         PointerType::getInt64PtrTy(vmp2.context));

auto dqValue2 = vmp2.builder.CreateLoad(Type::getInt64Ty(vmp2.context),ptr2);


//add rax2,rax1

auto sum = vmp2.builder.CreateAdd(dqValue2, dqValue1);


vmp2.builder.CreateStore(sum, ptr2);

vmp2.builder.CreateStore(vmp2.builder.getInt64(0), ptr1);


}

};

```

他的作用就是模仿vmp的堆栈机的流程。

```  

这个lifter 写的ir编译成x86是下面这样,熟悉vmp的一眼就能看出来就是add那个handler

mov     rcx,rsp

mov     rax, [rcx]

add     rax, [rcx+8]

mov     [rcx+8], rax

mov     qword ptr [rcx], 0(flags)   因为我是动态搞的,分支由模拟器决定,不需要flags,写0就行

mov     rsp,rcx


```


上图中rsp+xx是对应某个虚拟reg,不加优化编译出来还是堆栈机的流程,人还是看不懂,IDA也看不懂,下图是F5的,明显不行。




llvm具体优化有几个,都是干什么的,我不清楚,我把官网那个例子的优化加进去。


```

fpm->add(llvm::createDeadStoreEliminationPass());

fpm->add(llvm::createGVNPass());

fpm->add(llvm::createPromoteMemoryToRegisterPass());

fpm->add(llvm::createInstructionCombiningPass());

fpm->add(llvm::createReassociatePass());

fpm->add(llvm::createCFGSimplificationPass());

fpm->add(llvm::createCorrelatedValuePropagationPass());

fpm->run(*main);

```

有些优化会乱搞cfg,因为我要内联汇编,他会把汇编位置乱移,会有这个问题。



应该是某个优化会把vreg转化成真实x86的reg,具体怎么对应的我不知道。llvm优化的还不太好,人还是看不懂,F5还有IDA的优化,



上图是还原出来的,真实的未被虚拟的代码是下图。IDA能发现v3也就是eax是未知的,因为eax是由上面那个IsDebuggerPresent返回的,调用导入函数要先vm-exit,再vm-entry另一个指令流,我是直接从下一个指令流还原的,所以eax是未知的,所以这里由涉及到多个basic block的合并



而且顺序的代码很好还原,那种多重if的很容易出错,flags很难处理,basicblock也很难合并,这里开始我就没研究了,也木有这个水平了  

 

  

 附件是还原的,F5可以看看。







参考

https://back.engineering/17/05/2021/  by _xeroxz  最基础的识别handler的轮子我就是抄他的,有需要的话要扩展,他的也不全

VMProtect 学习 by OoWoodOne 

Samuel Chevet - SecurityDay2015 - Inside VMProtect 

VMProtect的逆向分析和静态还原 pdf    09软件峰会

VMProtect逆向分析 by oolff2

asia-18-Blazytko-Breaking-State-Of-The-Art-Binary-Code-Obfuscation-Via-Program-Synthesis-wp

https://slidesplayer.com/slide/14781905/

 https://github.com/aobfucated/vmp2-devirtualization 帖子中所有涉及代码基本都在这里






[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (1)
雪    币: 3671
活跃值: (3848)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caolinkai 2022-8-19 16:56
2
0
感谢分享
游客
登录 | 注册 方可回帖
返回