本文以 Themida 3.1.9.20 FALCON64 (Tiny) VM为研究对象,FALCON64是最简单的Themida VM。分析了大部分Handler与VM_Context等,并通过一个加了VM的简单程序来进行逆向,剖析其功能,最后进行JCC爆破,解决问题。
准备
#include <iostream>
#include <ThemidaSDK.h>
int main()
{
std::cout << "main()\n";
VM_START;
std::cout << "Input Your Flag:";
std::string s;
std::cin >> s;
if (s == "flag{test_flag}")
{
std::cout << "right";
}
else
{
std::cout << "fail";
}
VM_END;
system("pause");
return 0;
}
VM我们使用FALCON64 (Tiny)
调试器:x64dbg.exe,装插件 CodeCleaner https://github.com/Steesha/CodeCleaner
VM_init
我们留了一手 main() 字符串,可以看到jmp后面的代码被rand()替换掉了,本来是我们正常的代码。
jmp后即开始VM准备进入阶段。
使用CodeCleaner可以大概清除Mutate
大概流程是,
STACK
===============
.... All Registers
0x291FFE
RBX
RAX
R15 -> 0x291FFE
RDX
R8 -> 0x10B
RFLAG
这里需要注意的是一个 magic 0x291FFE
在下一个JMP后看到了一个CALL $0
这个CALL $0 负责获取 RIP(0x14004A4FC)
再往下翻,可以看到rcx(saved RIP)减去 0x4A4FC,计算基址(0x140000000)。
基址用于后续计算各种地址。
0x10B的作用是,左移3(*8)后,加上 handlers表的offset,可以获取到下一个Handler的地址。
Function Handler List 在这里解密后放入R14d,而后R14d加上BaseVA,就是上图的rax的值,再加上rbx(第n个函数的地址),就是跳转到下一个函数的地址。
最后,直接跳转,进入第一个VM Handler。
下面,给出CodeCleaner的完整结果(NOP指令已省去)。
000000014028B479 | 9C | pushfq
000000014028B47A | 68 0B010000 | push 0x10B
000000014028B4AA | 68 FE1F2900 | push 0x291FFE
000000014028B4CA | 50 | push rax
000000014028B4DB | 53 | push rbx
000000014028B4EB | 48:8B4424 20 | mov rax,qword ptr ss:[rsp+0x20]
000000014028B50F | 48:8B5C24 10 | mov rbx,qword ptr ss:[rsp+0x10]
000000014028B536 | 48:894424 10 | mov qword ptr ss:[rsp+0x10],rax
000000014028B54B | 48:895C24 20 | mov qword ptr ss:[rsp+0x20],rbx
000000014028B56E | 5B | pop rbx
000000014028B594 | 58 | pop rax
000000014028B5C5 | 68 D2120000 | push 0x12D2
000000014028B5EB | E9 07EFDBFF | jmp themida_test_protected.14004A4F7
000000014004A4F7 | E8 00000000 | call themida_test_protected.14004A4FC
000000014004A4FC | 52 | push rdx
000000014004A50E | 53 | push rbx
000000014004A51F | 53 | push rbx
000000014004A535 | 55 | push rbp
000000014004A545 | 56 | push rsi
000000014004A565 | 57 | push rdi
000000014004A575 | 41:57 | push r15
000000014004A58E | 41:56 | push r14
000000014004A5A6 | 41:55 | push r13
000000014004A5B8 | 41:54 | push r12
000000014004A5D5 | 41:53 | push r11
000000014004A5EC | 41:52 | push r10
000000014004A607 | 41:51 | push r9
000000014004A620 | 41:50 | push r8
000000014004A631 | 49:89C8 | mov r8,rcx
000000014004A64F | 4C:8B4C24 78 | mov r9,qword ptr ss:[rsp+0x78]
000000014004A670 | 48:8B4C24 70 | mov rcx,qword ptr ss:[rsp+0x70]
000000014004A686 | 48:894424 78 | mov qword ptr ss:[rsp+0x78],rax
000000014004A699 | 48:83E9 05 | sub rcx,0x5
000000014004A69D | 48:81E9 F7A40400 | sub rcx,0x4A4F7
000000014004A6A4 | 41:56 | push r14
000000014004A6AD | 49:C7C6 4E1ADD6F | mov r14,0x6FDD1A4E
000000014004A6B4 | 41:FFC6 | inc r14d
000000014004A6B7 | 41:81E6 D4A7EF7F | and r14d,0x7FEFA7D4
000000014004A6BE | 41:81EE 21FF0D60 | sub r14d,0x600DFF21
000000014004A6C5 | 4C:89F5 | mov rbp,r14
000000014004A6C8 | 48:81C5 C756CF7B | add rbp,0x7BCF56C7
000000014004A6CF | 81ED C756CF7B | sub ebp,0x7BCF56C7
000000014004A6D5 | 41:5E | pop r14
000000014004A6D7 | 81CD FF69EF7B | or ebp,0x7BEF69FF
000000014004A6DD | C1E5 06 | shl ebp,0x6
000000014004A6E0 | 81C5 668CFF4D | add ebp,0x4DFF8C66
000000014004A6E6 | F7DD | neg ebp
000000014004A6E8 | 81F5 B6FCFB2D | xor ebp,0x2DFBFCB6
000000014004A6EE | 81ED C2EFDB9F | sub ebp,0x9FDBEFC2
000000014004A710 | 48:01CD | add rbp,rcx
000000014004A72F | 51 | push rcx
000000014004A747 | B9 990FE7ED | mov ecx,0xEDE70F99
000000014004A752 | 57 | push rdi
000000014004A753 | BF 00892877 | mov edi,0x77288900
000000014004A75B | FFC7 | inc edi
000000014004A75D | 81C7 D7ECCF6B | add edi,0x6BCFECD7
000000014004A763 | C1EF 03 | shr edi,0x3
000000014004A766 | 81F7 C21E6C67 | xor edi,0x676C1EC2
000000014004A76C | 81C7 A831EF66 | add edi,0x66EF31A8
000000014004A772 | FFCF | dec edi
000000014004A774 | 81CF 73BEED4F | or edi,0x4FEDBE73
000000014004A77A | 41:54 | push r12
000000014004A77C | 41:BC CDD4FB6F | mov r12d,0x6FFBD4CD
000000014004A782 | 44:29E7 | sub edi,r12d
000000014004A785 | 41:5C | pop r12
000000014004A787 | F7D7 | not edi
000000014004A789 | 52 | push rdx
000000014004A78A | BA 072034EF | mov edx,0xEF342007
000000014004A795 | 01D7 | add edi,edx
000000014004A797 | 5A | pop rdx
000000014004A798 | 01F9 | add ecx,edi
000000014004A79A | 5F | pop rdi
000000014004A79B | 81E9 F805275D | sub ecx,0x5D2705F8
000000014004A7A1 | 57 | push rdi
000000014004A7A2 | 50 | push rax
000000014004A7A3 | B8 F75B7F5C | mov eax,0x5C7F5BF7
000000014004A7A8 | BF 43BC78D4 | mov edi,0xD478BC43
000000014004A7AD | 29C7 | sub edi,eax
000000014004A7AF | 58 | pop rax
000000014004A7B0 | BB 03E2BBAA | mov ebx,0xAABBE203
000000014004A7C7 | 01FB | add ebx,edi
000000014004A7C9 | 81C3 43E4FC7B | add ebx,0x7BFCE443
000000014004A7CF | 81EB 9CC0BA1F | sub ebx,0x1FBAC09C
000000014004A7D5 | 81EB 2365F77E | sub ebx,0x7EF76523
000000014004A7DB | 5F | pop rdi
000000014004A7DC | 31C0 | xor eax,eax
000000014004A7DE | F0:0FB10C2B | lock cmpxchg dword ptr ds:[rbx+rbp],ecx
000000014004A7E3 | 0F84 07000000 | je themida_test_protected.14004A7F0
000000014004A7E9 | F3:90 | pause
000000014004A7EB | E9 ECFFFFFF | jmp themida_test_protected.14004A7DC
000000014004A7F0 | 59 | pop rcx
000000014004A809 | 51 | push rcx
000000014004A80A | B9 E9A2FF7F | mov ecx,0x7FFFA2E9
000000014004A80F | FFC1 | inc ecx
000000014004A811 | C1E9 06 | shr ecx,0x6
000000014004A814 | 81C1 693EFE6F | add ecx,0x6FFE3E69
000000014004A81A | 81C1 91B1DE6B | add ecx,0x6BDEB191
000000014004A820 | 81F1 3EEEDCDD | xor ecx,0xDDDCEE3E
000000014004A826 | 48:89CB | mov rbx,rcx
000000014004A829 | 81F3 5AF7EF5F | xor ebx,0x5FEFF75A
000000014004A82F | 56 | push rsi
000000014004A830 | BE 5AF7EF5F | mov esi,0x5FEFF75A
000000014004A835 | 31F3 | xor ebx,esi
000000014004A837 | 5E | pop rsi
000000014004A838 | 59 | pop rcx
000000014004A840 | 41:52 | push r10
000000014004A842 | 49:89CA | mov r10,rcx
000000014004A85E | 4C:89142B | mov qword ptr ds:[rbx+rbp],r10
000000014004A862 | 41:5A | pop r10
000000014004A86A | 41:53 | push r11
000000014004A873 | 41:57 | push r15
000000014004A875 | 41:BF 3C2EE37B | mov r15d,0x7BE32E3C
000000014004A87B | 41:F7DF | neg r15d
000000014004A87E | 41:FFC7 | inc r15d
000000014004A881 | 41:81C7 FDAE4F7D | add r15d,0x7D4FAEFD
000000014004A888 | 41:81F7 BECBF75D | xor r15d,0x5DF7CBBE
000000014004A88F | 41:FFC7 | inc r15d
000000014004A892 | 41:81C7 83B464A3 | add r15d,0xA364B483
000000014004A899 | 45:89FB | mov r11d,r15d
000000014004A89C | 41:5F | pop r15
000000014004A89E | 44:89DA | mov edx,r11d
000000014004A8A1 | 41:5B | pop r11
000000014004A8AA | 85D2 | test edx,edx
000000014004A8AC | 0F84 12010000 | je themida_test_protected.14004A9C4
000000014004A8B2 | 55 | push rbp
000000014004A8BD | 48:89E5 | mov rbp,rsp
000000014004A8CB | 48:872C24 | xchg qword ptr ss:[rsp],rbp
000000014004A8CF | 48:8B2424 | mov rsp,qword ptr ss:[rsp]
000000014004A8D3 | 48:890C24 | mov qword ptr ss:[rsp],rcx
000000014004A8D7 | BB 403DFF1F | mov ebx,0x1FFF3D40
000000014004A8DF | FFC3 | inc ebx
000000014004A8E1 | 41:51 | push r9
000000014004A8E3 | 41:B9 11A63708 | mov r9d,0x837A611
000000014004A8F0 | 41:FFC1 | inc r9d
000000014004A8F3 | 41:FFC1 | inc r9d
000000014004A8F6 | 41:81C1 DC5D74D8 | add r9d,0xD8745DDC
000000014004A909 | 44:01CB | add ebx,r9d
000000014004A918 | 41:59 | pop r9
000000014004A92F | 48:01CB | add rbx,rcx
000000014004A947 | 53 | push rbx
000000014004A960 | BB 4F20BE6C | mov ebx,0x6CBE204F
000000014004A965 | B9 E120ED93 | mov ecx,0x93ED20E1
000000014004A96A | 01D9 | add ecx,ebx
000000014004A96C | 5B | pop rbx
000000014004A977 | 41:52 | push r10
000000014004A979 | 49:89DA | mov r10,rbx
000000014004A97C | 4C:891429 | mov qword ptr ds:[rcx+rbp],r10
000000014004A980 | 41:5A | pop r10
000000014004A999 | 59 | pop rcx
000000014004A9C4 | 56 | push rsi
000000014004A9C5 | BE 9808F777 | mov esi,0x77F70898
000000014004A9CA | BB 004CF6CE | mov ebx,0xCEF64C00
000000014004A9D2 | F7DB | neg ebx
000000014004A9D4 | C1E3 06 | shl ebx,0x6
000000014004A9D7 | 51 | push rcx
000000014004A9D8 | B9 2634F772 | mov ecx,0x72F73426
000000014004A9DD | 01CB | add ebx,ecx
000000014004A9DF | 59 | pop rcx
000000014004A9E0 | 81C3 00FD3F76 | add ebx,0x763FFD00
000000014004A9E6 | 81EB B6DEA7B3 | sub ebx,0xB3A7DEB6
000000014004A9EC | 29F3 | sub ebx,esi
000000014004A9EE | 5E | pop rsi
000000014004A9F6 | 41:50 | push r8
000000014004AA14 | 41:B8 01000000 | mov r8d,0x1
000000014004AA21 | 44:89C0 | mov eax,r8d
000000014004AA24 | 41:58 | pop r8
000000014004AA26 | 85C0 | test eax,eax
000000014004AA28 | 0F84 76000000 | je themida_test_protected.14004AAA4
000000014004AA2E | B8 C8C02C2A | mov eax,0x2A2CC0C8
000000014004AA45 | 41:51 | push r9
000000014004AA47 | 41:57 | push r15
000000014004AA49 | 49:C7C7 8DD4FF3E | mov r15,0x3EFFD48D
000000014004AA50 | 41:F7DF | neg r15d
000000014004AA53 | 41:F7D7 | not r15d
000000014004AA56 | 41:81F7 626F8C65 | xor r15d,0x658C6F62
000000014004AA5D | 45:89F9 | mov r9d,r15d
000000014004AA60 | 41:5F | pop r15
000000014004AA62 | 41:81E1 1212F95F | and r9d,0x5FF91212
000000014004AA69 | 41:FFC1 | inc r9d
000000014004AA6C | 41:FFC9 | dec r9d
000000014004AA6F | 41:55 | push r13
000000014004AA71 | 41:BD CAD29D85 | mov r13d,0x859DD2CA
000000014004AA77 | 45:29E9 | sub r9d,r13d
000000014004AA7A | 41:5D | pop r13
000000014004AA7C | 44:01C8 | add eax,r9d
000000014004AA7F | 41:59 | pop r9
000000014004AA81 | 85C0 | test eax,eax
000000014004AA83 | 0F84 10000000 | je themida_test_protected.14004AA99
000000014004AA89 | 6548:A1 8801000000000000 | mov rax,qword ptr gs:[0x188]
000000014004AA94 | E9 0B000000 | jmp themida_test_protected.14004AAA4
000000014004AA99 | 6548:A1 3000000000000000 | mov rax,qword ptr gs:[0x30]
000000014004AAA4 | 48:C1E0 20 | shl rax,0x20
000000014004AAA8 | 31D2 | xor edx,edx
000000014004AAAA | 41:53 | push r11
000000014004AAAC | 49:89C3 | mov r11,rax
000000014004AAAF | 41:53 | push r11
000000014004AAB1 | 52 | push rdx
000000014004AAB2 | 48:BA 9164781500000000 | mov rdx,0x15786491
000000014004AABC | 48:015424 08 | add qword ptr ss:[rsp+0x8],rdx
000000014004AAC1 | 5A | pop rdx
000000014004AAC2 | 5A | pop rdx
000000014004AACA | 48:81EA 91647815 | sub rdx,0x15786491
000000014004AAD1 | 41:5B | pop r11
000000014004AAD3 | 41:51 | push r9
000000014004AADD | 53 | push rbx
000000014004AADE | 41:52 | push r10
000000014004AAE0 | 41:BA 723BFB7F | mov r10d,0x7FFB3B72
000000014004AAE6 | BB 5CD49118 | mov ebx,0x1891D45C
000000014004AAEB | 44:31D3 | xor ebx,r10d
000000014004AAEE | 41:5A | pop r10
000000014004AAF0 | 295C24 08 | sub dword ptr ss:[rsp+0x8],ebx
000000014004AAF4 | 5B | pop rbx
000000014004AAF5 | 58 | pop rax
000000014004AAF6 | 05 2EEF6A67 | add eax,0x676AEF2E
000000014004AAFB | 48:09C2 | or rdx,rax
000000014004AAFE | 52 | push rdx
000000014004AAFF | 57 | push rdi
000000014004AB00 | 41:50 | push r8
000000014004AB09 | 49:B8 05DADF7F00000000 | mov r8,0x7FDFDA05
000000014004AB13 | 4C:89C7 | mov rdi,r8
000000014004AB16 | 41:58 | pop r8
000000014004AB18 | 48:317C24 08 | xor qword ptr ss:[rsp+0x8],rdi
000000014004AB1D | 5F | pop rdi
000000014004AB1E | 8F0419 | pop qword ptr ds:[rcx+rbx]
000000014004AB21 | 48:813419 05DADF7F | xor qword ptr ds:[rcx+rbx],0x7FDFDA05
000000014004AB29 | 41:51 | push r9
000000014004AB2B | 41:B9 7EF2DF6F | mov r9d,0x6FDFF27E
000000014004AB31 | 41:52 | push r10
000000014004AB33 | 41:BA 5BE3FA6D | mov r10d,0x6DFAE35B
000000014004AB39 | 45:29D1 | sub r9d,r10d
000000014004AB3C | 41:5A | pop r10
000000014004AB3E | 41:81C9 3601BF3E | or r9d,0x3EBF0136
000000014004AB45 | 41:C1E9 02 | shr r9d,0x2
000000014004AB49 | 41:57 | push r15
000000014004AB4B | 41:BF 01000000 | mov r15d,0x1
000000014004AB51 | 45:29F9 | sub r9d,r15d
000000014004AB54 | 41:5F | pop r15
000000014004AB5C | 41:81E9 E1C2FF0F | sub r9d,0xFFFC2E1
000000014004AB63 | 44:89CA | mov edx,r9d
000000014004AB66 | 41:59 | pop r9
000000014004AB68 | 53 | push rbx
000000014004AB81 | 41:50 | push r8
000000014004AB83 | 41:B8 A7ECDD27 | mov r8d,0x27DDECA7
000000014004AB89 | 44:014424 08 | add dword ptr ss:[rsp+0x8],r8d
000000014004AB8E | 41:58 | pop r8
000000014004AB90 | 58 | pop rax
000000014004AB91 | 2D A7ECDD27 | sub eax,0x27DDECA7
000000014004ABB4 | 48:01C8 | add rax,rcx
000000014004ABD5 | 48:89042A | mov qword ptr ds:[rdx+rbp],rax
000000014004ABFA | 4C:894424 70 | mov qword ptr ss:[rsp+0x70],r8
000000014004AC1F | 56 | push rsi
000000014004AC27 | 41:57 | push r15
000000014004AC29 | 49:C7C7 1BF66B7A | mov r15,0x7A6BF61B
000000014004AC37 | 41:81E7 172EFA4C | and r15d,0x4CFA2E17
000000014004AC3E | 52 | push rdx
000000014004AC3F | BA 768E7B6D | mov edx,0x6D7B8E76
000000014004AC44 | 41:31D7 | xor r15d,edx
000000014004AC47 | 5A | pop rdx
000000014004AC48 | 41:81EF 3F8B62A7 | sub r15d,0xA7628B3F
000000014004AC4F | 44:89FE | mov esi,r15d
000000014004AC52 | 41:5F | pop r15
000000014004AC54 | BB 9DE35082 | mov ebx,0x8250E39D
000000014004AC59 | 01F3 | add ebx,esi
000000014004AC5B | 5E | pop rsi
000000014004AC5C | 48:8B4424 50 | mov rax,qword ptr ss:[rsp+0x50]
000000014004AC6F | 50 | push rax
000000014004AC77 | 48:812C24 4F73757F | sub qword ptr ss:[rsp],0x7F75734F
000000014004AC7F | 8F042B | pop qword ptr ds:[rbx+rbp]
000000014004AC82 | 48:81042B 4F73757F | add qword ptr ds:[rbx+rbp],0x7F75734F
000000014004AC8A | 41:52 | push r10
000000014004AC92 | 41:BA 6A03F87F | mov r10d,0x7FF8036A
000000014004AC98 | 44:89D3 | mov ebx,r10d
000000014004AC9B | 41:5A | pop r10
000000014004AC9D | 41:52 | push r10
000000014004AC9F | 41:BA 6FEBFF5A | mov r10d,0x5AFFEB6F
000000014004ACAC | 41:F7DA | neg r10d
000000014004ACAF | 52 | push rdx
000000014004ACB0 | BA FCD3EF61 | mov edx,0x61EFD3FC
000000014004ACB5 | F7DA | neg edx
000000014004ACB7 | 81C2 C86CD5E1 | add edx,0xE1D56CC8
000000014004ACBD | 41:01D2 | add r10d,edx
000000014004ACC0 | 5A | pop rdx
000000014004ACC1 | 41:81CA B93BFD76 | or r10d,0x76FD3BB9
000000014004ACC8 | 41:81C2 E4E0AC06 | add r10d,0x6ACE0E4
000000014004ACCF | 44:09D3 | or ebx,r10d
000000014004ACD2 | 41:5A | pop r10
000000014004ACD4 | 81EB FB3E7B3F | sub ebx,0x3F7B3EFB
000000014004ACDA | FFC3 | inc ebx
000000014004ACDC | 81F3 43647F40 | xor ebx,0x407F6443
000000014004ACE2 | 48:8B8424 90000000 | mov rax,qword ptr ss:[rsp+0x90]
000000014004AD13 | 48:01C8 | add rax,rcx
000000014004AD2E | 56 | push rsi
000000014004AD37 | 48:89E6 | mov rsi,rsp
000000014004AD45 | 48:873424 | xchg qword ptr ss:[rsp],rsi
000000014004AD49 | 48:8B2424 | mov rsp,qword ptr ss:[rsp]
000000014004AD4D | 4C:893C24 | mov qword ptr ss:[rsp],r15
000000014004AD51 | 49:89C7 | mov r15,rax
000000014004AD54 | 4C:893C2B | mov qword ptr ds:[rbx+rbp],r15
000000014004AD58 | 41:5F | pop r15
000000014004AD5A | 41:56 | push r14
000000014004AD63 | 41:BE 14D2DDDE | mov r14d,0xDEDDD214
000000014004AD70 | 41:F7D6 | not r14d
000000014004AD73 | 41:FFC6 | inc r14d
000000014004AD76 | 41:81EE B623FD37 | sub r14d,0x37FD23B6
000000014004AD7D | 41:FFC6 | inc r14d
000000014004AD80 | 41:81EE A76A1FE9 | sub r14d,0xE91F6AA7
000000014004AD87 | 41:56 | push r14
000000014004AD89 | 53 | push rbx
000000014004AD8A | BB 3745FF77 | mov ebx,0x77FF4537
000000014004AD8F | 315C24 08 | xor dword ptr ss:[rsp+0x8],ebx
000000014004AD93 | 5B | pop rbx
000000014004AD94 | 58 | pop rax
000000014004AD9F | 35 3745FF77 | xor eax,0x77FF4537
000000014004ADA4 | 41:5E | pop r14
000000014004ADC4 | 48:01C8 | add rax,rcx
000000014004ADE5 | 41:57 | push r15
000000014004ADEF | 49:C7C7 71B2F67D | mov r15,0x7DF6B271
000000014004ADFF | 41:F7D7 | not r15d
000000014004AE02 | 41:C1E7 08 | shl r15d,0x8
000000014004AE06 | 41:81EF B47E8F7B | sub r15d,0x7B8F7EB4
000000014004AE0D | 41:81F7 9B0FBE8D | xor r15d,0x8DBE0F9B
000000014004AE14 | 44:89FB | mov ebx,r15d
000000014004AE17 | 41:5F | pop r15
000000014004AE1F | FF342B | push qword ptr ds:[rbx+rbp]
000000014004AE22 | 41:57 | push r15
000000014004AE2B | 49:BF 8AADEF5F00000000 | mov r15,0x5FEFAD8A
000000014004AE35 | 4C:317C24 08 | xor qword ptr ss:[rsp+0x8],r15
000000014004AE3A | 41:5F | pop r15
000000014004AE46 | 5A | pop rdx
000000014004AE47 | 48:81F2 8AADEF5F | xor rdx,0x5FEFAD8A
000000014004AE4E | 48:39C2 | cmp rdx,rax
000000014004AE51 | 0F84 6B010000 | je themida_test_protected.14004AFC2
000000014004AE57 | 53 | push rbx
000000014004AE70 | 55 | push rbp
000000014004AE71 | BD 4A6FDF76 | mov ebp,0x76DF6F4A
000000014004AE76 | BB DA7BDF76 | mov ebx,0x76DF7BDA
000000014004AE96 | 31EB | xor ebx,ebp
000000014004AE98 | 5D | pop rbp
000000014004AEB4 | C1EB 03 | shr ebx,0x3
000000014004AEB7 | 50 | push rax
000000014004AECF | 48:85DB | test rbx,rbx
000000014004AED2 | 0F84 78000000 | je themida_test_protected.14004AF50
000000014004AED8 | 48:8100 C29CCE7F | add qword ptr ds:[rax],0x7FCE9CC2
000000014004AEDF | 52 | push rdx
000000014004AEE0 | 48:31D2 | xor rdx,rdx
000000014004AEEE | 48:01C2 | add rdx,rax
000000014004AEF8 | 41:53 | push r11
000000014004AEFA | 4D:31DB | xor r11,r11
000000014004AF01 | 49:01D3 | add r11,rdx
000000014004AF04 | 49:010B | add qword ptr ds:[r11],rcx
000000014004AF07 | 41:5B | pop r11
000000014004AF09 | 5A | pop rdx
000000014004AF11 | 48:8128 C29CCE7F | sub qword ptr ds:[rax],0x7FCE9CC2
000000014004AF18 | 48:83C0 08 | add rax,0x8
000000014004AF1C | 41:51 | push r9
000000014004AF1E | 41:50 | push r8
000000014004AF20 | 41:B8 4649515F | mov r8d,0x5F514946
000000014004AF26 | 50 | push rax
000000014004AF27 | B8 13702E3F | mov eax,0x3F2E7013
000000014004AF2C | FFC0 | inc eax
000000014004AF2E | 55 | push rbp
000000014004AF2F | BD 53397F60 | mov ebp,0x607F3953
000000014004AF3A | 31E8 | xor eax,ebp
000000014004AF3C | 5D | pop rbp
000000014004AF3D | 41:29C0 | sub r8d,eax
000000014004AF40 | 58 | pop rax
000000014004AF41 | 45:89C1 | mov r9d,r8d
000000014004AF44 | 41:58 | pop r8
000000014004AF46 | 44:01CB | add ebx,r9d
000000014004AF49 | 41:59 | pop r9
000000014004AF4B | E9 7FFFFFFF | jmp themida_test_protected.14004AECF
000000014004AF50 | 58 | pop rax
000000014004AF70 | 5B | pop rbx
000000014004AF9F | 41:57 | push r15
000000014004AFA1 | 49:89C7 | mov r15,rax
000000014004AFA4 | 51 | push rcx
000000014004AFA5 | 4C:89F9 | mov rcx,r15
000000014004AFB1 | 48:890C2B | mov qword ptr ds:[rbx+rbp],rcx
000000014004AFB5 | 59 | pop rcx
000000014004AFC0 | 41:5F | pop r15
000000014004AFC2 | FFB424 88000000 | push qword ptr ss:[rsp+0x88]
000000014004AFC9 | 48:8B1C24 | mov rbx,qword ptr ss:[rsp]
000000014004AFCD | 53 | push rbx
000000014004AFCE | 48:89E3 | mov rbx,rsp
000000014004AFD1 | 83C3 08 | add ebx,0x8
000000014004AFD4 | 48:81C3 08000000 | add rbx,0x8
000000014004AFDB | 48:871C24 | xchg qword ptr ss:[rsp],rbx
000000014004AFDF | 5C | pop rsp
000000014004AFE0 | 48:C1E3 03 | shl rbx,0x3
000000014004B002 | 48:01D8 | add rax,rbx
000000014004B023 | FF20 | jmp qword ptr ds:[rax]
中间的立即数大多数都在解密常量,不清理了,能看就行。
额外注意对rbp的操作,比如 mov qword ptr ds:[rbx+rbp],rcx
rbp 在整个vm handler中都是指向 Handler的,可以从上面大致分析出VM handler的一些字段。
VM
经过简单分析,从第一个VM开始Trace,即可知道所有vm所调用的handler在哪,handler其实在handler表中,handler表在OEP vm内进行解密,当然OEP vm还进行了重定位修复等操作,由于我们没有启用反调试,所以OEP中没有反调试操作。
分析handler是大工程,但是比较简单,只要一边恢复VM_Context一边走遍所有Handlers,进行分析即可。
我们采用x64dbg的断点系统进行log断点,即可输出VM的相关信息。
下面我们给出VM_Context相关介绍。
VM_Context
struct __unaligned __declspec(align(1)) vm_context
{
_QWORD v_RAX;
_QWORD v_RBX;
_QWORD v_RCX;
_QWORD v_RDX;
_QWORD v_RSI;
_QWORD v_RDI;
_QWORD v_RBP_themida_seg_base;
_QWORD v_RSP;
_QWORD v_RFL;
_QWORD v_R8;
_QWORD v_R9;
_QWORD v_R10;
_QWORD v_R11;
_QWORD v_R12;
_QWORD v_R13;
_QWORD v_R14;
_QWORD v_R15;
_QWORD v_unk;
_BYTE gap_zero0[32];
_BYTE gap_zero1[2];
insn_ctx *vm_op;
_BYTE enable_jmp;
QWORD module_base;
QWORD start_Of_Themida_Segment_0;
QWORD gap_unk3;
DWORD mutex_lock;
__int64 (**handler_table)(void);
_BYTE gap2[12];
QWORD process_heap;
QWORD start_Of_Themida_Segment;
_DWORD vReg0;
_DWORD vReg1;
_DWORD vReg2;
unsigned int vReg3_dword;
_DWORD vReg4;
_DWORD vReg5;
_DWORD vReg6;
DWORD unk1;
_BYTE gap3[8];
_WORD vReg7;
unsigned __int16 v_tmp;
_WORD vReg9;
_BYTE gap4[4];
_BYTE vField1;
_BYTE vField1_2[6];
QWORD vFiled_unk;
_BYTE vField2[64];
};
struct __unaligned __declspec(align(2)) insn_ctx
{
unsigned __int16 r0;
unsigned __int8 r1l;
unsigned __int8 r1h;
unsigned __int8 r2l;
unsigned __int8 r2h;
unsigned __int8 r3l;
unsigned __int8 r3h;
unsigned __int8 r4l;
unsigned __int8 r4h;
unsigned __int8 r5l;
unsigned __int8 r5h;
unsigned __int8 r6l;
unsigned __int8 r6h;
unsigned __int8 r7l;
unsigned __int8 r7h;
unsigned __int8 r8l;
unsigned __int8 r8h;
};
VM中,RBP指向VM_Context。
可见Handler前半部分是VM内维护的寄存器,后半部分是保存的一些有用的数值和VM内的虚拟寄存器,用于存放临时数据。
Mutex_Lock
Themida VM具有多线程锁,VM同时只能在一个线程中运行,这由VM_init段的一段原子操作有关。
lock cmpxchg 操作的是 VM_Context 中的 mutex_lock 字段。我们下来解释一下这段代码。
首先eax置0,然后进行 lock cmpxchg操作,这个指令判断如果eax == [rbx+rbp],那么就把 ecx 放入 [rbx+rbp],否则将 [rbx+rbp] 放入 eax。
ecx是Imm,固定为1(上面解密了)。
它相当于是 一个 Mutex,第一次进入VM的时候,mutex_lock 字段是 0,eax也是0,那么就把ecx的1放入[rbx+rbp]之中,用于标记防止其他线程进入VM。在VM_Exit的时候将mutex_lock清空即可。这么做的原因是因为Themida的VM_Context是在文件中的,而不是动态分配的一段内存,所以所有VM都会复用这一段Context,这时必然出现一些问题。
VM_Handlers
下面我们介绍一些比较经典的Handlers
vPOP
handler_vPOP 用于把VM_init push进来的状态(各种寄存器)pop到VM_Context中。其中vm_op->r0是operands链表,在每个vm_handler中都会访问,并且更新(让它指向下一个operands)。
除此之外,每个handler还会准备下一个handler_table的值,用于准备跳转。
// positive sp value has been detected, the output may be wrong!
__int64 __fastcall handler_vPOP()
{
vm_context *v0; // rbp
_QWORD *saving_reg; // rdx
_QWORD *saved_sp; // r15
__int64 (*v3)(void); // rdx
__int64 value_from_stack; // [rsp+50h] [rbp-8h]
v0->v_tmp = v0->vm_op->r0; // mov [sp + v.operand], true_stack_value
saving_reg = (_QWORD *)((char *)&v0->v_RAX + v0->v_tmp);
*saving_reg = value_from_stack;
saved_sp = (_QWORD *)((char *)&v0->v_RAX + *(unsigned __int16 *)&v0->vm_op->r2l);// stack_size
if ( saving_reg != saved_sp )
*saved_sp += 8LL; // 保存的rsp,如果正在保存的寄存器要保存到虚拟栈的地址和之前保存的RSP的地址一样
// 说明POP RSP,所以给保存的RSP+8
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r1l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r3l);
return v3();
}
vJCC
这个handler有着根据Flags寄存器进行判断,而后进行跳转的职责。
我们查看Intel白皮书的EFLAGs寄存器与各种JCC的跳转前提。
注:这里本人认为,第一个 JA/JNBE的跳转条件应为: (CF and ZF) = 0。
__int64 __fastcall handler_check_RFL()
{
vm_context *v0; // rbp
unsigned __int8 *p_r4l; // rcx
eflags rfl; // edi
unsigned __int8 r5l; // si
char value; // r8
char v5; // r8
int OF; // r8d
int v7; // r8d
int v8; // r8d
int v9; // r8d
__int64 (*v10)(void); // r14
__int64 v11; // r15
__int64 (*v13)(void); // rdx
int v14; // [rsp+50h] [rbp-8h]
v0->enable_jmp = 0;
p_r4l = &v0->vm_op->r4l;
rfl.value = *(DWORD *)((char *)&v0->v_RAX + *(unsigned __int16 *)p_r4l);// get Flag Register
r5l = v0->vm_op->r5l;
if ( r5l == 0xCB || r5l == 0xA0 )
{
v14 = *(_DWORD *)((char *)&v0->v_RAX + *(unsigned __int16 *)p_r4l);
if ( (rfl.value & 0x40) != 0 ) // ZF != 0
v0->enable_jmp = 1; // jne/jnz
LOWORD(rfl.value) = v14;
}
if ( r5l == 0xC7 )
{
rfl.value = rfl.value & 0x40;
if ( !rfl.value ) // ZF == 0
v0->enable_jmp = 1; // je/jz
}
if ( r5l == 0xE )
{
value = rfl.value;
rfl.value = rfl.value & 0x40;
if ( !rfl.value && (value & 1) == 0 ) // ZF == 0 && CF == 0
v0->enable_jmp = 1; // JA
}
if ( r5l == 107 )
{
rfl.value = rfl.value & 1;
if ( !rfl.value ) // CF == 0
v0->enable_jmp = 1; // JAE/JNB
}
if ( r5l == 0xAA )
{
rfl.value = rfl.value & 1;
if ( rfl.value ) // CF == 1
v0->enable_jmp = 1; // JB/JNAE/JC
}
if ( r5l == 0xBA )
{
v5 = rfl.value;
rfl.value = rfl.value & 0x40;
if ( rfl.value )
v0->enable_jmp = 1; // ZF == 1
if ( (v5 & 1) != 0 )
v0->enable_jmp = 1; // CF == 1
} // ZF == 1 OR CF == 1
// JBE/JNA
if ( r5l == 0xD5 && (rfl.value & 0x40) == 0 )
{
OF = (unsigned __int16)(rfl.value & 0x800) >> 11;// OF
rfl.value = (unsigned __int8)(rfl.value & 0x80) >> 7;// SF
if ( rfl.value == OF ) // SF == OF
v0->enable_jmp = 1; // JGE/JNL
}
if ( r5l == 93 )
{
v7 = (unsigned __int16)(rfl.value & 0x800) >> 11;
rfl.value = (unsigned __int8)(rfl.value & 0x80) >> 7;
if ( rfl.value == v7 )
v0->enable_jmp = 1; // JGE/JNL
}
if ( r5l == 52 )
{
v8 = (unsigned __int16)(rfl.value & 0x800) >> 11;
rfl.value = (unsigned __int8)(rfl.value & 0x80) >> 7;
if ( rfl.value != v8 ) // SF != OF
v0->enable_jmp = 1; // JL/JNGE
}
if ( r5l == 0xA0 )
{
if ( (rfl.value & 0x40) != 0 )
v0->enable_jmp = 1;
v9 = (unsigned __int16)(rfl.value & 0x800) >> 11;
rfl.value = (unsigned __int8)(rfl.value & 0x80) >> 7;
if ( rfl.value != v9 ) // ((SF xor OF) or ZF) == 1
v0->enable_jmp = 1; // JLE/JNG
}
if ( r5l == 0xCF )
{
rfl.value = rfl.value & 0x800;
if ( !rfl.value ) // OF == 0
v0->enable_jmp = 1; // JNO
}
if ( r5l == 108 )
{
rfl.value = rfl.value & 4;
if ( !rfl.value ) // PF == 0
v0->enable_jmp = 1; // JNP/JPO
}
if ( r5l == 36 )
{
rfl.value = rfl.value & 0x80;
if ( !rfl.value ) // SF == 0
v0->enable_jmp = 1; // JNS
}
if ( r5l == 182 )
{
rfl.value = rfl.value & 0x800;
if ( rfl.value ) // OF == 1
v0->enable_jmp = 1; // JO
}
if ( r5l == 100 )
{
rfl.value = rfl.value & 4;
if ( rfl.value ) // PF == 1
v0->enable_jmp = 1; // JP/JPE
}
if ( r5l == 0xE5 && (rfl.value & 0x80) != 0 )
v0->enable_jmp = 1; // SF == 1
// JS
v10 = v0->handler_table[v0->vm_op->r0];
v11 = *(unsigned int *)&v0->vm_op->r2l;
if ( v0->enable_jmp )
{
if ( (v11 & 0x80000000) != 0 )
v0->vm_op = (insn_ctx *)((char *)v0->vm_op - (v11 & 0x7FFFFFFF));// offset > 0
else
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + v11);// offset < 0
return v10();
}
else
{
v13 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r5h];// not jump
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r6h);
return v13();
}
}
本Handler一目了然,通过vm_op中的值,来确定是哪种跳转,进而对rfl进行位运算,而后确定enable_jmp的值,在jump前进行偏移计算,来计算是否跳转的nodes。
vCMP & vXXX(影响标志位)
有了vJCC,那一定有一类Handlers负责通过比较运算或者算数/逻辑运算来改变EFLAGS寄存器。他们就是vCMP,vTEST和一些vADD(sub/xor等)。
算数/逻辑运算不一定都有保存Flag的操作(分两种Handlers),但是vTest,vCMP一定有保存Flag的操作。
__int64 __fastcall handler_vCmp_Reg8_Imm8()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r3h; // rbx
__int64 (*v3)(void); // r8
v0->v_tmp = v0->vm_op->r0;
v0->vReg3_dword = v0->vm_op->r1l;
v1 = __readeflags();
r3h = v0->vm_op->r3h;
if ( (_BYTE)r3h )
{
LOWORD(r3h) = *(_WORD *)&v0->vm_op->r1h;
*(_QWORD *)((char *)&v0->v_RAX + r3h) = v1;
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r2h];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4l);
return v3();
}
__int64 __fastcall handler_vCmp_Reg_Imm32()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r0_low; // r15
__int64 (*v3)(void); // r15
// 这个handler把vReg与常数比较,然后把RFL推入栈
v0->vReg3_dword = *(_DWORD *)&v0->vm_op->r1l;
v0->v_tmp = v0->vm_op->r0;
v1 = __readeflags();
r0_low = LOBYTE(v0->vm_op[1].r0);
if ( (_BYTE)r0_low ) // 是否保存RFL
{
LOWORD(r0_low) = v0->vm_op->r3l;
*(_QWORD *)((char *)&v0->v_RAX + r0_low) = v1;
}
v3 = v0->handler_table[v0->vm_op->r4l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)((char *)&v0->vm_op[1].r0 + 1));
return v3();
}
__int64 __fastcall handler_vCmp_mReg32_Imm32()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r5l; // r10
__int64 (*v3)(void); // r15
v0->vReg3_dword = *(_DWORD *)&v0->vm_op->r1l;
v0->v_tmp = v0->vm_op->r0;
v1 = __readeflags();
r5l = v0->vm_op->r5l;
if ( (_BYTE)r5l )
{
LOWORD(r5l) = *(_WORD *)&v0->vm_op->r3l;
*(_QWORD *)((char *)&v0->v_RAX + r5l) = v1;
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r4l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r5h);
return v3();
}
__int64 __fastcall handler_vCmp_Reg32_mReg32()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r4l; // rax
__int64 (*v3)(void); // r12
v0->v_tmp = v0->vm_op->r0;
v0->vReg7 = *(_WORD *)&v0->vm_op->r1l;
v1 = __readeflags();
r4l = v0->vm_op->r4l;
if ( (_BYTE)r4l )
{
LOWORD(r4l) = *(_WORD *)&v0->vm_op->r2l;
*(_QWORD *)((char *)&v0->v_RAX + r4l) = v1;
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r3l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4h);
return v3();
}
__int64 __fastcall handler_vTest_reg32_reg32()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r4l; // r14
__int64 (*v3)(void); // rcx
v0->vReg7 = *(_WORD *)&v0->vm_op->r1l;
v0->v_tmp = v0->vm_op->r0;
v1 = __readeflags();
r4l = v0->vm_op->r4l;
if ( (_BYTE)r4l )
{
LOWORD(r4l) = *(_WORD *)&v0->vm_op->r2l;
*(_QWORD *)((char *)&v0->v_RAX + r4l) = v1;
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r3l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4h);
return v3();
}
上面给出的vTEST/vCMP的核心指令(Test和CMP)IDA均没有分析出来,因为没有JCC。不过他们都是pushfq之前的一条指令,这样避免其他运算对Flag寄存器进行影响。
下面给出几种影响Flag寄存器的算术与逻辑运算。
__int64 __fastcall handler_vAdd_Reg64_Reg64()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r4l; // rbx
__int64 (*v3)(void); // r8
v0->v_tmp = v0->vm_op->r0;
v0->vReg7 = *(_WORD *)&v0->vm_op->r1l;
*(_QWORD *)((char *)&v0->v_RAX + v0->v_tmp) += *(_QWORD *)((char *)&v0->v_RAX + (unsigned __int16)v0->vReg7);
v1 = __readeflags(); // reg.op1 += reg.op2
// save RFL
r4l = v0->vm_op->r4l;
if ( (_BYTE)r4l )
{
LOWORD(r4l) = *(_WORD *)&v0->vm_op->r2l;
*(_QWORD *)((char *)&v0->v_RAX + r4l) = v1; // saveRFL
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r3l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4h);
return v3();
}
__int64 __fastcall handler_vAdd_mReg8_Imm8()
{
vm_context *v0; // rbp
__int64 v1; // rdi
_BYTE *v2; // r8
__int64 r3h; // r9
__int64 (*v4)(void); // r14
v0->v_tmp = v0->vm_op->r0;
v0->vReg3_dword = v0->vm_op->r1l;
v2 = *(_BYTE **)((char *)&v0->v_RAX + v0->v_tmp);
*v2 += v0->vReg3_dword;
__readeflags();
r3h = v0->vm_op->r3h;
if ( (_BYTE)r3h )
{
LOWORD(r3h) = *(_WORD *)&v0->vm_op->r1h;
*(_QWORD *)((char *)&v0->v_RAX + r3h) = v1;
}
v4 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r2h];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4l);
return v4();
}
__int64 __fastcall handler_vSub_Reg8_mReg8()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r4l; // rax
__int64 (*v3)(void); // r12
v0->vReg7 = *(_WORD *)&v0->vm_op->r1l;
v0->v_tmp = v0->vm_op->r0;
*((_BYTE *)&v0->v_RAX + v0->v_tmp) -= **(_BYTE **)((char *)&v0->v_RAX + (unsigned __int16)v0->vReg7);
v1 = __readeflags();
r4l = v0->vm_op->r4l;
if ( (_BYTE)r4l )
{
LOWORD(r4l) = *(_WORD *)&v0->vm_op->r2l;
*(_QWORD *)((char *)&v0->v_RAX + r4l) = v1;
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r3l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4h);
return v3();
}
__int64 __fastcall handler_vSub_Reg8_Reg8()
{
vm_context *v0; // rbp
unsigned __int64 v1; // kr00_8
__int64 r4l; // rsi
__int64 (*v3)(void); // rbx
v0->v_tmp = v0->vm_op->r0;
v0->vReg7 = *(_WORD *)&v0->vm_op->r1l;
*((_BYTE *)&v0->v_RAX + v0->v_tmp) -= *(_QWORD *)((char *)&v0->v_RAX + (unsigned __int16)v0->vReg7);
v1 = __readeflags();
r4l = v0->vm_op->r4l;
if ( (_BYTE)r4l )
{
LOWORD(r4l) = *(_WORD *)&v0->vm_op->r2l;
*(_QWORD *)((char *)&v0->v_RAX + r4l) = v1;
}
v3 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r3l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4h);
return v3();
}
__int64 __fastcall handler_vXor_Reg32_Reg32()
{
vm_context *v0; // rbp
_DWORD *v1; // r14
unsigned __int64 v2; // kr00_8
__int64 r4l; // rsi
__int64 (*v4)(void); // rbx
v0->v_tmp = v0->vm_op->r0;
v0->vReg7 = *(_WORD *)&v0->vm_op->r1l;
v1 = (_DWORD *)((char *)v0 + v0->v_tmp);
*v1 ^= *(_QWORD *)((char *)&v0->v_RAX + (unsigned __int16)v0->vReg7);
v2 = __readeflags();
v1[1] = 0;
r4l = v0->vm_op->r4l;
if ( (_BYTE)r4l )
{
LOWORD(r4l) = *(_WORD *)&v0->vm_op->r2l;
*(_QWORD *)((char *)&v0->v_RAX + r4l) = v2;
}
v4 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r3l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r4h);
return v4();
}
可以见得,Themida影响标志位的这些handler都是会先保存Flag,然后由op中的操作码决定是否舍弃,如果不舍弃就保存进vRFL,当然vRFL的位置也是从操作码中拿来的,可能是这个VM比较简单,所以未进行寄存器轮转。
vAddSp
__int64 __fastcall handler_vAddSp()
{
vm_context *v0; // rbp
_QWORD *v1; // r8
__int64 (*v2)(void); // r15
v1 = (_QWORD *)((char *)&v0->v_RAX + *(unsigned __int16 *)((char *)&v0->vm_op->r0 + 1));
*v1 += v0->vm_op->r0; // 虚拟寄存器与实际寄存器sp同时加
v2 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r1h];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r2h);
return v2();
}
这个handler其实是在所有vPOP结束后,把在VM_init推入栈上的两个立即数给POP掉的一个小trick,这两个操作数与VM内部无关,也算是维护栈平衡的handler。
vLoadSegmentAddr
__int64 __fastcall handler_vLoadSegmentAddr()
{
vm_context *v0; // rbp
__int64 (*v1)(void); // rsi
*(_QWORD *)((char *)&v0->v_RAX + v0->vm_op->r0) = v0->start_Of_Themida_Segment;
v1 = v0->handler_table[*(unsigned __int16 *)&v0->vm_op->r1l];
v0->vm_op = (insn_ctx *)((char *)v0->vm_op + *(int *)&v0->vm_op->r2l);
return v1();
}
这个handler意义明确,用于把程序的.themida段开头的虚拟地址推入一个由operand决定的虚拟寄存器中。
vClear_vmCtx
__int64 __fastcall handler_clear_vmCtx()
{
vm_context *vm_ctx; // rbp
__int64 r0; // r14
// 清空VMContext,并且把所有寄存器(已经保存在栈上)数据清理掉
vm_ctx->vReg0 = 0;
vm_ctx->vReg1 = 0;
vm_ctx->vReg2 = 0;
vm_ctx->vReg3_dword = 0;
vm_ctx->vReg4 = 0;
vm_ctx->vReg7 = 0;
vm_ctx->v_tmp = 0;
vm_ctx->vReg9 = 0;
vm_ctx->vReg6 = 0;
vm_ctx->vReg5 = 0;
vm_ctx->vField1 = 0;
r0 = vm_ctx->vm_op->r0;
vm_ctx->vm_op = (insn_ctx *)((char *)vm_ctx->vm_op + *(int *)&vm_ctx->vm_op->r1l);
return vm_ctx->handler_table[r0]();
}
这个handler一般在vJCC后执行或者在VM_init之后执行,用于清空VM内的内部寄存器值,可能是为了防追踪。
vSaveSP
__int64 __fastcall handler_save_rsp()
{
vm_context *vm_ctx; // rbp
__int64 v1; // rcx
_UNKNOWN *retaddr; // [rsp+58h] [rbp+0h] BYREF
*(_QWORD *)((char *)&vm_ctx->v_RAX + vm_ctx->vm_op->r0) = &retaddr;// Save RSP
v1 = *(unsigned __int16 *)&vm_ctx->vm_op->r1l;
vm_ctx->vm_op = (insn_ctx *)((char *)vm_ctx->vm_op + *(int *)&vm_ctx->vm_op->r2l);
return vm_ctx->handler_table[v1]();
}
这个函数直接把rsp指针保存在由Operand决定的寄存器中,因为直接vPOP rsp会出现一些问题。
VM_Exit
VM_Exit 是一个特殊的Handler,用于退出VM。
Themida并不是所有指令都可以进行虚拟化,比如含有mm,xmm,ymm等的SSE指令,还有cmova这类的条件mov指令没有进行虚拟化,这类操作需要在VM外进行操作。基本操作就是VM->VM_EXIT->无法虚拟化的指令->重新进入VM(需要走带局部混淆的VM_init,重新保存所有寄存器的状态)。
由于进行了bp寄存器的POP操作,栈不平衡,所以报错,我们同时给出汇编
.themida:00000001400567FD
.themida:00000001400567FD ; =============== S U B R O U T I N E =======================================
.themida:00000001400567FD
.themida:00000001400567FD
.themida:00000001400567FD handler_vm_jmp_unvirtualized_code proc near
.themida:00000001400567FD
.themida:00000001400567FD var_10 = qword ptr -10h
.themida:00000001400567FD var_8 = qword ptr -8
.themida:00000001400567FD
.themida:00000001400567FD mov rbx, rbp
.themida:0000000140056800 add rbx, 0B2h
.themida:0000000140056807 mov rbx, [rbx]
.themida:000000014005680A add rbx, 0
.themida:0000000140056811 mov al, [rbx]
.themida:0000000140056813 cmp al, 1
.themida:0000000140056815 jz loc_140056828
.themida:000000014005681B cmp al, 2
.themida:000000014005681D jz loc_140056828
.themida:0000000140056823 jmp loc_140056968
.themida:0000000140056828 ; ---------------------------------------------------------------------------
.themida:0000000140056828
.themida:0000000140056828 loc_140056828: ; CODE XREF: handler_vm_jmp_unvirtualized_code+18↑j
.themida:0000000140056828 ; handler_vm_jmp_unvirtualized_code+20↑j
.themida:0000000140056828 mov rbx, rbp
.themida:000000014005682B add rbx, 0B2h
.themida:0000000140056832 mov rbx, [rbx]
.themida:0000000140056835 add rbx, 7
.themida:000000014005683C mov eax, [rbx]
.themida:000000014005683E mov rbx, rbp
.themida:0000000140056841 add rbx, 0BBh
.themida:0000000140056848 add rax, [rbx]
.themida:000000014005684B mov rbx, rbp
.themida:000000014005684E add rbx, 0B2h
.themida:0000000140056855 mov rbx, [rbx]
.themida:0000000140056858 add rbx, 1
.themida:000000014005685F movzx r8d, byte ptr [rbx]
.themida:0000000140056863 mov rbx, rbp
.themida:0000000140056866 add rbx, 0B2h
.themida:000000014005686D mov rbx, [rbx]
.themida:0000000140056870 add rbx, 3
.themida:0000000140056877 mov r14d, [rbx]
.themida:000000014005687A mov rbx, rbp
.themida:000000014005687D add rbx, 0BBh
.themida:0000000140056884 add r14, [rbx]
.themida:0000000140056887 add r8, rax
.themida:000000014005688A mov r8, [r8]
.themida:000000014005688D cmp r8, r14
.themida:0000000140056890 jz loc_140056968
.themida:0000000140056896 mov rbx, rbp
.themida:0000000140056899 add rbx, 0BBh
.themida:00000001400568A0 mov rax, [rbx]
.themida:00000001400568A3 mov rbx, rbp
.themida:00000001400568A6 add rbx, 0B2h
.themida:00000001400568AD mov rbx, [rbx]
.themida:00000001400568B0 add rbx, 1
.themida:00000001400568B7 movzx r8d, byte ptr [rbx]
.themida:00000001400568BB mov rbx, rbp
.themida:00000001400568BE add rbx, 0B2h
.themida:00000001400568C5 mov rbx, [rbx]
.themida:00000001400568C8 add rbx, 7
.themida:00000001400568CF add r8d, [rbx]
.themida:00000001400568D2 add r8, rax
.themida:00000001400568D5 mov rbx, rbp
.themida:00000001400568D8 add rbx, 0CBh
.themida:00000001400568DF mov r14, [rbx]
.themida:00000001400568E2 sub [r8], r14
.themida:00000001400568E5 mov rbx, rbp
.themida:00000001400568E8 add rbx, 0BBh
.themida:00000001400568EF mov r14, [rbx]
.themida:00000001400568F2 add [r8], r14
.themida:00000001400568F5 mov rbx, rbp
.themida:00000001400568F8 add rbx, 0B2h
.themida:00000001400568FF mov rbx, [rbx]
.themida:0000000140056902 add rbx, 0
.themida:0000000140056909 mov r8b, [rbx]
.themida:000000014005690C cmp r8b, 2
.themida:0000000140056910 jnz loc_140056968
.themida:0000000140056916 mov rbx, rbp
.themida:0000000140056919 add rbx, 0B2h
.themida:0000000140056920 mov rbx, [rbx]
.themida:0000000140056923 add rbx, 2
.themida:000000014005692A movzx r8d, byte ptr [rbx]
.themida:000000014005692E mov rbx, rbp
.themida:0000000140056931 add rbx, 0B2h
.themida:0000000140056938 mov rbx, [rbx]
.themida:000000014005693B add rbx, 7
.themida:0000000140056942 add r8d, [rbx]
.themida:0000000140056945 add r8, rax
.themida:0000000140056948 mov rbx, rbp
.themida:000000014005694B add rbx, 0CBh
.themida:0000000140056952 mov r14, [rbx]
.themida:0000000140056955 sub [r8], r14
.themida:0000000140056958 mov rbx, rbp
.themida:000000014005695B add rbx, 0BBh
.themida:0000000140056962 mov r14, [rbx]
.themida:0000000140056965 add [r8], r14
.themida:0000000140056968
.themida:0000000140056968 loc_140056968: ; CODE XREF: handler_vm_jmp_unvirtualized_code+26↑j
.themida:0000000140056968 ; handler_vm_jmp_unvirtualized_code+93↑j ...
.themida:0000000140056968 mov r11, rbp
.themida:000000014005696B add r11, 0EBh
.themida:0000000140056972 mov r12, [r11]
.themida:0000000140056975 mov qword ptr [r12], 0
.themida:000000014005697D mov rax, 0
.themida:0000000140056984 mov r15, rbp
.themida:0000000140056987 add r15, 0B2h
.themida:000000014005698E mov r15, [r15]
.themida:0000000140056991 add r15, 7
.themida:0000000140056998 mov eax, [r15]
.themida:000000014005699B mov r11, rbp
.themida:000000014005699E add r11, 0BBh
.themida:00000001400569A5 add rax, [r11]
.themida:00000001400569A8 mov rdx, 0
.themida:00000001400569AF mov r13, rbp
.themida:00000001400569B2 add r13, 0B2h
.themida:00000001400569B9 mov r13, [r13+0]
.themida:00000001400569BD add r13, 0Bh
.themida:00000001400569C4 mov dx, [r13+0]
.themida:00000001400569C9 add rdx, rsp
.themida:00000001400569CC mov [rdx], rax
.themida:00000001400569CF mov r8, rbp
.themida:00000001400569D2 add r8, 0D3h
.themida:00000001400569D9 mov dword ptr [r8], 0
.themida:00000001400569E0 pop r8
.themida:00000001400569E2 pop r9
.themida:00000001400569E4 pop r10
.themida:00000001400569E6 pop r11
.themida:00000001400569E8 pop r12
.themida:00000001400569EA pop r13
.themida:00000001400569EC pop r14
.themida:00000001400569EE pop r15
.themida:00000001400569F0 pop rdi
.themida:00000001400569F1 pop rsi
.themida:00000001400569F2 pop rbp
.themida:00000001400569F3 pop rbx
.themida:00000001400569F4 pop rdx
.themida:00000001400569F5 pop rcx
.themida:00000001400569F6 pop rax
.themida:00000001400569F7 popfq
.themida:00000001400569F8 retn 0
// positive sp value has been detected, the output may be wrong!
__int64 __fastcall handler_vm_jmp_unvirtualized_code()
{
vm_context *vm_ctx; // rbp
char r0; // al
QWORD module_base; // rax
_QWORD *v3; // r8
_QWORD *v4; // r8
__int64 result; // rax
_BYTE v6[112]; // [rsp-28h] [rbp-80h]
__int64 v7; // [rsp+48h] [rbp-10h]
unsigned __int64 v8; // [rsp+50h] [rbp-8h]
r0 = vm_ctx->vm_op->r0;
if ( (r0 == 1 || r0 == 2)
&& *(_QWORD *)(vm_ctx->module_base + *(unsigned int *)&vm_ctx->vm_op->r3h + HIBYTE(vm_ctx->vm_op->r0)) != vm_ctx->module_base + *(unsigned int *)&vm_ctx->vm_op->r1h )
{
module_base = vm_ctx->module_base;
v3 = (_QWORD *)(module_base + *(_DWORD *)&vm_ctx->vm_op->r3h + (unsigned int)HIBYTE(vm_ctx->vm_op->r0));
*v3 -= vm_ctx->gap_unk3;
*v3 += vm_ctx->module_base;
if ( vm_ctx->vm_op->r0 == 2 )
{
v4 = (_QWORD *)(module_base + *(_DWORD *)&vm_ctx->vm_op->r3h + (unsigned int)vm_ctx->vm_op->r1l);
*v4 -= vm_ctx->gap_unk3;
*v4 += vm_ctx->module_base;
}
}
*(_QWORD *)vm_ctx->process_heap = 0LL;
*(_QWORD *)&v6[*(unsigned __int16 *)&vm_ctx->vm_op->r5h] = vm_ctx->module_base + *(unsigned int *)&vm_ctx->vm_op->r3h;
vm_ctx->mutex_lock = 0;
result = v7;
__writeeflags(v8);
return result; // VM_EXIT
}
可以看出,handler_vm_jmp_unvirtualized_code(这是一种VM_Exit)负责读取操作数r0,r3h并且进行一系列的判断操作与计算返回值的操作后,POP
还有一种VM_Exit,是为了CALL外部未VM的API,如下
.themida:0000000140062E41 ; =============== S U B R O U T I N E =======================================
.themida:0000000140062E41
.themida:0000000140062E41
.themida:0000000140062E41 handler_vm_exit_call_external proc near
.themida:0000000140062E41
.themida:0000000140062E41 var_10 = qword ptr -10h
.themida:0000000140062E41 var_8 = qword ptr -8
.themida:0000000140062E41
.themida:0000000140062E41 mov rsi, rbp
.themida:0000000140062E44 add rsi, 0EBh
.themida:0000000140062E4B mov rbx, [rsi]
.themida:0000000140062E4E mov qword ptr [rbx], 0
.themida:0000000140062E55 mov r13, 0
.themida:0000000140062E5C mov rsi, rbp
.themida:0000000140062E5F add rsi, 0B2h
.themida:0000000140062E66 mov rsi, [rsi]
.themida:0000000140062E69 add rsi, 6
.themida:0000000140062E70 mov r13d, [rsi]
.themida:0000000140062E73 mov r11, rbp
.themida:0000000140062E76 add r11, 0BBh
.themida:0000000140062E7D add r13, [r11]
.themida:0000000140062E80 mov rsi, 0
.themida:0000000140062E87 mov rdi, rbp
.themida:0000000140062E8A add rdi, 0B2h
.themida:0000000140062E91 mov rdi, [rdi]
.themida:0000000140062E94 add rdi, 4
.themida:0000000140062E9B mov si, [rdi]
.themida:0000000140062E9E add rsi, rsp
.themida:0000000140062EA1 mov [rsi], r13
.themida:0000000140062EA4 add rsi, 8
.themida:0000000140062EAB mov rbx, 0
.themida:0000000140062EB2 mov r12, rbp
.themida:0000000140062EB5 add r12, 0B2h
.themida:0000000140062EBC mov r12, [r12]
.themida:0000000140062EC0 add r12, 0
.themida:0000000140062EC7 mov ebx, [r12]
.themida:0000000140062ECB mov rdx, rbp
.themida:0000000140062ECE add rdx, 0BBh
.themida:0000000140062ED5 add rbx, [rdx]
.themida:0000000140062ED8 mov [rsi], rbx
.themida:0000000140062EDB mov r13, rbp
.themida:0000000140062EDE add r13, 0D3h
.themida:0000000140062EE5 mov dword ptr [r13+0], 0
.themida:0000000140062EED pop r8
.themida:0000000140062EEF pop r9
.themida:0000000140062EF1 pop r10
.themida:0000000140062EF3 pop r11
.themida:0000000140062EF5 pop r12
.themida:0000000140062EF7 pop r13
.themida:0000000140062EF9 pop r14
.themida:0000000140062EFB pop r15
.themida:0000000140062EFD pop rdi
.themida:0000000140062EFE pop rsi
.themida:0000000140062EFF pop rbp
.themida:0000000140062F00 pop rbx
.themida:0000000140062F01 pop rdx
.themida:0000000140062F02 pop rcx
.themida:0000000140062F03 pop rax
.themida:0000000140062F04 popfq
.themida:0000000140062F05 retn 0
.themida:0000000140062F05 handler_vm_exit_call_external endp ; sp-analysis failed
.themida:0000000140062F05
.themida:0000000140062F05 ; ---------------------------------------------------------------------------
// positive sp value has been detected, the output may be wrong!
__int64 __fastcall handler_vm_exit_call_external()
{
vm_context *v0; // rbp
_QWORD *v1; // rsi
__int64 result; // rax
_BYTE v3[112]; // [rsp-28h] [rbp-80h] BYREF
__int64 v4; // [rsp+48h] [rbp-10h]
unsigned __int64 v5; // [rsp+50h] [rbp-8h]
*(_QWORD *)v0->process_heap = 0LL;
v1 = &v3[*(unsigned __int16 *)&v0->vm_op->r2l];
*v1 = v0->module_base + *(unsigned int *)&v0->vm_op->r3l;
v1[1] = v0->module_base + *(unsigned int *)v0->vm_op;
v0->mutex_lock = 0; // 清理掉lock,保证vm退出
result = v4;
__writeeflags(v5);
return result;
}
VM->VM_Exit_Call_External->memcmp(例)->VM_init
Trace
我们采用X64dbg Log进行Trace,同时下断memcmp与cout进行观察。
stage [0, std::cin]
Breakpoint disabled!
Breakpoint disabled!
Breakpoint disabled!
Breakpoint disabled!
================================
handler_vm_init
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg32(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg6)
handler_vMov_Reg64_tmd_segment()
handler_vMov_Reg32_Reg32(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg64_Imm32(vReg4, 0x9F37)
handler_vAdd_Reg64_Reg64(vReg4, vReg6, saveRFL=C3, RFL->vReg8)
handler_vPush_Reg64(vReg2)
handler_vCmp_mReg8_Imm8([vReg4], 0x0, saveRFL=19, RFL->vReg8)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 9)
handler_vMov_Reg64_mReg64(vReg2, [vReg17])
handler_vPush_Reg64(vReg4)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg4, vReg17)
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=yes)
================================
handler_clear_vmCtx
handler_vPOP_Reg64(vReg4)
handler_vMov_mReg8_Imm8(vReg4, 0xB7)
================================
handler_clear_vmCtx
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg2, vReg17)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 32)
handler_vMov_mReg64_Reg64([vReg17], vReg2)
handler_vMov_Reg64_Imm32(vReg2, 0x1)
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg4)
handler_vPOP_RFL(vReg8)
handler_vPOP_Reg64(vReg3)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=387)
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vAdd_Reg64_Imm32(vReg17, 7712)
handler_vMov_Reg_mReg(vReg2, [vReg17])
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=605)
handler_vm_jmp_unvirtualized_code
=========================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=605)
handler_vm_jmp_unvirtualized_code
=========================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 64)
handler_vMov_mReg64_Imm32(vReg17, 0x0)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 72)
handler_vMov_mReg64_Imm32(vReg17, 0xF)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 48)
handler_vMov_mReg8_Imm8(vReg17, 0xD5)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 48)
handler_vMov_Reg32_Reg32(vReg3, vReg17)
handler_vAdd_Reg64_Imm32(vReg17, 7640)
handler_vMov_Reg_mReg(vReg2, [vReg17])
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
可以观察到,trace中的
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x19, saveRFL=165, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD6, saveRFL=51, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=CB, RFL->vReg8)
handler_op_branch(op+abs(248))
================================
是一个循环,这其实是Themida的字符串解密流程,解密"Input Your Flag:"字段,可见解密就是简单的xor+add。
解密后,通过 handler_vm_exit_call_external 输出上面的字符,并且通过这个handler调用std::cin,接收用户输入。
stage (std::cin, memcmp]
我们输入 flag{fake_flag} 继续trace。
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 48)
handler_vMov_Reg32_Reg32(vReg2, vReg17)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 48)
handler_vMov_Reg_mReg(vReg1, [vReg17])
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 72)
handler_vMov_Reg_mReg(vReg5, [vReg17])
handler_vCmp_Reg_Imm32(vReg5, 15)
handler_vCmp_Reg_Imm32(RFL->vReg8)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=605)
handler_vm_jmp_unvirtualized_code
=========================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 64)
handler_vCmp_mReg32_Imm32([vReg17], 0xF, saveRFL=A9, RFL->vReg8)
handler_check_RFL(operand=0xC7)
handler_check_RFL(jump=no)
handler_vMov_Reg64_Imm32(vReg9, 0xF)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg32(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg6)
handler_vMov_Reg64_tmd_segment()
handler_vMov_Reg32_Reg32(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg64_Imm32(vReg4, 0x4AE87)
handler_vAdd_Reg64_Reg64(vReg4, vReg6, saveRFL=CB, RFL->vReg8)
handler_vPush_Reg64(vReg2)
handler_vCmp_mReg8_Imm8([vReg4], 0x0, saveRFL=F9, RFL->vReg8)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 9)
handler_vMov_Reg64_mReg64(vReg2, [vReg17])
handler_vPush_Reg64(vReg4)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg4, vReg17)
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0x13, saveRFL=141, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0x29, saveRFL=3D, RFL->vReg8)
handler_vInc_Reg64(vReg4)
handler_vDec_Reg32(vReg2, saveRFL=BD, RFL->vReg8)
handler_op_branch(op+abs(30))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=yes)
================================
handler_clear_vmCtx
handler_vPOP_Reg64(vReg4)
handler_vMov_mReg8_Imm8(vReg4, 0xB7)
================================
handler_clear_vmCtx
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg2, vReg17)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 32)
handler_vMov_mReg64_Reg64([vReg17], vReg2)
handler_vMov_Reg64_Imm32(vReg2, 0x1)
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg4)
handler_vPOP_RFL(vReg8)
handler_vPOP_Reg64(vReg3)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=387)
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg8_Reg8(vReg3, vReg3)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
INT3 breakpoint at <vcruntime140.memcmp> (00007FFB1D6C2080)!
我们同样看到了字符串解密的操作,并且解密后进行memcmp,其实是解密正确的flag字符串,与用户输入一同传入memcmp函数。
由于我们输入的值,memcmp应返回 0xffffffff 而不是 0,过了memcmp,VM就应该来验证eax是否等于0,如果是0则跳转到right的node,否则就是输入错误。
所以我们下来只要关心vReg0相关的判断即可。
stage (memcmp, std::cout]
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vTest_reg32_reg32(vReg0, vReg0, saveRFL=1, RFL->vReg8)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg32(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg6)
handler_vMov_Reg64_tmd_segment()
handler_vMov_Reg32_Reg32(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg64_Imm32(vReg4, 0xE3C7)
handler_vAdd_Reg64_Reg64(vReg4, vReg6, saveRFL=65, RFL->vReg8)
handler_vPush_Reg64(vReg2)
handler_vCmp_mReg8_Imm8([vReg4], 0x0, saveRFL=9B, RFL->vReg8)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 9)
handler_vMov_Reg64_mReg64(vReg2, [vReg17])
handler_vPush_Reg64(vReg4)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg4, vReg17)
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0xDC, saveRFL=179, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD, saveRFL=11, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=F3, RFL->vReg8)
handler_op_branch(op+abs(2147483859))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0xDC, saveRFL=179, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD, saveRFL=11, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=F3, RFL->vReg8)
handler_op_branch(op+abs(2147483859))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0xDC, saveRFL=179, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD, saveRFL=11, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=F3, RFL->vReg8)
handler_op_branch(op+abs(2147483859))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0xDC, saveRFL=179, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD, saveRFL=11, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=F3, RFL->vReg8)
handler_op_branch(op+abs(2147483859))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vXor_mReg8_Imm8([vReg4], 0xDC, saveRFL=179, RFL->vReg8)
handler_vAdd_mReg8_Imm8([vReg4], 0xD, saveRFL=11, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=F3, RFL->vReg8)
handler_op_branch(op+abs(2147483859))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=yes)
================================
handler_clear_vmCtx
handler_vPOP_Reg64(vReg4)
handler_vMov_mReg8_Imm8(vReg4, 0xB7)
================================
handler_clear_vmCtx
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg2, vReg17)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 32)
handler_vMov_mReg64_Reg64([vReg17], vReg2)
handler_vMov_Reg64_Imm32(vReg2, 0x1)
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg4)
handler_vPOP_RFL(vReg8)
handler_vPOP_Reg64(vReg3)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=387)
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg8_Reg8(vReg1, vReg1)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
================================
handler_clear_vmCtx
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg32(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg6)
handler_vMov_Reg64_tmd_segment()
handler_vMov_Reg32_Reg32(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg64_Imm32(vReg4, 0x33137)
handler_vAdd_Reg64_Reg64(vReg4, vReg6, saveRFL=F5, RFL->vReg8)
handler_vPush_Reg64(vReg2)
handler_vCmp_mReg8_Imm8([vReg4], 0x0, saveRFL=AD, RFL->vReg8)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 9)
handler_vMov_Reg64_mReg64(vReg2, [vReg17])
handler_vPush_Reg64(vReg4)
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg4, vReg17)
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vAdd_mReg8_Imm8([vReg4], 0x4A, saveRFL=65, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=C3, RFL->vReg8)
handler_op_branch(op+abs(2147483794))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vAdd_mReg8_Imm8([vReg4], 0x4A, saveRFL=65, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=C3, RFL->vReg8)
handler_op_branch(op+abs(2147483794))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vAdd_mReg8_Imm8([vReg4], 0x4A, saveRFL=65, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=C3, RFL->vReg8)
handler_op_branch(op+abs(2147483794))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vAdd_mReg8_Imm8([vReg4], 0x4A, saveRFL=65, RFL->vReg8)
handler_vDec_Reg32(vReg2, saveRFL=C3, RFL->vReg8)
handler_op_branch(op+abs(2147483794))
================================
handler_clear_vmCtx
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=yes)
================================
handler_clear_vmCtx
handler_vPOP_Reg64(vReg4)
handler_vMov_mReg8_Imm8(vReg4, 0xB7)
================================
handler_clear_vmCtx
handler_vMov_Reg32_Reg32(vReg17, vReg4)
handler_vAdd_Reg64_Imm32(vReg17, 25)
handler_vMov_Reg32_Reg32(vReg2, vReg17)
handler_vMov_Reg32_Reg32(vReg17, vReg7)
handler_vAdd_Reg64_Imm32(vReg17, 32)
handler_vMov_mReg64_Reg64([vReg17], vReg2)
handler_vMov_Reg64_Imm32(vReg2, 0x1)
handler_vTest_reg32_reg32(vReg2, vReg2, saveRFL=0, RFL->vReg23)
handler_check_RFL(operand=0xCB)
handler_check_RFL(jump=no)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg4)
handler_vPOP_RFL(vReg8)
handler_vPOP_Reg64(vReg3)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vMov_Reg8_Reg8(vReg0, vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=387)
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vMov_Reg8_Reg8(vReg2, vReg2)
================================
handler_clear_vmCtx
handler_vAdd_Reg64_Imm32(vReg17, 7585)
handler_vMov_Reg_mReg(vReg2, [vReg17])
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=82)
handler_vm_exit_call_external
================================
================================
handler_clear_vmCtx
handler_save_rsp
handler_vPOP_Reg64(vReg9)
handler_vPOP_Reg64(vReg10)
handler_vPOP_Reg64(vReg11)
handler_vPOP_Reg64(vReg12)
handler_vPOP_Reg64(vReg13)
handler_vPOP_Reg64(vReg14)
handler_vPOP_Reg64(vReg15)
handler_vPOP_Reg64(vReg16)
handler_vPOP_Reg64(vReg5)
handler_vPOP_Reg64(vReg4)
handler_vPOP_Reg64(vReg6)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg1)
handler_vPOP_Reg64(vReg3)
handler_vPOP_Reg64(vReg2)
handler_vPOP_Reg64(vReg0)
handler_vPOP_RFL(vReg8)
handler_vAddSp_Imm16(vReg7, 16)
handler_vPush_Reg64(vReg0)
handler_vPush_RFL(vReg7)
handler_vPush_Reg64(vReg0)
handler_vPush_Reg64(vReg2)
handler_vPush_Reg64(vReg3)
handler_vPush_Reg64(vReg1)
handler_vPush_Reg64(vReg6)
handler_vPush_Reg64(vReg4)
handler_vPush_Reg64(vReg5)
handler_vPush_Reg64(vReg16)
handler_vPush_Reg64(vReg15)
handler_vPush_Reg64(vReg14)
handler_vPush_Reg64(vReg13)
handler_vPush_Reg64(vReg12)
handler_vPush_Reg64(vReg11)
handler_vPush_Reg64(vReg10)
handler_vPush_Reg64(vReg9)
handler_JMP(node=145)
handler_vm_exit()
exit-> mov dl, dl
INT3 breakpoint at themida_test_protected.000000014000136A!
注意到关键Handler handler_vTest_reg32_reg32(vReg0, vReg0, saveRFL=1, RFL->vReg8),这就是在判断vReg0是否为0。
随后,我们就可以定位到关键跳转
这样我们就做到了简单的JCC爆破。
后续
本系列未完结。后面会出相关算法逆向,VM还原的文章,敬请期待。
相关附件邮件联系我并说明来意。