吾爱破解论坛春节红包活动——第二题解题思路

CrackMe类型,难度不大

Posted by gxkyrftx on February 22, 2019

0.前言

这题早就做出来了,一直拖着不想写wp,来学校才能静下心来写点东西。

1.简单分析

下载运行,随便输入一些字符串,结果如下图

1

提示长度错误。 然后查一下壳,结果如下:

2

UPX壳,直接使用peid的插件脱掉upx壳

2.ida分析

将脱壳后的软件拖入ida,查看程序大致流程。 具体的追踪流程为:winmain窗口——>调用DialogBoxParamA函数——>调用DialogFunc函数,看一下DialogFunc函数

2.1 DialogFunc

BOOL __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4)
{
  BOOL result; // eax@6

  if ( a2 == 272 )
  {
    ::hWnd = hWnd;
    SendMessageA(hWnd, 0x80u, 1u, 0);
    SendMessageA(hWnd, 0x80u, 0, 0);
    result = 1;
  }
  else
  {
    if ( a2 != 273 )
      return 0;
    if ( (unsigned __int16)a3 == 1 )
    {
      sub_401170();                             // 这里对输入进行了验证
      result = 1;
    }
    else if ( (unsigned __int16)a3 == 2 )
    {
      EndDialog(0, 2);
      result = 1;
    }
    else
    {
      if ( (unsigned __int16)a3 != 1003 )
        return 0;
      WinExec("explorer.exe \"https://www.52pojie.cn/home.php?mod=task&do=view&id=14\"", 5u);    //在这里弹窗,跳到领取红包的页面
      result = 1;
    }
  }
  return result;
}

2.2 sub_401170()

核心验证函数,这个函数中,首先对通过GetWindowTextLengthA函数对输入sn的长度进行验证,必须使16个字符。然后以’udhYssdHzhNb9102’为初始字符串,让它经过change函数变换后与sn比较,相同则正确。关键就是经过change函数后变成了什么,change就是一系列变换,因为考虑使用了strcmp函数,所以判断寄存器中应该有相应的值,所以使用动态调试。

HWND sub_401170()
{
  HWND result; // eax@1
  _DWORD *sn; // esi@4
  _DWORD *v2; // edi@4
  int v3; // [sp+0h] [bp-14h]@4
  int v4; // [sp+4h] [bp-10h]@4
  int v5; // [sp+8h] [bp-Ch]@4
  int v6; // [sp+Ch] [bp-8h]@4
  char v7; // [sp+10h] [bp-4h]@4

  result = GetDlgItem(0, 1000);
  if ( result )
  {
    if ( GetWindowTextLengthA(result) == 16 )
    {
      sn = malloc(0x11u);                       // 分配空间
      v2 = malloc(0x11u);
      *sn = 0;
      sn[1] = 0;
      sn[2] = 0;
      sn[3] = 0;
      *((_BYTE *)sn + 16) = 0;
      *v2 = 0;
      v2[1] = 0;
      v2[2] = 0;
      v2[3] = 0;
      *((_BYTE *)v2 + 16) = 0;
      GetDlgItemTextA(0, 1000, (LPSTR)sn, 17);
      v5 = 'udhY';
      v3 = 'ssdH';
      v4 = 'zhNb';
      v6 = '9102';
      v7 = 0;
      change((const char *)&v3, (int)v2, 3);
      if ( !strcmp((const char *)v2, (const char *)sn) )
        result = (HWND)MessageBoxA(0, "正确!!!回复你输入的内容到吾爱破解论坛公众号,即可获取通关口令!", Caption, 0);
      else
        result = (HWND)MessageBoxA(0, "内容错误", Caption, 0);
    }
    else
    {
      result = (HWND)MessageBoxA(0, "长度错误", Caption, 0);
    }
  }
  return result;
}

3. 动态调试

在以下位置下断点

    if ( !strcmp((const char *)v2, (const char *)sn) )

输入16个字符,例如1234567890123456,然后检测密码。然后f9让程序运行,最终查看eax的值,发现就是sn

3

验证结果如下:

4 5


本文访问量: