能力值:
( LV2,RANK:10 )
|
-
-
2 楼
mark一下下,谢谢分享
|
能力值:
( LV3,RANK:20 )
|
-
-
3 楼
mark
|
能力值:
( LV5,RANK:60 )
|
-
-
4 楼
不错,学习,以前研究过,很想继续学习,可是时间太少了。有个问题,是不是handler里面加了混淆,就分析不出来了?我加的壳,跟到push jmp,跳到handler,发现好像混淆了。不知道当时是不是操作步骤弄错了。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
markyixia
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
楼下 可以简单介绍 加VM 和 解VM 的原理吗
|
能力值:
( LV5,RANK:69 )
|
-
-
7 楼
MARK
一下
|
能力值:
( LV4,RANK:50 )
|
-
-
8 楼
关键是啥时机运行这个插件。插件的几个地址如何取得?
|
能力值:
( LV5,RANK:60 )
|
-
-
9 楼
看看这里
要正确使用这个插件,要求其实是蛮高的:对虚拟机的结构要有所了解!而且插件作者也假设使用者已经具备这些基础知识。 关于CISC,可读读softworm较早的两篇文章“Themida 1.9.1.x CISC VM简单分析”和“Themida v1.8.0.0 Demo虚拟机分析”,很经典的。 而对RISC,可看一下Deathway的“Oreans RISC machine documentation”。 现在Oreans新的VM还没有见到谁有过公开的分析发布。关于TIGER VM,我曾写过一个非常初浅的说明,在这里;Deathway曾明确表示,他的插件暂时不会支持TIGER。
进入TIGER VM时有如下特征: 代码:
016058F6 68 A4FD5F00 PUSH 5FFDA4 ; pPCODE(RVA) 016058FB 68 97040000 PUSH 497 ; dwFirstHandlerNum 01605900 E9 0692EDFF JMP 014DEB0B ; VM_ENTRY
不细说它了,反正插件也没法用。
下面只说CISC和RISC,比如以下代码: 代码:
00408BEF E9 A7E84F00 JMP 0090749B ; to VM Section
0090749B 68 747A4674 PUSH 0x74467A74 ; Key 009074A0 E9 C6EBFEFF JMP 008F606B ; VM_Entry
这里,要特别注意代码的地址所处的区段:00408BEF位于户代码段(Base: 00401000, Size: 001C7000);而0090749B位于目标的倒数第三个区段(Base: 005D3000, Size: 00485000),即要进VM了。 这个例子是RISC的,它是准备调用一个Winlicense SDK函数,当然这个SDK函数肯定是VM了的。另一种情况是用户代码有被保护的片段时,也是同样的跳转。被保护的系统API不属于此讨论范围。
不是随便在任何一个“JMP 目标地址”都可以使用插件的Unvirtualize命令的!比如,在地址009074A0处Unvirtualize,一定会报"machine signature not found";在地址00408BEF处就能成功Unvirtualizing。 从代码的特征,我们可以得到以下结论:使用Unvirtualize命令那个JMP的目标地址一定是"PUSH KEY/JMP VM_Entry"指令序列,否则命令失败! 插件就是这样设计的,是它找VM入口(VM_Entry)的必要条件。
所以,"Find Referrences"命令在户代码段使用比较有意义!需要识别出JMP的目标地址是指向倒数第三个区段(VM区段)的才有效。 而如果在VM区段使用这个命令,就毫无意义了。原因在于,任何一个采用VM技术的产品,代码的乱序和膨胀是非常重要的一环,否则研究的人可以容易地,从而很快地搞懂你的VM结构。命令会找到无数多个用于乱序的JMPs。
这是最容易识别的,即你通常会看到一大片连续的PUSH/JMP序列。 还有一种隐蔽的情况,通常出现在Oreans的壳自身代码部分,到达OEP或Near OEP之前。即Oreans的某个功能模块结束,下一个模块的代码已经SMC完成,转向新的模块地址时,我称之为“转场”。 用户代码中,有关键代码被保护时,也可能出现这种情况。比如下面代码位于VM所在区段: 代码:
0084FC64 83EC 04 SUB ESP, 0x4 0084FC67 891424 MOV DWORD PTR [ESP], EDX 0084FC6A 89E2 MOV EDX, ESP 0084FC6C 81C2 04000000 ADD EDX, 0x4 0084FC72 83EA 04 SUB EDX, 0x4 0084FC75 871424 XCHG DWORD PTR [ESP], EDX 0084FC78 5C POP ESP 0084FC79 57 PUSH EDI 0084FC7A 893424 MOV DWORD PTR [ESP], ESI 0084FC7D 68 435C0000 PUSH 0x5C43 0084FC82 891C24 MOV DWORD PTR [ESP], EBX 0084FC85 53 PUSH EBX 0084FC86 68 6415E81D PUSH 0x1DE81564 0084FC8B 5B POP EBX 0084FC8C C1EB 04 SHR EBX, 0x4 0084FC8F 81C3 A406736D ADD EBX, 0x6D7306A4 0084FC95 53 PUSH EBX 0084FC96 812C24 35361274 SUB DWORD PTR [ESP], 0x74123635 0084FC9D 5E POP ESI 0084FC9E 81C6 35361274 ADD ESI, 0x74123635 0084FCA4 5B POP EBX 0084FCA5 68 75080000 PUSH 0x875 0084FCAA 892424 MOV DWORD PTR [ESP], ESP 0084FCAD 810424 04000000 ADD DWORD PTR [ESP], 0x4 0084FCB4 5B POP EBX 0084FCB5 56 PUSH ESI 0084FCB6 8F43 08 POP DWORD PTR [EBX+0x8] 0084FCB9 8B1C24 MOV EBX, DWORD PTR [ESP] 0084FCBC 50 PUSH EAX 0084FCBD 89E0 MOV EAX, ESP 0084FCBF 05 04000000 ADD EAX, 0x4 0084FCC4 05 04000000 ADD EAX, 0x4 0084FCC9 870424 XCHG DWORD PTR [ESP], EAX 0084FCCC 5C POP ESP 0084FCCD 8B3424 MOV ESI, DWORD PTR [ESP] 0084FCD0 52 PUSH EDX 0084FCD1 89E2 MOV EDX, ESP 0084FCD3 81C2 04000000 ADD EDX, 0x4 0084FCD9 83C2 04 ADD EDX, 0x4 0084FCDC 871424 XCHG DWORD PTR [ESP], EDX 0084FCDF 5C POP ESP 0084FCE0 E9 D182FFFF JMP 00847FB6 ; VM_Entry Stack: 0012FF30 6F5187FA ; Key
某个JMP指令,或RET指令到本段代码的入口:0084FC64。到0084FCE0之前的代码属于膨胀变形,实际就一条指令"PUSH 6F5187FA"。 这时,显然Unvirtualize命令没法用。这里怎么让这个命令可用,留给大家去思考——很简单的!
简单说下VM_Entry的特征: 代码:
; RISC时 00847FB6 6A 00 PUSH 0x0 ; VM_ENTRY ... 00847FD6 9C PUSHFD ... 00847FF4 60 PUSHAD ... 013C6476 61 POPAD 013C6477 9D POPFD 013C6478 C3 RETN ; VM_EXIT
; CISC时 0041F7FC 9C PUSHFD ; VM_1_ENTRY ... 00420593 61 POPAD 00420594 E9 6BA20000 JMP 0042A804 ... 0042A804 9D POPFD 0042A805 ^ E9 969EFFFF JMP 004246A0 ... 004246A0 C3 RETN ; VM_1_EXIT
你会注意到,RISC一定以"PUSH 0"指令开始,接下来一定有个"PUSHFD";而CISC一定是直接从"PUSHFD"开始。 然后是"PUSHAD",但可能转变成好多条指令来完成,"PUSHAD"就消失了。 VM出口一定是"POPAD/POPFD/RETN",中间可能会有少量膨胀。 CISC的出口地址仅一个,而RISC可能有好几个。VM的出口可以通过VM的Busy寄存器清零来定位,Busy用于防止多线程时的重入(Thread-safe)。 这些东西看起来比较困难,其间夹杂着大量垃圾代码,参考插件生成的Risc_ZeroData.txt文件,比较清爽。
RISC和CISC相比,还有两点不同:1) 有Stack切换。2) VM_Context和RISC VM代码不在目标区段的内存段,所以在Dump一个TMD/WL RISC VM目标时需要补区段。 RISC的特征代码: A. add esp,1ffc 栈切换后指向栈顶,栈的地址空间也位于另一个单独的内存段。 B. jmp dword ptr [edi+XXX] 到VM_Context段代码。 C. jmp dword ptr [esi] 到RISC VM段。 印象中LCF-AT的脚本是用这些特征来区分CISC和RISC的。
最后,重要的区别在于Key。 有个32位常数,它是目标被保护时随机生成的,在一个已被保护的目标中是固定的,又不同于其它目标。softworm称其为DeltaOffset,Deathway叫做Align。 在Oreans很常见的寻址方式"DWORD PTR [EBP+0xXXXXXXXX]"中,很容易在EBP找到这个值,如果对VM结构不熟悉的话。 在CISC中,PCODE的地址计算:pPCODE = Key + DeltaOffset(Align)。 而在RISC中,Key为一个索引值,用它查表得到的值,加上DeltaOffset(Align)才得到pPCODE。 VM Handlers的入口地址,也是这样定位的。非常类似PE导入表(Import)的IAT,所以Deathway也把它称为CISC_Iat或RISC_Iat。
可见,Oreans的RISC实现远比CISC来得复杂。这也导致插件在处理RISC VM时,可能出现错误。 后来我发现是插件在处理"Zero area"的代码时,有些垃圾指令无法正确识别、过滤造成的。曾跟Deathway沟通过,那时他状态不好、很郁闷。现在的v1.8有改进,偶尔还是有问题。
我以前在论坛有两篇文章,也大致讲过插件怎么用,感兴趣的可找找看。
|
能力值:
( LV12,RANK:310 )
|
-
-
10 楼
好久没来逛逛了,mark一下
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
谢谢分享
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
用Oreans UnVirtualizer插件还原VM代码,学习了
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
你说的插件问题是这个吗
http://www.jphf.net/undel/
00439C82 jmp 009E8515 vm bug
009DBAAA MOV EAX,DWORD PTR [EAX+0x4]
009DBAEB PUSH ECX
009DBB05 0007(00000005)
009DBB07 0001
009DBB0B 0009
009DBB1B PUSH 0x2
009DBB20 015F
009DBB21 0001
009DBB27 0153(00000007)
009DBB31 0009
009DBB37 PUSH 0x48
009DBB46 0006
009DBB47 0001
009DBB48 0009
009DBB4E PUSH 0x4
009DBB5A 0006
009DBB5B 0001
009DBB5C 0018
009DBB67 INC EDX
009DBBE0 TEST EAX,EAX
009DBC24 JNZ 0xfffffe03 @Label_009DBC39
009DBC43 MOV EDI,EDX
009DBC74 XOR ECX,ECX
009DBCC6 XOR EAX,EAX
009DBD5A CMP EDI,ECX
009DBD8D MOV DWORD PTR [ESP+0x10],EDI
009DBE52 JBE 0x2e4
009DBE58 NOP @Label_009DBE5F
009DBE69 PUSH DWORD PTR [ESP+EAX*4+0x48]
009DBF00 PUSH ESI
009DBF07 003D
009DBF23 001C(00000007)
009DBF2E 0007(00000003)
009DBF30 0001
009DBF3B 0009
009DBF41 PUSH 0x2
009DBF46 015F
009DBF47 0001
009DBF4D 0153(00000007)
009DBF4F 0009
009DBF5D PUSH 0x48
009DBF62 0006
009DBF63 0001
009DBF71 0009
009DBF72 PUSH 0x4
009DBF77 0006
009DBF78 0001
009DBF86 0018
009DBF87 LEA EDX,DWORD PTR [EAX+0x85]
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
期待高人指点下怎么修复这个插件
|
能力值:
( LV13,RANK:400 )
|
-
-
14 楼
00634B34 MOV CL,BYTE PTR [EAX]
00634B83 ADD EAX,0x1
00634BD1 TEST CL,CL
00634C32 JNZ 0xfffffef6
00634C41 SUB EAX,EDX
00634C7A 0002(00000048)
00634C7C 014E
00634C89 0153(00000006)
00634C92 0009
00634C93 PUSH 0x5e0
00634CB8 0006
00634CB9 0001
00634CBF 0009
00634CC0 PUSH 0x2
00634CEC 0006
00634CED 0001
00634CEE 0016
00634CF6 LEA EAX,DWORD PTR [ESP+0x5e0]
00634D6D LEA EDX,DWORD PTR [EAX+0x1]
00634DA0 LEA ECX,DWORD PTR [ECX]
//出现这种情况据说是插件bug 请问如何修正
|
能力值:
( LV1,RANK:0 )
|
-
-
15 楼
请问有没有可能加密c代码,或者c编译完的obj文件,防止逆向呢?
|
能力值:
( LV3,RANK:35 )
|
-
-
16 楼
.
最后于 2022-12-29 11:13
被轻快笑着行编辑
,原因:
|
|
|