本文以 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还原的文章,敬请期待。

相关附件邮件联系我并说明来意。