-
-
vmp是如何修复api的
-
发表于:
2020-7-2 19:12
17739
-
1.vmp 在执行完形如以下指令时 完成了对api的解密以及调用
2.先说 imm1 因为 reg+imm1 位于 vmp0 区段之中
eg:
vmp0的区段 base 以及 size 分别为
00007FFDAFA54840 为 jmp qword ptr ds:[<&GetModuleFileNameW>]
此时 kernel32.dll 的 base 为
设想以下情况:
假如电脑关机后重启 重新打开 而此时kernel32.dll 的 base 变成了
那此时 [00000001400F1360] 应该填上多少比较合适呢
至此就修复了该api的调用
所以我们是不是就可以这样了
弄点代码 跑在原本oep之前 根据记录到的dllname,dllbase,dllsize以及api的name
然后在对vmp0进行暴搜
进行修复就可以了
回到最开始 我们发现还有个imm2 而这个立即数会导致
[reg+imm1]里面存放的数可能不属于[dllbase, dllbase + dllsize]
3.看看vmp是如何完成映射的
写入
先看看 映射空间 0x000007FEEAC2C999 怎么计算得到的
rax 来自于 mov rax,qword ptr ss:[rbp]
我们不难发现 这个偏移来自于vmp的bytecode里面
再看看 数据 0x0000000020A44E60 怎么计算得到的
先看 0xFFFFFFFFA90235F0
偏移也来自于vmp的bytecode里面
再看关键的 0x77A21870
首先 kernel32.dll 的 base为 0x77A10000
接下来 我们看看获得序号0x8F后做了哪些事情
获取到 rdi 之后
设置好 rsi 开始
在根据Export Names的不同序号(如:aCreatefilew)进行比较
得到想要的api的地址 只是这个api的name是写死在vm的字节码中
然后在写入 vmp0 或者像 LocalAlloc开辟的空间里
其实就是我们去获取api地址的那些常规逻辑
vmp类似去处理字符串的方式还是很多
比方说xjun师傅的插件绕过syscall的处理方式
就是因为vmp就是去读ntdll .rsrc里面的版本信息的
样本中 处理的api:
以上过程就是vmp在LocalAlloc之后
LoadLibrary dll修复完vmp0中各个api的地址的过程
LocalAlloc中的数据填写也类似 此外还有cpuid的运算
btw:
明白了 就能去处理这些东西了
思路会有一些 不同思路会处理起来不一样
一些思路上一些需要注意的点
1.
vmp1里面会调用到一些api,涉及到空间问题
2.
0xAAA: call 0xBBB
0xBBB: call 0xCCC // CCC去解密调用api
这种需要将 BBB 修复成 jmp
3.
反汇编引擎search 0xe8会得到两种 // 感谢大表哥(hzqst)提供的暴搜0xe8以及开源的unicorn_pe
一种为5字节的
一种为6字节的 即opcode中会包含前缀 // 前面如果会有 push reg opcode也会有前缀 即2字节
4.
根据堆栈情况
call/jmp
前移/补ret
还有的 等我遇到再补充
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课