破解之算法解析

来源:互联网 发布:用友软件体系 编辑:程序博客网 时间:2024/04/27 17:07

这题是找程序获取到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]]=tfor i in a:    print(a,end="")

计算结果为Oops…OD__15_Useful!
得到的flag为 SYC{Oops…OD__15_Useful!}

当然这一题也可以用爆破解决。

总结:有时候得到flag不一定非要先的到注册码和用户名(用户名和注册码可能特别难计算)。
注意字符串给出的提示% 格式化数据需要用到,很多时候就是为了输出