Reversing.Kr练习

发布于 2018-08-01  781 次阅读


Easy Crack

Download

先运行一下程序,随便输入一些东西

Reversing.Kr练习
得到了特殊字符串"Incorrect Password"

用PEID查壳

Reversing.Kr练习
显示没有加壳

用IDA Pro进行分析

  • 先Shift+F12搜索所有字符串,查找特殊字符串"Incorrect Password"和其他字符串
  • Reversing.Kr练习

  • 跳转到改字符串所在的汇编代码片段,F5查看伪代码
  • int __cdecl sub_401080(HWND hDlg)
    {
      int result; // eax@5
      CHAR String; // [sp+4h] [bp-64h]@1
      char v3; // [sp+5h] [bp-63h]@1
      char v4; // [sp+6h] [bp-62h]@2
      char v5; // [sp+8h] [bp-60h]@3
      __int16 v6; // [sp+65h] [bp-3h]@1
      char v7; // [sp+67h] [bp-1h]@1
    
      String = 0;
      memset(&v3, 0, 0x60u);
      v6 = 0;
      v7 = 0;
      GetDlgItemTextA(hDlg, 1000, &String, 100);
      if ( v3 == 97 && !strncmp(&v4, a5y, 2u) && !strcmp(&v5, aR3versing) && String == 69 )
      {
        MessageBoxA(hDlg, Text, Caption, 0x40u);
        result = EndDialog(hDlg, 0);
      }
      else
      {
        result = MessageBoxA(hDlg, aIncorrectPassw, Caption, 0x10u);
      }
      return result;
    }
    
  • 通过伪代码可以知道我们要通过第一个if就可以得到flag
  • if ( v3 == 97 && !strncmp(&v4, a5y, 2u) && !strcmp(&v5, aR3versing) && String == 69 )
    

    Reversing.Kr练习
    可以得到String = 69(E) + var_63(a) + var_62(5y) + var_60(R3versing)就是flag

  • 测试一下
  • Reversing.Kr练习

    Easy Keygen

    Download

    查看文件

  • 有一个Easy Keygen.exe和ReadMe.txt
  • 从ReadMe.txt中可以知道要得到Name在Serial = 5B134977135E7D13时的值

  • 运行Easy Keygen.exe可以得到一些特殊字符串
  • 查壳

    和上面那个一样没有加壳

    直接拖到IDA Pro里分析

  • 先Shift+F12查找特殊字符串并跳转到改字符串所在汇编代码位置,F5查看伪代码
  • int __cdecl main(int argc, const char **argv, const char **envp)
    {
      signed int v3; // ebp@1
      signed int i; // esi@1
      int result; // eax@6
      char v6; // [sp+Ch] [bp-130h]@1
      char v7; // [sp+Dh] [bp-12Fh]@1
      char v8; // [sp+Eh] [bp-12Eh]@1
      char v9; // [sp+10h] [bp-12Ch]@1
      char v10; // [sp+11h] [bp-12Bh]@1
      __int16 v11; // [sp+71h] [bp-CBh]@1
      char v12; // [sp+73h] [bp-C9h]@1
      char v13; // [sp+74h] [bp-C8h]@1
      char v14; // [sp+75h] [bp-C7h]@1
      __int16 v15; // [sp+139h] [bp-3h]@1
      char v16; // [sp+13Bh] [bp-1h]@1
    
      v9 = 0;
      v13 = 0;
      memset(&v10, 0, 0x60u);
      v11 = 0;
      v12 = 0;
      memset(&v14, 0, 0xC4u);
      v15 = 0;
      v16 = 0;
      v6 = 16;
      v7 = 32;
      v8 = 48;
      sub_4011B9(aInputName);
      scanf(aS, &v9);
      v3 = 0;
      for ( i = 0; v3 < (signed int)strlen(&v9); ++i )
      {
        if ( i >= 3 )
          i = 0;
        sprintf(&v13, aS02x, &v13, *(&v9 + v3++) ^ *(&v6 + i));
      }
      memset(&v9, 0, 0x64u);
      sub_4011B9(aInputSerial);
      scanf(aS, &v9);
      if ( !strcmp(&v9, &v13) )
      {
        sub_4011B9(aCorrect);
        result = 0;
      }
      else
      {
        sub_4011B9(aWrong);
        result = 0;
      }
      return result;
    }
    
  • 主要代码
  • sub_4011B9(aInputName);
      scanf(aS, &v9);
      v3 = 0;
      for ( i = 0; v3 < (signed int)strlen(&v9); ++i )
      {
        if ( i >= 3 )
          i = 0;
        sprintf(&v13, aS02x, &v13, *(&v9 + v3++) ^ *(&v6 + i));
      }
      memset(&v9, 0, 0x64u);
      sub_4011B9(aInputSerial);
      scanf(aS, &v9);
      if ( !strcmp(&v9, &v13) )
      {
        sub_4011B9(aCorrect);
        result = 0;
      }
      else
      {
        sub_4011B9(aWrong);
        result = 0;
      }
    
  • v6,v7和v8为连续地址,且即为&(v6),&(v6+1)与&(v6+2),分别为16,32,48
  • sprintf的格式化参数在IDA中没有直接显示,双击aS02x可以看到%s%02X。前一个%s是地址的值,后一个%02x则表示宽度为2,以0填充,十六进制数字,即将字符的ASCII传入v13
  • 把输入每一个字符分别依次和v6、v7与v8进行xor,即可得到最终结果,如果a xor b=c,那么c xor b=a
  • C++解密代码

    #include <iostream>
    #include <string>
    #include <cstdio>
    
    using namespace std;
    
    string Serial = "5B134977135E7D13";
    int n[3] = {16, 32, 48};
    
    int change(char a) {
        if (a >= 'A' && a <= 'Z')
            return a - 'A' + 10;
        if (a >= '0' && a <= '9') 
            return a - '0';
    }
    
    int main() {
        int index = 0;
        for(int i = 0; i < Serial.length(); i+= 2) { 
            if(index >= 3) 
                index = 0;
            int num1 = change(Serial[i]);
            int num2 = change(Serial[i + 1]);
            int num = num1 * 16 + num2;
            printf("%c",num ^ n[index++]);
        }
        getchar();
    }
    
  • 运行完后得到K3yg3nm3
  • Easy_ELF

    Download

    分析

  • 由于不是windows的可执行文件所以直接用IDA Pro进行分析
  • 还是先Shift+F12查找特殊字符串
  • Reversing.Kr练习

  • 跳转到改字符串所在汇编代码位置F5查看伪代码
  • int __cdecl main()
    {
      int result; // eax@2
    
      write(1, "Reversing.Kr Easy ELF\n\n", 0x17u);
      sub_8048434();
      if ( sub_8048451() == 1 )
      {
        sub_80484F7();
        result = 0;
      }
      else
      {
        write(1, "Wrong\n", 6u);
        result = 0;
      }
      return result;
    }
    
  • 要通过第一个if
  • if ( sub_8048451() == 1 )
    
  • sub_8048451()
  • int sub_8048451()
    {
      int result; // eax@2
    
      if ( byte_804A021 == '1' )
      {
        byte_804A020 ^= 0x34u;
        byte_804A022 ^= 0x32u;
        byte_804A023 ^= 0x88u;
        if ( byte_804A024 == 'X' )
        {
          if ( byte_804A025 )
          {
            result = 0;
          }
          else if ( byte_804A022 == ('|') )
          {
            if ( byte_804A020 == 'x' )
              result = byte_804A023 == ';
            else
              result = 0;
          }
          else
          {
            result = 0;
          }
        }
        else
        {
          result = 0;
        }
      }
      else
      {
        result = 0;
      }
      return result;
    }
    
  • byte_804A020 = x ^ 0x34u
  • byte_804A021 = 1
  • byte_804A022 = | ^ 0x32u
  • byte_804A023 = -35 ^ 0x88u
  • byte_804A024 = X
  • byte_804A025 = 0
  • C++解密代码

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    int main(){
        int byte_804A020 = 'x' ^ 0x34u;
        int byte_804A021 = 1;   
        int byte_804A022 = '|' ^ 0x32u;
        int byte_804A023 = -35 ^ 0x88u;
        int byte_804A024 = 'X';
        int byte_804A025 = 0;
        cout << char(byte_804A020) << byte_804A021 << char(byte_804A022) << char(byte_804A023) << char(byte_804A024) << char(byte_804A025) << endl;
        getchar();
    }
    
  • flag:L1NUX