下面的代码可知:flag的长度是14,通过judge来判断是否成功。但jugde函数是加密过,也就是代码是被混淆过的。所以不可以直接查看。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[24]; // [rsp+0h] [rbp-20h] BYREF
int v5; // [rsp+18h] [rbp-8h]
int i; // [rsp+1Ch] [rbp-4h]
for ( i = 0; i <= 181; ++i )
*((_BYTE *)judge + i) ^= 0xCu;
printf("Please input flag:");
__isoc99_scanf("%20s", s);
v5 = strlen(s);
if ( v5 == 14 && (unsigned int)judge((__int64)s) )
puts("Right!");
else
puts("Wrong!");
return 0;
}
main函数中有下面这段代码,它是用来还原或解密代码的。
for ( i = 0; i <= 181; ++i )
*((_BYTE *)judge + i) ^= 0xCu;
解决方法有两个:
1. 静态方法
使用脚本还原代码。在File-》script command中输入脚本:
在“run”后,可看到judge的数值已经发生改变。
选择judge,按“c” 然后“p”,得到下面的代码:
.data:0000000000600B00 public judge
.data:0000000000600B00 judge proc near ; CODE XREF: main+80↑p
.data:0000000000600B00 ; DATA XREF: main+16↑r ...
.data:0000000000600B00
.data:0000000000600B00 var_28 = qword ptr -28h
.data:0000000000600B00 var_20 = byte ptr -20h
.data:0000000000600B00 var_1F = byte ptr -1Fh
.data:0000000000600B00 var_1E = byte ptr -1Eh
.data:0000000000600B00 var_1D = byte ptr -1Dh
.data:0000000000600B00 var_1C = byte ptr -1Ch
.data:0000000000600B00 var_1B = byte ptr -1Bh
.data:0000000000600B00 var_1A = byte ptr -1Ah
.data:0000000000600B00 var_19 = byte ptr -19h
.data:0000000000600B00 var_18 = byte ptr -18h
.data:0000000000600B00 var_17 = byte ptr -17h
.data:0000000000600B00 var_16 = byte ptr -16h
.data:0000000000600B00 var_15 = byte ptr -15h
.data:0000000000600B00 var_14 = byte ptr -14h
.data:0000000000600B00 var_13 = byte ptr -13h
.data:0000000000600B00 var_4 = dword ptr -4
.data:0000000000600B00
.data:0000000000600B00 push rbp
.data:0000000000600B01 mov rbp, rsp
.data:0000000000600B04 mov [rbp+var_28], rdi
.data:0000000000600B08 mov [rbp+var_20], 66h ; 'f'
.data:0000000000600B0C mov [rbp+var_1F], 6Dh ; 'm'
.data:0000000000600B10 mov [rbp+var_1E], 63h ; 'c'
.data:0000000000600B14 mov [rbp+var_1D], 64h ; 'd'
.data:0000000000600B18 mov [rbp+var_1C], 7Fh
.data:0000000000600B1C mov [rbp+var_1B], 6Bh ; 'k'
.data:0000000000600B20 mov [rbp+var_1A], 37h ; '7'
.data:0000000000600B24 mov [rbp+var_19], 64h ; 'd'
.data:0000000000600B28 mov [rbp+var_18], 3Bh ; ';'
.data:0000000000600B2C mov [rbp+var_17], 56h ; 'V'
.data:0000000000600B30 mov [rbp+var_16], 60h ; '`'
.data:0000000000600B34 mov [rbp+var_15], 3Bh ; ';'
.data:0000000000600B38 mov [rbp+var_14], 6Eh ; 'n'
.data:0000000000600B3C mov [rbp+var_13], 70h ; 'p'
.data:0000000000600B40 mov [rbp+var_4], 0
.data:0000000000600B47 jmp short loc_600B71
.data:0000000000600B49 ; ---------------------------------------------------------------------------
.data:0000000000600B49
.data:0000000000600B49 loc_600B49: ; CODE XREF: judge+75↓j
.data:0000000000600B49 mov eax, [rbp+var_4]
.data:0000000000600B4C movsxd rdx, eax
.data:0000000000600B4F mov rax, [rbp+var_28]
.data:0000000000600B53 add rax, rdx
.data:0000000000600B56 mov edx, [rbp+var_4]
.data:0000000000600B59 movsxd rcx, edx
.data:0000000000600B5C mov rdx, [rbp+var_28]
.data:0000000000600B60 add rdx, rcx
.data:0000000000600B63 movzx edx, byte ptr [rdx]
.data:0000000000600B66 mov ecx, [rbp+var_4]
.data:0000000000600B69 xor edx, ecx
.data:0000000000600B6B mov [rax], dl
.data:0000000000600B6D add [rbp+var_4], 1
.data:0000000000600B71
.data:0000000000600B71 loc_600B71: ; CODE XREF: judge+47↑j
.data:0000000000600B71 cmp [rbp+var_4], 0Dh
.data:0000000000600B75 jle short loc_600B49
.data:0000000000600B77 mov [rbp+var_4], 0
.data:0000000000600B7E jmp short loc_600BA9
.data:0000000000600B80 ; ---------------------------------------------------------------------------
.data:0000000000600B80
.data:0000000000600B80 loc_600B80: ; CODE XREF: judge+AD↓j
.data:0000000000600B80 mov eax, [rbp+var_4]
.data:0000000000600B83 movsxd rdx, eax
.data:0000000000600B86 mov rax, [rbp+var_28]
.data:0000000000600B8A add rax, rdx
.data:0000000000600B8D movzx edx, byte ptr [rax]
.data:0000000000600B90 mov eax, [rbp+var_4]
.data:0000000000600B93 cdqe
.data:0000000000600B95 movzx eax, [rbp+rax+var_20]
.data:0000000000600B9A cmp dl, al
.data:0000000000600B9C jz short loc_600BA5
.data:0000000000600B9E mov eax, 0
.data:0000000000600BA3 jmp short loc_600BB4
.data:0000000000600BA5 ; ---------------------------------------------------------------------------
.data:0000000000600BA5
.data:0000000000600BA5 loc_600BA5: ; CODE XREF: judge+9C↑j
.data:0000000000600BA5 add [rbp+var_4], 1
.data:0000000000600BA9
.data:0000000000600BA9 loc_600BA9: ; CODE XREF: judge+7E↑j
.data:0000000000600BA9 cmp [rbp+var_4], 0Dh
.data:0000000000600BAD jle short loc_600B80
.data:0000000000600BAF mov eax, 1
.data:0000000000600BB4
.data:0000000000600BB4 loc_600BB4: ; CODE XREF: judge+A3↑j
.data:0000000000600BB4 pop rbp
.data:0000000000600BB5 retn
.data:0000000000600BB5 judge endp
反编译后可得:
__int64 __fastcall judge(__int64 a1)
{
char v2[5]; // [rsp+8h] [rbp-20h] BYREF
char v3[9]; // [rsp+Dh] [rbp-1Bh] BYREF
int i; // [rsp+24h] [rbp-4h]
qmemcpy(v2, "fmcd", 4);
v2[4] = 127;
qmemcpy(v3, "k7d;V`;np", sizeof(v3));
for ( i = 0; i <= 13; ++i )
*(_BYTE *)(i + a1) ^= i;
for ( i = 0; i <= 13; ++i )
{
if ( *(_BYTE *)(i + a1) != v2[i] )
return 0LL;
}
return 1LL;
}
输出flag:
v2='fmcd'+chr(127)+'k7d;V`;np'
flag = ''
for i in range(14):
flag+= chr(ord(v2[i])^i)
print(flag)
方法2:动态方法
在?if ( v5 == 14 && (unsigned int)judge((__int64)s) ) 这行下断点,这时解密方法已经执行,也就是可以跳转到judge函数查看解密后的代码。