新160个crackme - 017-Cabeca

运行分析

在这里插入图片描述

  • 需要破解Serial1和Serial2

PE分析

在这里插入图片描述

  • Delphi文件,32位,无壳

静态分析&动态调试

在这里插入图片描述

  • 找到关键字符串(Delphi程序的字符串一般都在最下方),进入关键函数

int __usercall TForm1_Button1Click@<eax>(_DWORD *a1@<eax>, int a2@<ebx>)
{
  char v3; // zf
  int v5; // [esp-14h] [ebp-24h]
  int v6; // [esp-14h] [ebp-24h]
  int v7; // [esp-14h] [ebp-24h]
  int v8; // [esp-14h] [ebp-24h]
  unsigned int v9[2]; // [esp-10h] [ebp-20h] BYREF
  int *v10; // [esp-8h] [ebp-18h]
  int v11; // [esp-4h] [ebp-14h]
  int v12; // [esp+0h] [ebp-10h] BYREF
  int Serial2; // [esp+4h] [ebp-Ch] BYREF
  int Serial1; // [esp+8h] [ebp-8h] BYREF
  int v15; // [esp+Ch] [ebp-4h] BYREF
  int savedregs; // [esp+10h] [ebp+0h] BYREF

  Serial2 = 0;
  v12 = 0;
  v11 = a2;
  v10 = &savedregs;
  v9[1] = (unsigned int)&loc_42D5AD;
  v9[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)v9);
  if ( dword_42F714
    && dword_42F718
    && (set(a1[120], &v15), v15)                // v15 = Name
    && (set(a1[121], &Serial1), Serial1)
    && (set(a1[123], &Serial2), Serial2) )
  {
    if ( !dword_42F714 )
      goto LABEL_20;
    if ( !dword_42F718 )
      goto LABEL_20;
    sub_406550(dword_42F714, &v12);
    v5 = v12;
    set(a1[121], &v15);                         // v15 = Serial1
    cmp(v5, v15);
    if ( !v3 )
      goto LABEL_20;
    sub_406550(dword_42F718, &v12);
    v6 = v12;
    set(a1[123], &v15);                         // v15 = Serial2
    cmp(v6, v15);
    if ( v3 )
    {
      sub_42CA8C(&str_Hmmm_____Cracke[1]);
    }
    else
    {
LABEL_20:
      if ( dword_42F714 )
      {
        if ( dword_42F718 )
        {
          sub_406550(dword_42F714, &v12);
          v7 = v12;
          set(a1[121], &v15);
          cmp(v7, v15);
          if ( !v3 )
            goto LABEL_16;
        }
      }
      sub_406550(dword_42F718, &v12);
      v8 = v12;
      set(a1[123], &v15);
      cmp(v8, v15);
      if ( !v3 )
      {
LABEL_16:
        sub_42CA8C(&str_Nice_try____but[1]);    // 成功弹窗
        dword_42F714 = 0;
        dword_42F718 = 0;
        sub_419E10(a1[120], 0);
        sub_419E10(a1[121], 0);
        sub_419E10(a1[123], 0);
      }
    }
  }
  else
  {
    sub_42CA8C(&str_Fill_all_boxes_[1]);        // 失败弹窗
    dword_42F714 = 0;
    dword_42F718 = 0;
    sub_419E10(a1[120], 0);
    sub_419E10(a1[121], 0);
    sub_419E10(a1[123], 0);
  }
  __writefsdword(0, v9[0]);
  v10 = (int *)&loc_42D5B4;
  sub_403544(&v12);
  return sub_403568(&Serial2, 3);
}
  • 静态分析关键函数得出下列结论:
  • 1、Name、Serial1、Serial2必须不为空,同时dword_42F714和dword_42F718两个地址的值也不能为空
  • 2、sub_406550(dword_42F714, &v12)得到v12,v12要与Serial1相等
  • 3、sub_406550(dword_42F718, &v12)得到v12,v12要与Serial2相等
  • 4、猜测dword_42F714和dword_42F718应该与Name有关

在这里插入图片描述

  • 使用x32dbg动态调试,在关键函数头下断点

在这里插入图片描述

  • 在dword_42F714处下内存写入断点(在dword_42F714变化时跳转至运行位置)

在这里插入图片描述

  • Name处输入A,跳转至该位置

在这里插入图片描述

  • 用ida定位该位置,发现是switch函数
  • 当输入Name每个字符时,根据输入字符的值对dword_42F714和dword_42F718进行计算

在这里插入图片描述

  • 在sub_406550函数处下断点,输入Name和Serial运行

在这里插入图片描述

  • dword_42F714的值为BA50,运行sub_406550后,得到栈中变量0226B604的值为47696

在这里插入图片描述

  • BA50正好是47696的十六进制数,即sub_406550函数的作用是将dword_42F714的十六进制数转为十进制数

算法分析

Name = 'concealbear'
Serial1 = ''
Serial2 = ''
dword_42F714 = 0
dword_42F718 = 0

# switch函数
def switch(byte):
    global dword_42F718
    global dword_42F714
    if ord(byte) == 8:
        dword_42F714 = 0;
        dword_42F718 = 0;
    if ord(byte) == 0x41:
        dword_42F714 += 1064;
        dword_42F718 += 5648;
    if ord(byte) == 0x42:
        dword_42F714 += 726576;
        dword_42F718 += 2;
    if ord(byte) == 0x43:
        dword_42F714 += 3462;
        dword_42F718 += 9999;
    if ord(byte) == 0x44:
        dword_42F714 += 4516;
        dword_42F718 += 74445628;
    if ord(byte) == 0x45:
        dword_42F714 += 73482;
        dword_42F718 += 35644;
    if ord(byte) == 0x46:
        dword_42F714 += 15554;
        dword_42F718 += 34328;
    if ord(byte) == 0x47:
        dword_42F714 += 254376;
        dword_42F718 += 444444;
    if ord(byte) == 0x48:
        dword_42F714 += 37348;
        dword_42F718 += 2615621;
    if ord(byte) == 0x49:
        dword_42F714 += 27458;
        dword_42F718 += 3131331;
    if ord(byte) == 0x4A:
        dword_42F714 += 333476;
        dword_42F718 += 12121212;
    if ord(byte) == 0x4B:
        dword_42F714 += 275546;
        dword_42F718 += 71111;
    if ord(byte) == 0x4C:
        dword_42F714 += 1834457;
        dword_42F718 += 76628;
    if ord(byte) == 0x4D:
        dword_42F714 += 10349;
        dword_42F718 += 734348;
    if ord(byte) == 0x4E:
        dword_42F714 += 1025;
        dword_42F718 += 897376628;
    if ord(byte) == 0x4F:
        dword_42F714 += 1652;
        dword_42F718 += 3243223;
    if ord(byte) == 0x50:
        dword_42F714 += 156;
        dword_42F718 += 8247348;
    if ord(byte) == 0x51:
        dword_42F714 += 342;
        dword_42F718 += 236752;
    if ord(byte) == 0x52:
        dword_42F714 += 34343;
        dword_42F718 += 783434;
    if ord(byte) == 0x53:
        dword_42F714 += 7635344;
        dword_42F718 += 8734342;
    if ord(byte) == 0x54:
        dword_42F714 += 42344;
        dword_42F718 += 78368;
    if ord(byte) == 0x55:
        dword_42F714 += 87442;
        dword_42F718 += 12334;
    if ord(byte) == 0x56:
        dword_42F714 += 7641;
        dword_42F718 += 7235;
    if ord(byte) == 0x57:
        dword_42F714 += 15552;
        dword_42F718 += 323528;
    if ord(byte) == 0x58:
        dword_42F714 += 9834;
        dword_42F718 += 732523528;
    if ord(byte) == 0x59:
        dword_42F714 += 33553;
        dword_42F718 += 7238;
    if ord(byte) == 0x5A:
        dword_42F714 += 52763;
        dword_42F718 += 726628;
    if ord(byte) == 0x61:
        dword_42F714 += 1063;
        dword_42F718 += 121;
    if ord(byte) == 0x62:
        dword_42F714 += 1724;
        dword_42F718 += 111;
    if ord(byte) == 0x63:
        dword_42F714 += 1169;
        dword_42F718 += 738;
    if ord(byte) == 0x64:
        dword_42F714 += 18253;
        dword_42F718 += 762;
    if ord(byte) == 0x65:
        dword_42F714 += 1024;
        dword_42F718 += 14;
    if ord(byte) == 0x66:
        dword_42F714 += 1744;
        dword_42F718 += 13;
    if ord(byte) == 0x67:
        dword_42F714 += 1661;
        dword_42F718 += 12;
    if ord(byte) == 0x68:
        dword_42F714 += 1872;
        dword_42F718 += 11;
    if ord(byte) == 0x69:
        dword_42F714 += 1084;
        dword_42F718 += 99;
    if ord(byte) == 0x6A:
        dword_42F714 += 1892;
        dword_42F718 += 888;
    if ord(byte) == 0x6B:
        dword_42F714 += 192;
        dword_42F718 += 77;
    if ord(byte) == 0x6C:
        dword_42F714 += 10109;
        dword_42F718 += 555;
    if ord(byte) == 0x6D:
        dword_42F714 += 2078;
        dword_42F718 += 90;
    if ord(byte) == 0x6E:
        dword_42F714 += 3591;
        dword_42F718 += 98;
    if ord(byte) == 0x6F:
        dword_42F714 += 142;
        dword_42F718 += 7468;
    if ord(byte) == 0x70:
        dword_42F714 += 632432;
        dword_42F718 += 575475;
    if ord(byte) == 0x71:
        dword_42F714 += 3415;
        dword_42F718 += 648;
    if ord(byte) == 0x72:
        dword_42F714 += 24555;
        dword_42F718 += 538;
    if ord(byte) == 0x73:
        dword_42F714 += 2224;
        ++dword_42F718;
    if ord(byte) == 0x74:
        dword_42F714 += 1211;
        dword_42F718 += 64;
    if ord(byte) == 0x75:
        dword_42F714 += 2242;
        dword_42F718 += 75;
    if ord(byte) == 0x76:
        dword_42F714 += 7334;
        dword_42F718 += 78;
    if ord(byte) == 0x77:
        dword_42F714 += 9502;
        dword_42F718 += 5;
    if ord(byte) == 0x78:
        dword_42F714 += 917;
        dword_42F718 += 38;
    if ord(byte) == 0x79:
        dword_42F714 += 11539;
        dword_42F718 += 8;
    if ord(byte) == 0x7A:
        dword_42F714 += 6400;
        dword_42F718 += 456;

# 计算dword_42F714和dword_42F718
for i in Name:
    switch(i)

Serial1 = str(dword_42F714)
Serial2 = str(dword_42F718)

print(Name + '的Serial1为:' + Serial1)
print(Name + '的Serial2为:' + Serial2)

在这里插入图片描述
在这里插入图片描述

  • 输入任意Name,得到Serial1和Serial2,验证成功
  • 注意输入Name的时候要逐个字符输入,不能复制粘贴,否则无法每个字符都触发switch函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值