• Jarvis OJ部分逆向


    Jarvis OJ部分逆向题解

      很久没有写博客了,前天上Jarvis OJ刷了几道逆向,保持了一下感觉。都是简单题目,写个writeup记录一下。

    easycrackme

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      __int64 v3; // rdi
      char v5; // [rsp+0h] [rbp-38h]
      char v6; // [rsp+1h] [rbp-37h]
      char v7; // [rsp+2h] [rbp-36h]
      char v8; // [rsp+3h] [rbp-35h]
      char v9; // [rsp+4h] [rbp-34h]
      char v10; // [rsp+5h] [rbp-33h]
      unsigned __int8 v11; // [rsp+10h] [rbp-28h]
      _BYTE v12[7]; // [rsp+11h] [rbp-27h]
    
      v5 = -85;
      v6 = -35;
      v7 = 51;
      v8 = 84;
      v9 = 53;
      v10 = -17;
      printf((unsigned __int64)"Input your password:");
      _isoc99_scanf((unsigned __int64)"%s");
      if ( strlen((const char *)&v11) == 26 )       // 这里的strlen函数被去符号表解析了
      {
        v3 = 0LL;
        if ( (v11 ^ 0xAB) == list1 )                // 输入的第一个字母:"P",list1这里有关键数据
        {
          while ( (v12[v3] ^ (unsigned __int8)*(&v5 + ((signed int)v3 + 1) % 6)) == byte_6B41D1[v3] )
          {
            if ( ++v3 == 25 )
            {
              printf((unsigned __int64)"Congratulations!");
              return 0;
            }
          }
        }
      }
      printf((unsigned __int64)"Password Wrong!! Please try again.");
      return 0;
    }

      静态分析找到代码,把byte_6841D1和list1那里的关键数据提取出来,直接逆向算法。

    ch=[171,221,51,84,53,239]
    list1=[0x9E,0x67,0x12,0x4E,0x9D,0x98,0xAB,0,6,0x46,0x8A,0xF4,0xB4,6,0x0B,0x43,0xDC,0xD9,0xA4,0x6C,0x31,0x74,0x9C,0xD2,0xA0]
    print(len(list1))
    temp,temp_ch=0,''
    flag=''
    flag+='P'
    for i in range(25):
        temp=list1[i]^ch[(i+1)%6]
        temp_ch=chr(temp)
        print(temp_ch)
        flag+=temp_ch
    print(flag)

     Baby's Crack

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int result; // eax
      char Dest; // [rsp+20h] [rbp-80h]
      FILE *v5; // [rsp+88h] [rbp-18h]
      FILE *File; // [rsp+90h] [rbp-10h]
      char v7; // [rsp+9Fh] [rbp-1h]
      const char **v8; // [rsp+B8h] [rbp+18h]
    
      v8 = argv;
      if ( argc <= 1 )
      {
        printf("Usage: %s [FileName]
    ", *argv, envp);
        printf("FileName是待加密的文件");
        exit(1);
      }
      File = fopen(argv[1], "rb+");
      if ( File )
      {
        v5 = fopen("tmp", "wb+");                   // v5是文件操作符
        while ( feof(File) == 0 )
        {
          v7 = fgetc(File);
          if ( v7 != -1 && v7 )                     // -1表示读取到文件末尾EOF
          {
            if ( v7 > 47 && v7 <= 96 )
            {
              v7 += 53;
            }
            else if ( v7 <= 46 )
            {
              v7 += v7 % 11;
            }
            else
            {
              v7 = 61 * (v7 / 61);
            }
            fputc(v7, v5);
          }
        }
        fclose(v5);
        fclose(File);
        sprintf(&Dest, "del %s", v8[1]);
        system(&Dest);
        sprintf(&Dest, "ren tmp %s", v8[1]);
        system(&Dest);
        result = 0;
      }
      else
      {
        printf("无法打开文件%s
    ", v8[1]);
        result = -1;
      }
      return result;
    }

      这里提供了flag的加密文件flag.enc,从关键代码这里来看,我们只要在字母表中找准对应的映射就可以了。脚本如下:

    # -*- coding: utf-8 -*
    import string
    with open("C://Users//wolf//Desktop//babyscrack//flag.enc",'rb+') as f:
        flag_info=f.read()
    print(flag_info)
    def encrypto(a):
        if a!='xff' and a:
            if ord(a)>47 and ord(a)<=96:
                a=chr(ord(a)+53)
            elif ord(a)<=46:
                a=chr(ord(a)+ord(a)%11)
            else:
                a=chr(61*(ord(a)/61))
        return a
    enc='jeihjiiklwjnk{ljj{kflghhj{ilk{k{kij{ihlgkfkhkwhhjgly'
    print(string.printable)
    flag=""
    for i in enc:
        for j in string.printable:
            if i==encrypto(j):
                flag+=j
                break
    print(flag.decode('hex'))

    stheasy

      这道题有一个小坑点在int8那里,表明是取后8位做抑或。

    signed int __cdecl check(int a1)
    {
      int v1; // eax
      int v3; // edx
    
      if ( a1 )
      {
        v1 = sub_804849C(a1);
        if ( v1 )
        {
          if ( v1 == 29 )
          {
            v3 = 0;
            while ( *(_BYTE *)(a1 + v3) == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
            {
              if ( ++v3 == 29 )
                return 1;
            }
          }
        }
      }
      return 0;
    }
    s="k2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U"
    flag_info=[0x48,0x5D,0x8D,0x24,0x84,0x27,0x99,0x9F,0x54,0x18,0x1E,0x69,0x7E,0x33,
               0x15,0x72,0x8D,0x33,0x24,0x63,0x21,0x54,0x0C,0x78,0x78,0x78,0x78,0x78,0x1B]
    print(len(flag_info))
    print(len(s))
    index,temp,flag,idx=0,"","",[]
    for i in flag_info:
        temp=bin(i/3-2)
        if len(temp)>=10:
            temp=temp[-8:]
        else:
            temp=temp[2:]
        index=int(temp,2)
        idx.append(index)
    for i in idx:
        flag+=s[i-1]
    print(flag)

    1.Hello

      这题有个反调试,但是不影响,静态分析就能出。start函数和dummy函数地址相减的地方注意一下,逻辑写正确即可。

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int result; // eax
      signed int v4; // [rsp+1Ch] [rbp-14h]
      int v5; // [rsp+24h] [rbp-Ch]
    
      v5 = ((unsigned __int64)((char *)start - (char *)dummy) >> 2) ^ flag_data[0];
      result = anti_debug();
      if ( !(result & 1) )
      {
        v4 = 0;
        while ( v4 < 55 )
        {
          flag_data[v4] -= 2;
          flag_data[v4] ^= v5;
          ++v4;
          ++v5;
        }
        result = printf("
    Final output is %s
    ", &flag_data[1]);
      }
      return result;
    }
    flag_data=[0x41, 0x10, 0x11,0x11,0x1B, 0x0A, 0x64, 0x67, 0x6A, 0x68,
                0x62, 0x68, 0x6E, 0x67, 0x68, 0x6B, 0x62, 0x3D, 0x65, 0x6A,0x6A,
                0x3D, 0x68, 0x4, 0x5, 0x8, 0x3, 0x2,0x2, 0x55, 8, 0x5D, 0x61, 0x55,
                0xA, 0x5F, 0x0D, 0x5D, 0x61, 0x32, 0x17, 0x1D, 0x19, 0x1F, 0x18,
                0x20, 0x4, 0x2, 0x12, 0x16, 0x1E, 0x54,0x20,0x13,0x14]
    print(len(flag_data))
    v5=((0xcb0-0xc90)>>2)^flag_data[0]
    v4,flag=0,""
    while(v4<55):
        flag_data[v4]-=2
        flag_data[v4]^=v5
        flag+=chr(flag_data[v4])
        v4+=1
        v5+=1
    print(flag)

    Classical Crackme

      这道题去了符号表,加了返混淆,好像还是C#写的,但是没关系,直接去找字符串常量,发现有一串字符串

       一看就是base64加密的,解密之后就是flag。

    findkey

      这是一道python逆向的题目,直接用IDA看显示的就是字节码。在linux下用file查一下,发现应该是一个pyc,这时候用在线网站进行一步反汇编,拿到源码之后,逆向算法,exp如下所示。

    lookup = [196,153,149,206,17,221,10,217,167,18,36,135,103,61,111,31,92,152,21,228,105,191,
            173,41,2,245,23,144,1,246,89,178,182,119,38,85,48,226,165,241,166,214,71,90,151,3,
            109,169,150,224,69,156,158,57,181,29,200,37,51,252,227,93,65,82,66,80,170,77,49,177,
            81,94,202,107,25,73,148,98,129,231,212,14,84,121,174,171,64,180,233,74,140,242,75,
            104,253,44,39,87,86,27,68,22,55,76,35,248,96,5,56,20,161,213,238,220,72,100,247,8,
            63,249,145,243,155,222,122,32,43,186,0,102,216,126,15,42,115,138,240,147,229,204,117,
            223,141,159,131,232,124,254,60,116,46,113,79,16,128,6,251,40,205,137,199,83,54,188,19,
            184,201,110,255,26,91,211,132,160,168,154,185,183,244,78,33,123,28,59,12,210,218,47,
            163,215,209,108,235,237,118,101,24,234,106,143,88,9,136,95,30,193,176,225,198,197,194,
            239,134,162,192,11,70,58,187,50,67,236,230,13,99,190,208,207,7,53,219,203,62,114,127,
            125,164,179,175,112,172,250,133,130,52,189,97,146,34,157,120,195,45,4,142,139]
    pwda = [188,155,11,58,251,208,204,202,150,120,206,237,114,92,126,6,42]
    pwdb = [53,222,230,35,67,248,226,216,17,209,32,2,181,200,171,60,108]
    
    flag,temp="",0
    for i in range(0,17):
        temp=lookup[i+pwdb[i]]-pwda[i]&255
        flag+=chr(temp)
    flag=flag[::-1]
    print(flag)

    软件密码破解-1

      这道题肯定用strip把符号表全部都去掉了。静态分析的时候,修复符号表当然是一种思路,但是还是不够,我修复了大概7000个函数,还是很难找到关键代码,而且在IDA中找不到程序运行过程中出现过的一些字符串。这种时候,直接用OD的中文搜索引擎去找一些特殊的字符串,找到“你赢了”,然后很快地就可以定位到关键代码段。

       脚本如下。

    array_1=[0x1b,0x1c,0x17,0x46,0xf4,0xfd,0x20,0x30,0xb7,0xc,0x8e,0x7e,0x78,0xDE]
    array_2=[0xff,0x1a,0x4e,0xe4,0x53,0xe3,0x51,0x65,0x8f,0x93,0x6B,0x64,0x57,0x28]
    array_2=array_2[::-1]
    flag,temp="",0
    for i in range(14):
        temp=array_1[i]^array_2[i]
        flag+=chr(temp)
    print(flag)

     

  • 相关阅读:
    (转)const变量通过指针修改问题
    sleep wait yeild join
    做事贵在坚持
    我的学习进度
    织梦dedecms后台添加图片style全部都变成st<x>yle的解决办法
    调用DEDE日期时间格式整理大全
    Arcgis andoid开发之应用百度地图接口实现精准定位与显示
    jquery自定义插件——window的实现
    lzugis—搭建属于自己的小型的版本控制SVN
    lzugis——Arcgis Server for JavaScript API之自定义InfoWindow
  • 原文地址:https://www.cnblogs.com/L0g4n-blog/p/13724997.html
Copyright © 2020-2023  润新知