CRC32算法逆向 lebel:基本过程 / 数据表过程(模二过程) / CRC校验 / str转int

参考:
https://bbs.ichunqiu.com/thread-30717-1-1.html

ida通过字符串定位到该函数

静态分析第一部分

int sub_4042A8()
{
  int v0; // esi
  int name_len; // ebx
  char *v2; // eax
  int v3; // eax
  unsigned int v4; // esi
  int password_len; // ebx
  char *v6; // eax
  unsigned int v8; // [esp-14h] [ebp-1Ch]
  void *v9; // [esp-10h] [ebp-18h]
  int *v10; // [esp-Ch] [ebp-14h]
  char *v11; // [esp+0h] [ebp-8h]
  char *v12; // [esp+4h] [ebp-4h]
  int savedregs; // [esp+8h] [ebp+0h]

  v12 = 0;
  v11 = 0;
  v10 = &savedregs;
  v9 = &loc_4043D5;
  v8 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v8);
  sub_402DE8(&v12);							    //动调,没什么变化
  v0 = GetWindowTextLengthA(hWnd);              // 可通过输入长度不同并动调判断是哪个hwnd,动调结果为Name
  name_len = v0;
  if ( v0 > 0 )
  {
    do
    {
      sub_402ED8((int *)&v12, (int)dword_4043EC);// dword[3]数组固定,应该是做运算后赋值给&v12,动调发现值和Name长度有关,且大小为int
      --name_len;
    }
    while ( name_len );
  }
  v2 = sub_402FA0(v12);                         // 动调前静态分析是v2 = v13地址,动调后发现是v2 = *(int*)&v12
  GetWindowTextA(hWnd, v2, 50);                 // Name的输入放入了地址为v2的值的地方

总结一下就是根据Name的长度指定一块空间来存Name

静态分析第二部分

if ( v0 >= 5 )
  {
    sub_402F1C((int *)&v12, (int)"DiKeN", (int)v12);// 动调,发现在输入前加了DiKeN
    v3 = sub_402ED0((int)v12);                  // 动调,发现是len('DiKeN')+len(Name)
    v4 = CRC_check(&v12, v3);                   // CRC_check
    sub_402DE8(&v11);                           // 同上
    password_len = GetWindowTextLengthA(dword_40652C);
    if ( password_len > 0 )
    {
      do
      {
        sub_402ED8((int *)&v11, (int)dword_4043EC);// 同上
        --password_len;
      }
      while ( password_len );
    }
    v6 = sub_402FA0(v11);                       // 同上
    GetWindowTextA(dword_40652C, v6, 32);       // 同上
    sub_402F1C((int *)&v11, (int)&dword_404408, (int)v11);// 动调,在前面加了个0
    if ( sub_404224((int)v11) ^ v4 )            // sub_404224 str转int,异或为0,两者相等
      MessageBoxA_0(dword_406504, "错误的注册码", "错误", 0);
    else
      MessageBoxA_0(dword_406504, "正确的注册码", "恭喜", 0);

str转int

unsigned calc_code(char *c,int len){
unsigned i,j=0;
for(i=0;c!='\0';i++){
	j=j*10;
	j=j+(int)c-0x30;
}
printf("%x,\n",j);
return j;
}

CRC_check原代码

unsigned CRC32(char *c,int len){
unsigned i,j;
unsigned crc_i=0xFFFFFFFF;
for(i=0;c!='\0';i++){
	j=(crc_i&0xFF) ^ (int)c;
	crc_i=(crc_i>>8)^crc32_table[j%256];
}
crc_i=crc_i^0xFFFFFFFF;
return crc_i;
}

题目中的CRC_check

int __usercall CRC_check@<eax>(_BYTE **a1@<eax>, int len@<edx>)
{
  _BYTE *v2; // esi
  unsigned int v3; // eax

  v2 = *a1;
  v3 = -1;                                      // 0xFFFFFFFF
  do
  {
    LOBYTE(v3) = *v2 ^ v3;
    //注意到表的第一个元素是0对应有效数据为0,元素个数为256个刚好对应8bit有效数据的所有情况
    v3 = *(_DWORD *)&word_403E1A[2 * (unsigned __int8)v3] ^ (v3 >> 8);
    ++v2;
    --len;
  }
  while ( len );
  return ~v3;
}

Name CRC_check(CRC32加密)的结果等于password经str转Int的值

解题脚本

import zlib
s = b'DiKeNq1uTruth'
print(zlib.crc32(s))
print(hex(zlib.crc32(s)))

#1894268809
#0x70e83f89

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

q1uTruth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值