题目来源:qsnctf/reverse/flower_tea
直接下载: link

此题目中有一处明显的调用IsDebuggerPresent()的反调试:

.text:00000001400022AA                 call    cs:__imp_IsDebuggerPresent

另外一处隐藏在一个乍一看很像printf的函数(1400021E0)中。如果没有patch掉暗处的,那么很容易认为140001050处的函数就是加密、比较函数,并且此函数非常像是真正的加密函数,但是根据这个函数解出来的是假的flag。
因此,关键在于隐藏在1400021E0函数中的反调试。

.text:00000001400021E0                 sub     rsp, 158h
.text:00000001400021E7                 mov     rax, cs:__security_cookie
.text:00000001400021EE                 xor     rax, rsp
.text:00000001400021F1                 mov     [rsp+158h+var_8], rax
.text:00000001400021F9                 mov     [rsp+158h+var_110], rcx
.text:00000001400021FE                 lea     rax, [rsp+158h+var_110+4]
.text:0000000140002203                 mov     [rsp+158h+var_120], rax
.text:0000000140002208                 mov     rax, [rsp+158h+var_120]
.text:000000014000220D                 mov     [rsp+158h+var_130], rax
.text:0000000140002212                 mov     rcx, [rsp+158h+var_110]
.text:0000000140002217                 call    modify_bytesin1050_to_12A0 
										; modify_bytesin1050_to_12A0函数会改变140001050处的汇编代码,
										; 会改成跳转到1400012A0,这才是真正的加密函数
.text:00000001400020C0 modify_bytesin1050_to_12A0 proc near    ; CODE XREF: sub_1400021E0+37↓p
.text:00000001400020C0                                         ; DATA XREF: .pdata:0000000140008030↓o
.text:00000001400020C0
.text:00000001400020C0 var_38          = qword ptr -38h
.text:00000001400020C0 var_30          = qword ptr -30h
.text:00000001400020C0 Block           = qword ptr -28h
.text:00000001400020C0 var_20          = qword ptr -20h
.text:00000001400020C0 var_18          = qword ptr -18h
.text:00000001400020C0 lpflOldProtect  = dword ptr -0Ch
.text:00000001400020C0 var_8           = qword ptr -8
.text:00000001400020C0
.text:00000001400020C0                 sub     rsp, 58h
.text:00000001400020C4                 mov     rax, cs:__security_cookie
.text:00000001400020CB                 xor     rax, rsp
.text:00000001400020CE                 mov     [rsp+58h+var_8], rax
.text:00000001400020D3                 mov     [rsp+58h+var_20], rcx ; rcx = a_welcometoDRKCTF
.text:00000001400020D8                 xor     ecx, ecx
.text:00000001400020DA                 call    gs__60__debugger_detect
										; gs__60__debugger_detect函数内部:
										;.text:00000001400020A2   mov     rax, gs:[rax]   ; gs:[60] debugger here!
										;.text:00000001400020A6   movsx   eax, byte ptr [rax+2]
.text:00000001400020DF                 cmp     eax, 0
.text:00000001400020E2                 jz      loc_1400020F7   ; must jz
.text:00000001400020E8                 mov     rax, [rsp+58h+var_20]
.text:00000001400020ED                 mov     [rsp+58h+var_18], rax
.text:00000001400020F2                 jmp     loc_1400021B0
.text:00000001400020F7 ; ---------------------------------------------------------------------------
.text:00000001400020F7
.text:00000001400020F7 loc_1400020F7:                          ; CODE XREF: modify_bytesin1050_to_12A0+22↑j
.text:00000001400020F7                 call    sub_140001010
										; 1010函数中,先malloc(0x10)的堆,
										; 前8个字节是0x0000000140001050
										; 后8个字节是0x00000001400012A0
										; 返回值为堆的地址
.text:00000001400020FC                 mov     [rsp+58h+Block], rax ; rax = addr_malloc(0x10)
.text:0000000140002101                 call    sub_140002410
										; 2410函数:取得kernel32.dll中VirtualProtect函数的地址并返回
.text:0000000140002106                 mov     [rsp+58h+var_30], rax
.text:000000014000210B                 mov     rax, [rsp+58h+var_30] ;var_30:&VirtualProtect()
.text:0000000140002110                 mov     rax, [rax]
.text:0000000140002113                 mov     rcx, [rsp+58h+Block]  ;block = addr_malloc(0x10)
.text:0000000140002118                 mov     rcx, [rcx]			 ;rcx = 0x140001050
.text:000000014000211B                 mov     edx, 20h ; ' '
.text:0000000140002120                 mov     r8d, 40h ; '@'		 ;PAGE_EXECUTE_READWRITE
.text:0000000140002126                 lea     r9, [rsp+58h+lpflOldProtect]
.text:000000014000212B                 call    rax             ; VirtualProctect
.text:000000014000212D                 cmp     eax, 0
.text:0000000140002130                 jz      loc_14000219B
.text:0000000140002136                 mov     rax, [rsp+58h+Block]
.text:000000014000213B                 mov     rax, [rax]      ; rax = addr_1050
.text:000000014000213E                 mov     byte ptr [rax], 48h ; 'H'	; 改写!
.text:0000000140002141                 mov     rax, [rsp+58h+Block]
.text:0000000140002146                 mov     rax, [rax]
.text:0000000140002149                 mov     byte ptr [rax+1], 0B8h		; 改写!
.text:000000014000214D                 mov     rax, [rsp+58h+Block]
.text:0000000140002152                 mov     rcx, [rax+8]
.text:0000000140002156                 mov     rax, [rsp+58h+Block]
.text:000000014000215B                 mov     rax, [rax]
.text:000000014000215E                 mov     [rax+2], rcx					; 改写!
.text:0000000140002162                 mov     rax, [rsp+58h+Block]
.text:0000000140002167                 mov     rax, [rax]
.text:000000014000216A                 mov     byte ptr [rax+0Ah], 50h ; 'P'	; 改写!
.text:000000014000216E                 mov     rax, [rsp+58h+Block]
.text:0000000140002173                 mov     rax, [rax]
.text:0000000140002176                 mov     byte ptr [rax+0Bh], 0C3h		; 改写!
.text:000000014000217A                 mov     rax, [rsp+58h+var_30]
.text:000000014000217F                 mov     rax, [rax]
.text:0000000140002182                 mov     r8d, [rsp+58h+lpflOldProtect]
.text:0000000140002187                 mov     rcx, [rsp+58h+Block]
.text:000000014000218C                 mov     rcx, [rcx]
.text:000000014000218F                 mov     edx, 20h ; ' '
.text:0000000140002194                 lea     r9, [rsp+58h+lpflOldProtect]
.text:0000000140002199                 call    rax		;再次调用VirtualProtect函数,恢复
.text:000000014000219B
.text:000000014000219B loc_14000219B:                          ; CODE XREF: modify_bytesin1050_to_12A0+70↑j
.text:000000014000219B                 mov     rcx, [rsp+58h+Block] ; Block
.text:00000001400021A0                 call    cs:__imp_free

之后就是分析12A0函数。

posted on 2025-06-03 14:15  NJyO  阅读(31)  评论(0)    收藏  举报