zoukankan      html  css  js  c++  java
  • BUUCTF CrackMe

    这道题写了我将近一周。。还是看着别人博客写了一周才搞懂的,犯了几个错误:1.没看题目,2.没清楚什么样的代码是调试

    所以看这道题之前先看这个wiki里的前置知识:https://wiki.x10sec.org/reverse/anti-debug/example/了解调试代码

     然后检查下有没有加壳,检查完后发现没有。

    在运行一下这个程序看看,从而做出一些判断,和通过字符串找到程序入口

     打开ida分析

     通过分析代码结构和程序流程可以知道,需要让代码中的死循环跳出,那么sub_401830和loc_4011a0需要成立的,但是loc_4011a0这个函数的参数都是0,所以这个函数是不需要去分析的

    而其他几个函数,是检查字母和数字的,但这个函数时给byte_416050赋值的。

     打开sub_401830函数

     该函数是否成功,再于v14是否等于43924,所以打开sub_401470函数

    _DWORD *__usercall sub_401470@<eax>(int a1@<ebx>, _BYTE *a2, _DWORD *a3)
    {
      int v3; // ST28_4
      int v4; // ecx
      int v6; // edx
      int v8; // ST20_4
      int v9; // eax
      int v10; // edi
      int v11; // ST1C_4
      int v12; // edx
      char v13; // di
      int v14; // ST18_4
      int v15; // eax
      int v16; // ST14_4
      int v17; // edx
      char v18; // al
      int v19; // ST10_4
      int v20; // ecx
      int v23; // ST0C_4
      int v24; // eax
      _DWORD *result; // eax
      int v26; // edx
    
      if ( *a2 == 100 )
      {
        *a3 |= 4u;
        v4 = *a3;
      }
      else
      {
        *a3 ^= 3u;
      }
      v3 = *a3;
      if ( a2[1] == 98 )
      {
        _EAX = a3;
        *a3 |= 0x14u;
        v6 = *a3;
      }
      else
      {
        *a3 &= 0x61u;
        _EAX = (_DWORD *)*a3;
      }
      __asm { aam }
      if ( a2[2] == 97 )
      {
        *a3 |= 0x84u;
        v9 = *a3;
      }
      else
      {
        *a3 &= 0xAu;
      }
      v8 = *a3;
      v10 = ~(a1 >> -91);
      if ( a2[3] == 112 )
      {
        *a3 |= 0x114u;
        v12 = *a3;
      }
      else
      {
        *a3 >>= 7;
      }
      v11 = *a3;
      v13 = v10 - 1;
      if ( a2[4] == 112 )
      {
        *a3 |= 0x380u;
        v15 = *a3;
      }
      else
      {
        *a3 *= 2;
      }
      v14 = *a3;
      if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
      {
        if ( a2[5] == 102 )
        {
          *a3 |= 0x2DCu;
          v17 = *a3;
        }
        else
        {
          *a3 |= 0x21u;
        }
        v16 = *a3;
      }
      if ( a2[5] == 115 )
      {
        *a3 |= 0xA04u;
        v18 = (char)a3;
        v20 = *a3;
      }
      else
      {
        v18 = (char)a3;
        *a3 ^= 0x1ADu;
      }
      v19 = *a3;
      _AL = v18 - v13;
      __asm { daa }
      if ( a2[6] == 101 )
      {
        *a3 |= 0x2310u;
        v24 = *a3;
      }
      else
      {
        *a3 |= 0x4Au;
      }
      v23 = *a3;
      if ( a2[7] == 99 )
      {
        result = a3;
        *a3 |= 0x8A10u;
        v26 = *a3;
      }
      else
      {
        *a3 &= 0x3A3u;
        result = (_DWORD *)*a3;
      }
      return result;
    }

    可以知道这个函数是如果a2满足所有的if就可以成立,v14也就可以等于43924

    所以其值为b=[0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63]

    所以我们知道了v17的值,但需要求v17的值是如何来的

    在接着往上看,

     这里有两个反调试的代码,如果在调试就进行一些别的操作,否则直接让byte_416050和v15这个字符串进行异或。

    接着往上看

     也有反调试的代码,显然这一部分与密码有关,并且通过最后一个if可以发现这是将两个字符串进行合并为一个,第一个if是将字符数转换为整型数,第二个我没搞明白是什么意思,但第三个是将字母变成0-15的数字,所以我们可以推测,密码是字母0-15和数字0-9组成的。例如密码是"0a",经过合并后就会变为一个字符为'0a'

    所以我们只需要求v17对byte_416050这个字符串的异或了,通过动态调试,我们可以知道byte_416050的值为a=[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd],与其做异或得出的值就是密码。

     一开始没看题目,带了个12345678进去,然后.......解出来了,但不符合题意。。。

    得到密码后,在进行md5 32位小写加密就行了

  • 相关阅读:
    expect
    grep
    Python函数
    Python的set
    Python字典
    Python循环
    Python条件判断
    Python列表
    Python字符串
    Python组织代码块的形式
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/12546844.html
Copyright © 2011-2022 走看看