在http://bbs.pediy.com/showthread.php?s=&threadid=40770
中我用VMProtect把UPX转入口点的一小段加密了, 然后会发现用正常的方式很难停在入口点.
加密前:
010143D4 58 pop eax
010143D5 50 push eax
010143D6 54 push esp
010143D7 50 push eax
010143D8 53 push ebx
010143D9 57 push edi
010143DA FFD5 call ebp
010143DC 58 pop eax
010143DD 61 popad
010143DE 8D442480 lea eax, [esp-80]
010143E2 6A00 push 00
010143E4 39C4 cmp esp, eax
010143E6 75FA jnz 010143E2
010143E8 83EC80 sub esp, -80
010143EB E9B52FFFFF jmp 010073A5 ; UPX经典的Jmp, 入口地方一直往下拉就可以来到这里.
加密后, 代码变成这样了:
010143D4 68 E5E45EBC push BC5EE4E5
010143D9 - E9 81990000 jmp 0101DD5F
010143DE 80E0 3C and al, 3C
010143E1 8F0407 pop dword ptr [edi+eax]
010143E4 - E9 8D920000 jmp 0101D676
010143E9 5C pop esp
010143EA - E9 87920000 jmp 0101D676
010143EF 54 push esp
我们发现可爱的Jmp不见了, 对于我们这些菜鸟来说, 面对上万的循环着实无能为力. 但是我们可以对其进行RUN跟踪, 总结一些规律.
在已知Notepad的入口点为010073A5的情况下, 我们设置跟踪条件为EIP位于范围内 :010073A4-010073A6
然后跟踪步入.运行一段时间以后, 程序顺利停
在入口点. 察看RUN记录发现在此之间程序运行了1.6W条指令(曾经在论坛上看过有人要用VM加密整个程序的同志......这个数字转换是在令人吃惊) 把记录拉到最下面, 可以看到VMProtect在POP恢复了寄存器之后(随机顺序)RETN到了入口点.
嘿嘿, 想到了什么吗? 我们加密之前程序段中没有RETN! 我们可以用"执行到返回 CTRL+F9"快速定位到这个JMP中:
010143C7 8D87 07020000 lea eax, dword ptr [edi+207]
010143CD 8020 7F and byte ptr [eax], 7F
010143D0 8060 28 7F and byte ptr [eax+28], 7F ;停在这里
010143D4 68 E5E45EBC push BC5EE4E5
010143D9 - E9 81990000 jmp 0101DD5F
010143DE 80E0 3C and al, 3C
010143E1 8F0407 pop dword ptr [edi+eax]
010143E4 - E9 8D920000 jmp 0101D676
010143E9 5C pop esp
010143EA - E9 87920000 jmp 0101D676
010143EF 54 push esp
首先停在010143D0处, 然后摁4次CTRL+F9 顺利到达入口点.
以上是一个超笨的方法, 首先我们已经知道代码加密前的情况, 并且我还不知道这是否有通用性. 如果加密者稍微摆动一下, 这些诡计就可能失效了. (我猜测, 如果加密段最后一个语句是JMP, 而不是retn, 我们可以用此方法快速步过Vmprotect加密的段, 到达想去的地方).
VM让整个世界变复杂了...
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法