首页
社区
课程
招聘
[原创]vmprotect某版本浅析
2019-4-23 14:40 24432

[原创]vmprotect某版本浅析

2019-4-23 14:40
24432
先说下仅仅是一部分,从零开始分析一个vmprotect虚拟机。

Step1:偶然入手一个vmprotect的样本,我这里版本是vmprotect3.0.8,拖入ida,查看区段

      

啥也没看出来,估计真正入口在text段吧,暂时不管他。

Step2:尝试直接去入口分析


一看这种代码就很坑,慢慢来吧

Step3:尝试用ida画图看下,乱七八糟的


Step4:这么乱的流程图不是我们想要的,所以我们可以尝试写个程序清理出一块代码,基本来说,区分块就是用jmp edi和ret来截断了指令。看起来也很乱


Step5:由于并不清楚这个虚拟机的结构,于是尝试清理代码,去掉一些无用的花指令,先给第一个块去花。过程如下:


前面两个jmp是无效的,nop之


这种衔接cmp,无用,nop之


Step6:没意义的cmp与test,nop之……总是这些规律不难,需要注意的是xchg指令需要花点心思。直接给大家看下清理花指令以后的吧。


开头部分是一堆的push,可能是保存寄存器环境,最后的mov esi,[esp+28h]应该是取出一个key,继续往下分析

Step7:中间对esi和eax做了一系列的变化,


其中esi来源于一个key,eax也来源于一个const,然后一直变化

Step8:最后ret回去,来源于edi,而edi来源于esi和eax


Step9:根据前面的信息,我们大概就理清了一点思路,首先一堆push保存寄存器;然后ebp=esp以后esp就随意变换了。。尽管他也没使用过esp,也就是说,这时候的ebp相当于esp,就是个堆栈指针;最后根据2个key变换esi和eax,eax和esi仅仅用来计算edi,edi用来计算ret的地址。

Sep10:

Ebp:堆栈指针

Esi:数据源

Eax:临时变量

Edi:ret专用返回(跳转)地址

Step11:根据上面的结果,我们只是得到了一个大概,还需要继续分析block2(实际上,所有的block已经获取到),才能分清楚他的机构,以便后期的继续自动化。

Step12:看block2,也就是第二个块,仍旧有很多花指令


Step13:继续尝试根据上面的规律去掉这些花指令,去掉以后如下:


很显然,第二个block也是符合上面的规律的

ebp作为一个指针a,esp+eax作为一个指针b,eax作为一个临时变量可以不用管,edi作为衔接作用也暂时不用管,esi作为一个指向const区域的指针也可以不用管,这些相当于虚拟机的内部,我们都可以屏蔽,我们要做的,就是搞清楚这个block哪些部分是重要的。

Step14:继续观察代码,发现真正有用的代码,只有下图(之所以说其他没用,因为其他代码里面的eax,esi寄存器,都是用来计算下一个代码块的,这些代码对于我们分析虚拟机没什么作用)


Step15:没错,真正有效代码,就是上面这四句,其实就是做了一个从ebp到[esp+eax]位置的变量转移,也可以说说一个 x86寄存器=》vmp虚拟机寄存器的mov

。然后根据之前的分析结果,ebp是堆栈的话,那么这里的ebp+4相当于一个vmp的pop指令,esi作为指令指针继续指向下一条const,这句代码,可以简称为一个

“vmp_push reg”,之所以是push,是因为ebp+4了,而这里变动的堆栈,则是vmp的esp(听起来很绕),同时看出来,他的指令是倒着走的,vmp的eip会减1 ,至于这个reg对应哪个寄存器,因为我们这里仅仅是纯静态,所以很难确定,但是这里可以暂时猜测这一块代码,仅仅是做了一个操作,那就是:把x86的寄存器放入到vmp的区域,如果以后写一个伪指令调试器,则可以直接模拟一个push即可,其他的esi寄存器、ebp寄存器,eax寄存器,忘掉他吧。或者,直接写伪调试器的时候,不去写这几句,因为他们仅仅是在初始化vmp的堆栈,给他们一个初始值。

Step16:对,你没看错,block1是保存了所有的x86寄存器,block2是开始初始化vmp的第一个寄存器,至于block3我们可以大胆猜测,是初始化vmp的第二个寄存器。而这些,如果在做还原的时候,其实是最好忽略掉的,因为来回的堆栈改变会影响我们的分析(这句现在说的很啰嗦,但是后面就知道,这句话会很重要)。

Step17:现在可以先停下来,重新梳理一下思路,已知他会先把所有寄存器保存下来,然后用新的ptr指针代替原操作,那么我们需要做的是,搞清楚他哪些ptr对应哪些寄存器,做了哪些操作。到这里,需要我们获取所有的block了,正好把他的反调试处理一下。

Step18:刚才说到了反调试。现在就按照严格的顺序,按部就班的说一下反调试怎么处理(不要打开任何反反调试插件,要么就自己写,我们要的是纯手工)
    IsDebuggerPresent下断点,这将使第一个反调试点,可以利用它回溯一下堆栈,会看到一句 call eax,这里将是vmprptect调用反调试函数的入口;
    CheckRemoteDebuggerPresent,这也也很好处理;返回值改1
    ZwQueryInformationProcess,这时的[esp+4]是0x1e,处理的方法是,把返回值eax改成0xC0000353,把[esp+8]的buffer改成0;
    NtSetInformationThread 这个需要改他的传递参数,0x11改成别的;
    NtQuerySystemInformation 调用号为0x23,这里需要改他的返回OUT参数为0;
    NtQuerySystemInformation 调用号为0x0b,这里他会遍历系统模块,一些sys和dll等,这个处理。我么不能直接全部清0,需要和没调试状态的对比一份修改    ,可能有人说直接清零缓冲区就可以。但是在我的系统里面,这样依然会被检测到,也可能是我姿势不对吧,继续
Step19:好了,关于反调试本身现在暂时到此为止,我们要做的,并不满足于如何过掉他,而是看他如何检测和调用的,如果想要过掉他直接用个插件就可以了。回到正题,先以第一个IsDebuggerPresent为例;我们看看他是怎么调用过来的,这对于理解vmp虚拟机,是有好处的。那么根据之前总结的结果,我们知道,代码都是一块一块的,由0xc3和0xffe7截断,也就是一些ret和jmp edi,我们现在,可以获取目前为止的所有block了,先说下结果,经过ida trace,从入口到IsDebuggerPresent,一共调用了1022个block,我们要做的,就是把这1022个block,尽可能的读懂。好了,现在可以开始尝试读混淆过的虚拟机代码了。

Step20:这里可能会有人问如何获取这么多block,其实办法很多,run trace可以,但是最好还是静态解析,然后下断,再f9,这样中途可以截获一些指令,而且效率也比较高一些。好了,现在先贴一下这1022个block的块头
block adress 008628aa
block adress 00653dc2
block adress 00663169
block adress 0065be22
。。。。。。以下略
Step21:由于代码当中,有很多混淆,用肉眼识别,是很不现实的,所以这里需要我们清除一下这些混淆,清除的方法也很简单,利用寄存器的读写特性,假设所有opcode只有,一个字节寄存器eax在0x00000001和0x00000003被修改了,但是0x00000002没有被使用过,那么就可以判定,0x00000001是无效的混淆指令。
例如下图
0x00000001 mov eax,1
0x00000002 mov ebx,2
0x00000003 mov eax,3
那么第一句mov eax,1就是无效的。这里我们可以自动化来完成。先看个demo

lea ecx, [edx + esi + 8]
Registers read:  代表使用的寄存器,记为输入进村器
edx
esi
Registers modified:代表改变的寄存器,记为输出寄存器
ecx
add eax, ebx
Registers read:  输入寄存器
eax
ebx
Registers modified:输出寄存器
eflags
eax
上图的代码识别,就是用我们的引擎做的,可以自动化识别出一条指令的细节。要写这么个引擎,需要用到反汇编引擎。
Step22:前文说道,既然要利用寄存器读写进行去混淆,那么我们首选eflags寄存器。用它可以去掉一些jcc指令和test、cmp指令以及cmc、stc指令
Step23:去混淆的过程可能比较枯燥。暂时跳过,以后会改。现在给大家看看去过混淆以后的handle,分析一下虚拟机结构,这是很爽的一个部分(提前给个惊喜,以后可以跳过混淆了,我们眼里只有handle);下面请看一个handle(去混淆版):
handle->vmp_pop_context  

reference:这句指令相当于一个pop context指令,导致vmp堆栈变动,x86堆栈不变,简写为 vmp_pop_context

//取出opcode,对ebx寄存器做一系列的解密
lea 	 esi, [esi - 1]
adc 	 cl, 3
movzx 	 eax, byte ptr [esi]
xor 	 al, bl
adc 	 ch, al
neg 	 al
not 	 al
neg 	 al
inc 	 al
not 	 al
xor 	 bl, al
//vmp的堆栈向下移动,导致vmp_esp=vmp_esp+4
mov 	 ecx, dword ptr [ebp]
add 	 ebp, 4
//将上值放入vmp的context当中,由于vmp的context在堆栈里面,所以用[esp+eax]表示
mov 	 dword ptr [esp + eax], ecx
//取出opcode继续做解密,这决定着edi、ebx寄存器
lea 	 esi, [esi - 4]
mov 	 eax, dword ptr [esi]	 
xor 	 eax, ebx
sub 	 eax, 0x271051b0
neg 	 eax
dec 	 eax
bswap 	 eax 	 
not 	 eax
lea 	 eax, [eax - 0x5eaa3b85]	 
neg 	 eax	 
ror 	 eax, 2
inc 	 eax
xor 	 ebx, eax
add 	 edi, eax
jmp 	 edi
如果上面这个不够看,再看一个,其实他两的功能是一样的
handle->vmp_pop_context

reference:这句指令相当于一个pop context指令,导致vmp堆栈变动,x86堆栈不变,简写为 vmp_pop_context

//opcode向左移动1字节
lea 	 esi, [esi - 1]
movzx 	 eax, byte ptr [esi]

//根据取得的opcode,解密ebx寄存器
xor 	 al, bl
rcl 	 ch, cl
neg 	 al
sbb 	 cl, 0xeb
btr 	 ecx, 0x76
cmovno 	 ecx, eax
not 	 al
and 	 ecx, edx
rol 	 cl, 0xc5
neg 	 al
movsx 	 cx, cl
inc 	 cx
inc 	 al
rcl 	 cx, cl
shl 	 ch, 0x55
neg 	 cx
not 	 al
shl 	 ch, cl
sub 	 cl, dl
xor 	 bl, al
//这里会改变vmp的堆栈,增加4个字节,相当于一个pop指令
mov 	 ecx, dword ptr [ebp] 
lea 	 ebp, [ebp + 4]
//将vmp堆栈的值,pop以后放入context当中,并opcode继续移动,相当于x86的eip+1,只不过这个是倒着走的
mov 	 dword ptr [esp + eax], ecx
sub 	 esi, 4
//取出opcode,用来计算edi,ebx,其中ebx用来计算key,edi用来做ret和jmp衔接
mov 	 eax, dword ptr [esi]
xor 	 eax, ebx
lea 	 eax, [eax - 0x271051b0]
neg 	 eax
dec 	 eax
bswap 	 eax
not 	 eax
sub 	 eax, 0x5eaa3b85	 
neg 	 eax
ror 	 eax, 2
inc 	 eax
xor 	 ebx, eax
add 	 edi, eax
jmp 	 edi
看到了吧。其实,他两的功能是一样的,都是一个vmp_pop_context,也就是说,即使是同一样的功能,也可能会用不同的汇编来表现他。这就是一项代码变形技术。这个手段,组织了我们对handle进行特征码识别,是个小技巧。
继续再看一个有意思的handle,传说中的vmp堆栈调整在这里面,其实很简单。
handle->vmp_push_context

reference:这指令的目的是将context的内容放入vmp的堆栈,会改变vmp的堆栈指针,类似于x86的push,这里可以是 push vmp_reg

//移动opcode,解密ebx
sub 	 esi, 1
movzx 	 eax, byte ptr [esi]
xor 	 al, bl	 
neg 	 al
not 	 al
neg 	 al
inc 	 al	 
not 	 al
xor 	 bl, al
//从context取得数据
mov 	 eax, dword ptr [esp + eax]
//将context取得的数据,放入vmp堆栈,并且堆栈指针-4,相当于一句push
sub 	 ebp, 4
mov 	 dword ptr [ebp], eax
//移动opcode四个字节,用于计算edi,也就是衔接地址
lea 	 esi, [esi - 4]
mov 	 eax, dword ptr [esi]	 
xor 	 eax, ebx
lea 	 eax, [eax - 0x271051b0]
neg 	 eax
dec 	 eax
bswap 	 eax
not 	 eax	 
lea 	 eax, [eax - 0x5eaa3b85]
neg 	 eax
ror 	 eax, 2
inc 	 eax
xor 	 ebx, eax
add 	 edi, eax
//这里的比较,其实是比较vmp的当前堆栈和[esp+60]的大小,也就是说。现在vmp的堆栈。占用了x86堆栈的60个字节,这里看看我们的push和pop有没有使得堆栈重合,否则需要调整堆栈	 
lea 	 eax, [esp + 0x60]
cmp 	 ebp, eax
ja 	 0x3f992a
//这里进行了一次调整堆栈操作,将esp移动到了ebp-0x80的位置,也就是说门上面是ebp,下面是esp,中间的0x80个字节用于预留给vmp使用
mov 	 edx, esp
mov 	 ecx, 0x40
lea 	 eax, [ebp - 0x80]
and 	 al, 0xfc	//堆栈字节对齐
sub 	 eax, ecx
mov 	 esp, eax
//调整堆栈以后,我们需要将x86堆栈的一些内容,再次拷贝到vmp的堆栈当中去,这是因为上一步我们如果仅仅改变了x86堆栈。但是堆栈内容不完全一致,容易使数据错位
push 	 edi
pushfd 	 
push 	 esi
mov 	 esi, edx
mov 	 edi, eax
cld 	 
rep movsb 	 byte ptr es:[edi], byte ptr [esi]
pop 	 esi
popfd 	 
pop 	 edi
jmp 	 edi
Step24。好了,暂时不需要纠结于浩如烟海的汇编代码。我们只需要大概的看一下,规整以后的形式

有关这些伪代码的形式,大家可以参考一下相关文章,关键词“vmp handle”。现在我们有了思路了。其实vmprotect的保护,是把原先的代码,等价换成了这种形式,也就是一条一条的handle。其实他并没有那么可怕。
如果为了脱壳和过反调试,可以从 vmp_call和vmp_ret这两类handle入手,下断,然后就可以找到他的函数调用序列;如果是为了破解,需要对 vmp_push_const这类handle入手,修改常量。如果想要过一些代码校验或者内存校验,可以下硬断,即可找到handle,patch这条handle即可。
Step25:==================================================================================================================
好了。打住,打住打住。我们现在对这个壳的大概结构有了了解了,已知他的逻辑代码换了形式,其实本质上还是会对系统调用(api)进行调用,那我们就没有什么好怕的了。当然前面这部分分析,并不是没有用,他会奠定我们分析vmp的基石。只不过,我们目前为止,仅仅是寻找一个切入点,从没头苍蝇,到找到第一个系统调用IsDebuggerPresent,这已经是一个很大的进步了,接下来我们开始尝试用一些技巧。到现在,应该对vmprotect没有什么害怕了。
=========================================================================================================================
Step26:重新观察,发现text区段没有内容,这明显是被加密了。在运行之后会解密,而且我们重新看一下Step1的部分,text区段没有可写属性,那么如果想要对他读写,则必须调用VirtualProtect函数,将text区段设置成可写,然后将原本代码写入text区段。这也就是为什么很多教程用bp VirtualProtect找oep的原因。其实是因为text段不可写的缘故,所以才要调用这个函数写回原始字节码。
Step27:在step18的时候,说到我们经过call eax调用api,那么我们顺藤摸瓜,对他下断点,尝试看看系统发生了什么。这里使用x32dbg+sharpod(其实不用他也行,这里是为了方便,不然每次都得手动过反调试)。观察外壳程序的api调用。在我的程序里面。call eax的地址是0x65d22c,我们在这里先下硬断。下面贴一下,程序的流程,这里一目了然的就看清楚了vmp的外壳部分做了什么

很一目了然吧。外壳所有的api,就是这些。其实到这里。我们就可以明白为什么,非要对VirtualProtect下断点了。因为最后一个系统api,是VirtualProtect。到这里,vmp3.0.8的所有保护。就一目了然了。我们只需要在最后一个VirtualProtect的地方下断,就接近了oep。
Step28:找oep,这里提供一个简便办法,当然这部分我会补充,之所以先讲一个取巧办法,是为了讲一下iat,后面帖子部分会大改。其实还有更权威的办法,不是这种投机取巧的,而且我也不会使用这种办法的。好了。讲下简便办法。在最后一次VirtualProtect以后,去掉那些忽略异常什么的,对vmp0区段下访问断点,f9,对text断下访问断点,f9,他的附近就是oep了(以后不会讲这种投机办法,这部分会删除)。长这个样子:

不太懂oep特征。但是看样子是个winmain函数。(其实是mfc的)。=============打住,oep部分其实这部分会删除,因为太取巧了。这里仅仅是过渡一下。以后会改成讲解怎么正面刚vm找oep。
Step29:接下来处理iat,他的iat,我这里识别出938个需要修补的地方。基本来说。他是这种形式:
text:00400000   call vmp0.00500000
text:00400005   ret    (这个字节执行时候会被跳过,但是这里可以阻断ida分析)
vmp0.00500000 nop
vmp0.00500001 jmp 解密函数
vmp0.解密函数 ...xchg [esp],随机reg
其实大表哥(hzqst)那个图就正好。我不发了。
这里,需要修复iat的话,要完全重建一张表,找到那938个需要修补的地方。然而这里面有个坑要注意一下。他会shadow一部分api的字节。具体来说,是这样子

push ebp
mov ebp,esp
pop ebp
call TlsSetValue+0x05
其中他会自己shadow了前面三句代码,这样一定程度上防止了断首下断,可以防止detours的hook,这也就是为什么一些高手们断尾下断的原因。个人吐槽一下。这已经超出一个壳应该保护的范围了,他是保护pe,不该保护到这种地步。修复的话。我的脚本可以识别640个,还有300个不能自动识别(手动识别是可以,但是这不是我们的初衷),所以不讲怎么修复

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

最后于 2019-5-9 21:21 被白菜大哥编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (18)
雪    币: 2050
活跃值: (2805)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
xiaohang 3 2019-4-24 14:18
2
0
没有章法,建议你从pe结构开始学起,理解一下系统是如何加载镜像,启动进程的,有些混淆你去认真看你就输了
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-4-29 16:48
3
0
xiaohang 没有章法,建议你从pe结构开始学起,理解一下系统是如何加载镜像,启动进程的,有些混淆你去认真看你就输了
谢谢指点,这部分后面会有的。之所以搞混淆和vm,主要是不喜欢那种一个bp VirtualProtect然后怎么怎么就脱壳的教程。想用自己的方式,把其中的原理阐述清楚。让大家在看到有些高手,几个bp就脱壳之后,了解原理,而不是导致有些人不求甚解的一个“esp定律”就脱。
雪    币: 7
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lijunlin 2019-4-29 17:57
4
2
不知道你的逆向水平如何(不知道是否有点班门弄斧了),也不知道我说得对错(欢迎指正)。
反正呢,我的理解来说,不管什么加壳,都不能脱离PE结构,如果你有想法,好好的学好逆向,建议好好的学习一下PE结构,再好好学一下编程。
网上有一份内存加载DLL的代码,值得你好好的研究一下。
一般人所使用的编程等级,基本上都不高,所以不管用什么加壳,最终都是对系统API的调用,他自己实现的API,目前这些强壳估计他也处理不了得。
另外,了解一下什么叫做堆栈平衡、回溯什么的。总结下来,基本上就是一下一些手法。
1、对PE头乱搞,让你的调试器检测玩玩,不过呢,最终还是得遵守PE文件规则,所以很好处理得。
2、对区段乱搞,对其中的结构进行加密、破坏处理等等,但是呢,最终都得还原,所以,bp VirtualProtect 就是那最后设置执行属性的一步。不然这个程序执行就会挂。
3、对输入输出表乱搞,其目的嘛,自然就是破坏原有的对系统调用过程,所以网上有些脱壳才会有补区段这种说法。最终结果还得遵守堆栈平衡原理。所以两头一卡,就露馅了。
4、其他的一些乱搞,什么文件校验、内存校验、反调试啊、双进程保护啊、等等,都是基于系统基本规则得,所以嘛,处理起来也会很简单。无非就是分析对方的手法然后对抗而已。

另外,说说破解,能够到这一步,前面的分析工作应该是处理得差不多了。也就知道该怎么修改代码了。
然后就可以了解一下什么异常处理啊、断点原理之类的,反正都是这么些东西。至于修改这些,无非就是那几个简单的函数调用,太简单了,我就不多说了。
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-4-29 18:20
5
1
lijunlin 不知道你的逆向水平如何(不知道是否有点班门弄斧了),也不知道我说得对错(欢迎指正)。 反正呢,我的理解来说,不管什么加壳,都不能脱离PE结构,如果你有想法,好好的学好逆向,建议好好的学习一下PE结构 ...
谢谢,受益匪浅。如果是为了脱壳,确实是应该更注重系统调用和pe规范。退一万步讲,他所有的api都sysenter了,也还是可以ssdt hook搞。再不行挂个windbg或者softice,也能下断了。本文目的,仅仅是提供一个最笨的办法,高手可能很多不屑于看,但是如果新手认真看完,实验完(最后提供demo),那么vmprotect和upx,他都不会害怕,能可以按照自己的思路脱壳。
雪    币: 7
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lijunlin 2019-4-30 20:50
6
0
白菜大哥 谢谢,受益匪浅。如果是为了脱壳,确实是应该更注重系统调用和pe规范。退一万步讲,他所有的api都sysenter了,也还是可以ssdt hook搞。再不行挂个windbg或者softice,也能下断了 ...
很赞成你的说法,网上现有的很多方法、都显得零散,建议可以做一套教程出来,从零突破VMP,然后让大家都可以学习,让技术传承下去。
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-5-1 00:02
7
0
lijunlin 很赞成你的说法,网上现有的很多方法、都显得零散,建议可以做一套教程出来,从零突破VMP,然后让大家都可以学习,让技术传承下去。
限于个人水平不足。并没有按照传统方式,先把pe讲一遍,再几个bp 断点。而是按照自己遇到一个壳子的过程,一点一点的来。pe结构什么的,用到的时候会提及。
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-5-7 17:36
8
0
xiaohang 没有章法,建议你从pe结构开始学起,理解一下系统是如何加载镜像,启动进程的,有些混淆你去认真看你就输了
你好,你看这样符合吗。这是正面刚vmp,从一开始啥也不懂,连vmp调用啥api也不懂。逐步分析 过反调试,最后贴了所有vmp308的api序列,最终用最直接的方式解释了,为什么脱壳vmp一定是对VirtualProtect下断而不是别的函数。当然还会更新,包括之后如何找oep修复iat
雪    币: 2050
活跃值: (2805)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
xiaohang 3 2019-5-8 15:29
9
0
并不是说你不能在别的函数下断,像三楼的所说的,任何事情都是有它的内在规律和规则的,别人在VirtualProtect下断,他们为什么要这么做?
理解规则能少走弯路,不然我怕你的热情没多久就会被失败磨灭了
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-5-8 15:59
10
1
xiaohang 并不是说你不能在别的函数下断,像三楼的所说的,任何事情都是有它的内在规律和规则的,别人在VirtualProtect下断,他们为什么要这么做? 理解规则能少走弯路,不然我怕你的热情没多久就会被失败磨 ...
没有磨灭。现在找oep搞定了,没写上来,iat修复不难,正在写脚本。快结贴了
雪    币: 2050
活跃值: (2805)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
xiaohang 3 2019-5-9 10:09
11
0
没有就好,期待你的帖子
雪    币: 47
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
frdGo 2019-5-9 10:43
12
0
这个帖子很好啊,  跟我几个月前硬刚vmp虚拟化的经历几乎完全一样了(我之前也是没有仔细分析过任何壳的)
我觉得没有搞过vmp虚拟化的同学照着这个流程走, 最后都能实现还原opcode的

不过就算还原了vcode, 想要还原成源代码也还是非常难的
雪    币: 47
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
frdGo 2019-5-9 10:56
13
0
附上一个vmp3.0.x从启动开始的还原了vcode的runtrace
加密样本来源
上传的附件:
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-5-9 11:28
14
0
frdGo 这个帖子很好啊, 跟我几个月前硬刚vmp虚拟化的经历几乎完全一样了(我之前也是没有仔细分析过任何壳的) 我觉得没有搞过vmp虚拟化的同学照着这个流程走, 最后都能实现还原opcode的 不过 ...
现在我自己可以手动修复iat了,但是写程序太麻烦。半天写不完这个程序,很烦。。主要code能力太差。其实剩下的很简单了。所有需要修复的地方,以及修复的方法都很明确的,比如0x00400010改0x10为0x20,很精确的,所有位置和改法都有了。。就是我写程序,总是bug。全是些编译错误。很尴尬。。
最后于 2019-5-9 11:31 被白菜大哥编辑 ,原因:
雪    币: 12500
活跃值: (3043)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-5-9 11:29
15
0
frdGo 附上一个vmp3.0.x从启动开始的还原了vcode的runtrace加密样本来源[原创]追踪还原vmp3.0.9-VMProtectDecryptStringA
我没用run trace,这种会被他带入误区。我是动态中的静态分析。
雪    币: 13935
活跃值: (1215)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
严启真 2019-5-16 13:32
16
0
写得不错,回复的总结也不错…
雪    币: 781
活跃值: (1071)
能力值: ( LV5,RANK:78 )
在线值:
发帖
回帖
粉丝
bambooqj 2019-9-10 00:55
17
0
这么好的帖子我竟然现在才发现...罪过 马克一下.真的不错.分析的很透彻 深入浅出.适合我这种初学者.
雪    币: 1700
活跃值: (676)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
弱冠甕卿还仓 2019-9-11 21:20
18
0
老铁们你们说的是不是windows的,不是移动的把?
雪    币: 73
活跃值: (893)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hixhi 2020-4-1 17:01
19
0
领悟到不少,有感觉,谢谢楼主
游客
登录 | 注册 方可回帖
返回