程序中能搜到flag字符串,跟到主函数。加密分几部分
1,输入的数据位置交换。怎么换的函数都太复杂了,ida跟进去后输入0123…得到一个顺序变化的串,并没有加密内容只是交换位置
v1 = sub_13F5F1280(&v13);
v2 = name;
if ( v1 )
{
sub_13F5F15C0((unsigned __int8 *)v1[1]);
sub_13F5F15C0(*(unsigned __int8 **)(v3 + 16));
v4 = dword_13F5F57E0;
v2[v4] = *v5;
dword_13F5F57E0 = v4 + 1;
}
2,反修饰。由于这是个标准函数,也就用不碰上看内容了——没有,从网上搜。比如一个修饰好的串反修饰后会变成 public char * abc::def(int)这样的常用样式。
UnDecorateSymbolName(v2, outputString, 0x100u, 0);
3,查表加密,两个码表都已经给出了,直接逆向即可。
do
{
v11 = outputString[v10];
v12 = v11 % 23;
if ( a1234567890Qwer[v12] != *(_BYTE *)(v10 + 0x13F5F3478i64) )
_exit(v9);
if ( a1234567890Qwer[v11 / 23] != *(_BYTE *)(v10 + 0x13F5F3438i64) )
_exit(v9 * v9);
++v9;
++v10;
}
while ( v9 < 62 );
4,最后告诉flag的得到方法是md5
解密程序
a3438 = '55565653255552225565565555243466334653663544426565555525555222'
a3478 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&'
qwer = '1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;\'ASDFGHJKL:"ZXCVBNM<>?zxcvbnm,./'
ostr = ''
for i in range(62):
for j in range(256):
if qwer[j%23] == a3478[i] and qwer[j//23] == a3438[i]:
ostr +=chr(j)
break
print(ostr)
#'private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)'
'''
UnDecorateSymbolName(v2, outputString, 0x100u, 0);
c++函数名的修饰
v2 = ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
? 修饰开始
My_Aut0_PWN@R0Pxx 类及成员函数
@@AAE 成员类型 public @@QAE private @@AAE protected @@IAE
PAD 参数返回值char * (*:PA,const:PB,void:X,char:D,unsigned char:E,short:F,int:H,unsigned int:I,long:J,unsigned long:K,float:M,double:N,bool:_N,struct:U)
PAE 参数1 unsigned char *
@Z 结束标志
手工按给定的名称进行修饰
'''
v2 = '?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z'
s = '0123456789abcdefghijklmnopqrstu'
t = 'fg7hi83jk9lma41nobpqc5rsdtue620'
st = [t.index(i) for i in s]
print(st)
flag = ['']*len(v2)
for i,v in enumerate(st):
flag[i] = v2[v]
flag = ''.join(flag)
print(flag)
#Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP
form hashlib import md5
print('flag{'+md5(flag.encode()).hexdigest()+'}')
#flag{63b148e750fed3a33419168ac58083f5}
版权声明:本文为weixin_52640415原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。