查看strings window,看到字符串“correct”和“wrong“,猜测字符串所在的位置就是我们要分分析的内容。
反编译代码发现代码有点乱,因为大部分变量名是没有意义的,是很难读懂的。经过分析后,我重新命名了部分函数名,使其变得可读:
int sub_400BC8()
{
int result; // $v0
int len; // [sp+18h] [+18h]
unsigned __int8 *v2; // [sp+1Ch] [+1Ch]
char v3[100]; // [sp+20h] [+20h] BYREF
int v4; // [sp+84h] [+84h]
v4 = dword_49E990;
printf("please input your flag:");
((void (*)(const char *, ...))scanf)("%s", v3);
len = length(v3);
encrpyt(v3);
v2 = (unsigned __int8 *)newbase64(v3, len);
if ( compare(v2, "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ==") )
{
put("wrong!");
result = -1;
}
else
{
put("correct!");
result = 0;
}
if ( v4 != dword_49E990 )
sub_420350();
return result;
}
BOOL __fastcall encrpyt(char *a1)
{
BOOL result; // $v0
unsigned int i; // [sp+1Ch] [+1Ch]
int v3; // [sp+20h] [+20h]
int v4; // [sp+24h] [+24h]
unsigned __int8 v5; // [sp+2Bh] [+2Bh]
((void (__fastcall *)())init_tab)();
v4 = 0;
v3 = 0;
for ( i = 0; ; ++i )
{
result = i < length(a1);
if ( !result )
break;
v3 = (v3 + 1) % 256;
v4 = (tab[v3] + v4) % 256;
v5 = tab[v3];
tab[v3] = tab[v4];
tab[v4] = v5;
a1[i] ^= tab[(unsigned __int8)(tab[v3] + tab[v4])];
}
return result;
这样就很清晰,首先对输入进行加密(encrypt),然后在通过一个修改过的Base64函数(仅仅是修改了表的顺序,这个解密方法我在做mobile easyjni那篇博客上有具体步骤,这里不详细解释)。最后做对比。
了解它的基本逻辑,比较费时间分析。但是分析好了,解密就很简单。要做逆向,所以先解密newBase64(下面的fromBase64函数),然后再decrypt。事实上,init_tab和decrypt的逻辑跟反编译后得到的代码(init_tab和encrypt)是一样的,不用修改,直接改写成python就可以了:
import base64
def fromBase64(result):
new="ZYXWVUTSRQPONMLKJIHGFEDCBAabcdefghijklmnopqrstuvwxyz/+9876543210"
ori = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
change = result.translate(str.maketrans(new,ori))
# print("after changing:"+change)
#print(base64.b64decode(change))
return base64.b64decode(change)
def init_tab():
flag= 'flag{123321321123badbeef012}'
aFlag1233213211 = [ord(x) for x in flag]
tab = [i % 256 for i in range(256)]
current_index_in_key_array = 0
index_in_flag = 0
new_index = 0
for current_index_in_key_array in range(256):
current_value = tab[current_index_in_key_array]
new_index = (current_value + new_index + aFlag1233213211[index_in_flag]) % 256
tab[current_index_in_key_array], tab[new_index] = tab[new_index], tab[current_index_in_key_array]
index_in_flag +=1
if index_in_flag >= len(aFlag1233213211):
index_in_flag=0
print(len(tab))
print(tab)
return tab
def decrypt(enc):
dec= []
tab = init_tab()
v3 = 0
v4 = 0
for i in range(len(enc)):
v3 = (v3+1)%256
v4 = (v4+tab[v3])%256
tab[v3],tab[v4] = tab[v4],tab[v3]
sum = tab[(tab[v3]+tab[v4])%256]
dec.append(enc[i]^sum)
#print(dec)
return dec
if __name__ == '__main__':
result = "ScDZC1cNDZaxnh/2eW1UdqaCiJ0ijRIExlvVEgP43rpxoxbYePBhpwHDPJ=="
input = fromBase64(result)
#input = b'\x1d\xc5\x80_\xe7\x0cX\x06\xb1\x9e\x1d=x?\x85v\xa6\x97\x89\x0f\xe2\x8c\x84U\xc6[\xc4V\x02\xbb\xf2\xbaq\xa3\x16\xc1x\xa6!\xa7\x04\x96)'
enc = decrypt(input)
flag = ''.join([chr(x) for x in enc])
print(flag)