这题是找程序获取到key时运行后输出的结果,很显然2种解法。
解法1:找出正确注册码的算法。
解法2:找出输入正确注册码后输出flag的算法。
这里是后者容易一些。
.text:0045C458 00000005 C pass
.rdata:00508E60 00000043 C Flag in the safe inside, I heard that explosives can be exploded.\n
.rdata:00508EB0 00000030 C No explosives, please enter your password \n ->
.rdata:00508EEC 00000012 C check faild!\n ->
.rdata:00508F08 00000025 C Password can not exceed %d bit \n ->
.rdata:00508F34 00000009 C SYC{%s}\n
.rdata:00508F7C 0000001C C Stack around the variable '
.rdata:00508F98 00000011 C ' was corrupted.
.rdata:00508FAC 0000000F C The variable '
.rdata:00508FBC 0000002B C ' is being used without being initialized.
这是查找到的字符串。SYC{%s}这里是个提示。很可能这里是生成flag的的计算
int sub_45BFF0()
{
int v0; // edx@4
int v1; // ST04_4@4
int v2; // ecx@4
char v4; // [sp+Ch] [bp-134h]@1
int v5; // [sp+10h] [bp-130h]@4
int i; // [sp+DCh] [bp-64h]@1
char v7; // [sp+EBh] [bp-55h]@3
int v8; // [sp+F4h] [bp-4Ch]@1
int v9; // [sp+F8h] [bp-48h]@1
int v10; // [sp+FCh] [bp-44h]@1
int v11; // [sp+100h] [bp-40h]@1
int v12; // [sp+104h] [bp-3Ch]@1
int v13; // [sp+108h] [bp-38h]@1
int v14; // [sp+10Ch] [bp-34h]@1
int v15; // [sp+110h] [bp-30h]@1
int v16; // [sp+11Ch] [bp-24h]@1
int v17; // [sp+120h] [bp-20h]@1
int v18; // [sp+124h] [bp-1Ch]@1
int v19; // [sp+128h] [bp-18h]@1
int v20; // [sp+12Ch] [bp-14h]@1
int v21; // [sp+130h] [bp-10h]@1
int v22; // [sp+134h] [bp-Ch]@1
int v23; // [sp+138h] [bp-8h]@1
int savedregs; // [sp+140h] [bp+0h]@4
memset(&v4, 0xCCu, 0x134u);
v16 = 7;
v17 = 3;
v18 = 1;
v19 = 8;
v20 = 7;
v21 = 2;
v22 = 3;
v23 = 2;
v8 = 18;
v9 = 19;
v10 = 20;
v11 = 1;
v12 = 15;
v13 = 20;
v14 = 16;
v15 = 11;
for ( i = 0; i < 8; ++i )
{
v7 = byte_52E000[*(&v16 + i)];
byte_52E000[*(&v16 + i)] = byte_52E000[*(&v8 + i)];
byte_52E000[*(&v8 + i)] = v7;
}
v5 = 21;
byte_52E000[21] = 0;
sub_458430("SYC{%s}\n", (unsigned int)byte_52E000);
v1 = v0;
sub_457841(&savedregs, &dword_45C134);
return sub_456685(v2, v1);
}
这是还原的伪代码
基地址 byte_52E000双击后有
.data:0052E000 byte_52E000 db 'O' ; DATA XREF: sub_45BFF0+ADr
.data:0052E000 ; sub_45BFF0+C4r ...
.data:0052E001 dd '.l!1'
.data:0052E005 dd 'ou..'
.data:0052E009 dd '5p__'
.data:0052E00D dd 'sOU_'
.data:0052E011 dd 'Desf'
.data:0052E015 dd 15h
.data:0052E019 db 0
.data:0052E01A db 0
.data:0052E01B db 0
这里是找到的ascii码
o21 15h NAK ␕ 确认失败回应
str.replace(a,b,c)方法:用b替换str中的a替换c个(a,b为str型,c为int型)
a="01!l...uo__p5_UOsfseD"
b=[7,3,1,8,7,2,3,2]
c=[18,19,20,1,15,20,16,11]
a=list(a)
t=""
for i in range(8):
t=a[b[i]]
a[b[i]]=a[c[i]]
a[c[i]]=t
for i in a:
print(a,end="")
计算结果为Oops…OD__15_Useful!
得到的flag为 SYC{Oops…OD__15_Useful!}
当然这一题也可以用爆破解决。
总结:有时候得到flag不一定非要先的到注册码和用户名(用户名和注册码可能特别难计算)。
注意字符串给出的提示% 格式化数据需要用到,很多时候就是为了输出