HNHuangJingYU 发表于 2021-9-30 10:27

《攻防世界》MOBILE--首题--easy-so

本帖最后由 HNHuangJingYU 于 2021-9-30 10:32 编辑

首先将easy-so.apk拉进jeb进行静态分析:
1.入口界面发现只有一个so层的函数进行判断输入,嗯解题思路很明显

2.将so拉进IDA进行分析,根据so层的函数加密逆向过来,因为是静态函数所以很容易就找到,对CheckString函数进行分析(大多数思路我都会在代码旁边进行注释,大家看代码就行)

3. 再来到j_TestDec函数、再进去TestDec函数,代码加密其实就是两个循环进行位置互换,因为只是位置互换所以我们只要按着顺序去倒回来就行(逆向算法大概都是这种思路)size_t __fastcall TestDec(const char *a1)
{
char *string; // r4
size_t index; // r5
int v3; // r1
unsigned __int8 v4; // r0
size_t result; // r0
int index2; // r5
int v7; // r0
unsigned __int8 v8; // r1
unsigned int v9; // r1

string = a1;
if ( strlen(a1) >= 2 )                        // 字符长度至少2位
{
    index = 0;
    do
    {
      v3 = &string;                      // 取字符串单个的地址
      v4 = string;
      string = string;
      ++index;
      *(v3 + 16) = v4;                        // 将v4赋值给在地址16个单元处的单元值
    }
    while ( index < strlen(string) >> 1 );      // 索引自增后是否小于右移后的字符长度
}
result = *string;                           // *string 等价于 stirng
if ( *string )                              // string不为0
{
    *string = string;                        // 这里索引0和索引1进行位置变换
    string = result;
    result = strlen(string);
    if ( result >= 3 )
    {
      index2 = 0;
      do
      {
      v7 = &string;
      v8 = string;                // 这里的逻辑也是对字符串进行位置交换
      *(v7 + 2) = string;         // 这里因为v7被赋值了&string所以v7这里是地址,然后取地址+2个单元的数据值那么就是string
      *(v7 + 3) = v8;
      result = strlen(string);
      v9 = index2 + 4;
      index2 += 2;
      }
      while ( v9 < result );
    }
}
return result;
}
4. 算法还原:@Test
    public void demo1() {
      String data = "f72c5a36569418a20907b55be5bf95ad";
      char[] chars = data.toCharArray();
      int index2 = 0;
      int result;
      int v9;
      char v8;
      do {
            v8 = chars;
            chars = chars;
            chars = v8;
            result = chars.length;
            v9 = index2 + 4;
            index2 += 2;
      }
      while (v9 < result);
      result = chars;
      chars = chars;
      chars = (char) result;

      int index = 0;
      char v4;
      do {
            v4 = chars;
            chars = chars;
            chars = v4;                        // 将v4赋值给在地址16个单元处的单元值
            ++index;
      }
      while (index < chars.length >> 1);
      System.out.println("得到flag");
      System.out.println(chars);
    }

      //得到flag90705bb55efb59da7fc2a5636549812a
下次尽量用C/C++写脚本,C++基础太重要了

zhanglei0546 发表于 2021-9-30 14:03

感谢分享

aonima 发表于 2021-9-30 20:16

感谢分享!

xunxunmimi0936 发表于 2021-10-1 14:23

非常感谢分享。

坎德沃 发表于 2021-10-8 09:53

感谢楼主的细致教程,另外我很想知道这些逆算法是怎么思考出来的,然后如果要提升这方面怎么去学

wantwill 发表于 2021-10-19 17:20


感谢分享!
页: [1]
查看完整版本: 《攻防世界》MOBILE--首题--easy-so