破解练习

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax@1
  int v4; // eax@5
  signed int v5; // kr04_4@5
  signed int i; // eax@6
  char v7; // dl@7
  int v9; // [sp+4h] [bp-4Ch]@1
  int v10; // [sp+8h] [bp-48h]@1
  int v11; // [sp+Ch] [bp-44h]@1
  int v12; // [sp+10h] [bp-40h]@1
  int v13; // [sp+14h] [bp-3Ch]@1
  __int16 v14; // [sp+18h] [bp-38h]@1
  char v15; // [sp+1Ah] [bp-36h]@1
  int v16; // [sp+1Ch] [bp-34h]@1
  int v17; // [sp+20h] [bp-30h]@1
  __int16 v18; // [sp+24h] [bp-2Ch]@1
  char v19; // [sp+2Bh] [bp-25h]@7
  char v20; // [sp+2Ch] [bp-24h]@1
  int v21; // [sp+2Dh] [bp-23h]@1
  int v22; // [sp+31h] [bp-1Fh]@1
  __int16 v23; // [sp+35h] [bp-1Bh]@1
  char v24; // [sp+37h] [bp-19h]@1
  char v25; // [sp+38h] [bp-18h]@1

  v21 = 0;
  v22 = 0;
  v23 = 0;
  v24 = 0;
  v20 = 0;
  v16 = 0x7544634D;
  v17 = 0x41406C6C;
  v18 = 0x6E75;
  v9 = 0x4F4C5F49;
  v10 = 0x435F4556;
  v11 = 0x5F4654;
  v12 = 0x3A352A10;
  v13 = 0x3333C1B;
  v14 = 0x2322;
  v15 = 0x7E;
  v3 = print(std::cout, &unk_40317C);
  std::basic_ostream<char,std::char_traits<char>>::operator<<(v3, std::endl);
  sub_401610(std::cin, &v25);
  if ( strlen(&v25) - 5 <= 3 || strcmp(&v25, (const char *)&v16) )// >8
  {
    printf(Format);
    exit(0);
  }
  v4 = print(std::cout, "请输入管理员密码:");
  std::basic_ostream<char,std::char_traits<char>>::operator<<(v4, std::endl);
  sub_401610(std::cin, &v16);
  v5 = strlen((const char *)&v16);
  if ( (unsigned int)(v5 - 5) > 6 )             // <=o11
  {
    printf("对不起,您输入的密码错误!");
    exit(0);
  }
  for ( i = 0; i < v5; *(&v19 + i) = v7 )
  {
    v7 = *((_BYTE *)&v12 + i) ^ *((_BYTE *)&v16 + i);
    ++i;
  }
  if ( !strcmp((const char *)&v9, &v20) )
    printf("登陆成功!KEY{管理员密码}       \n");
  else
    printf("对不起,您输入的密码错误!");
  system("pause");
  return 0;
}

这里是IDA反编译出来的伪C代码,值得注意的是IDA里面数据的存储。
这里的数组被还原为int型数据读入的时候是从后往前,判断是另一个数组的依据是变量的名字v16 = 0x7544634D;
v17 = 0x41406C6C;
v18 = 0x6E75;
v9 = 0x4F4C5F49;
v10 = 0x435F4556;
v11 = 0x5F4654;
这里可以看出来v18后面不是v19可以大致确定下面不是同一个数组。

for ( i = 0; i < v5; *(&v19 + i) = v7 )
  {
    v7 = *((_BYTE *)&v12 + i) ^ *((_BYTE *)&v16 + i);
    ++i;
  }
  if ( !strcmp((const char *)&v9, &v20) )
这段代码看,比较的是v20而v20并没有参与其他的运算,而实际上,v20是在v19下面定义的给v19赋值时会把v20给覆盖掉这里的v20和就是循环里面改变的v19的值。

这里结题脚本:
a=[0x4F,0x4C,0x5F,0x49, 0x43,0x5F,0x45,0x56,0x5F,0x46,0x54]
a1=[a[3],[a[2],a[1],a[0],a[7],a[6],a[5],a[4],a[10],a[9],a[8]]
b=[0x3A,0x35,0x2A,0x10,0x03,0x33,0x3C,0x1B,0x23,0x22,0x7E]
b1=[b[3],b[2],b[1],b[0],b[7],b[6],b[5],b[4],b[9],b[8],b[10]]
c=''
for i in range(11):
    c[i]=chr(a1[i]^b1[i])
print(c,end="")
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值