Android逆向题解-攻防世界easyso

jeb反编译apk

输入字符串传入到native方法CheckString进行判断。
核心逻辑都在so里面的CheckString函数。
在这里插入图片描述
在这里插入图片描述

ida反编译so

直接反编译看伪代码,代码比较简单直接手撕即可,循环走一两遍就可以知道整个逻辑了。
整理逻辑流程就是输入字符串前16位与后16位互换。
然后单双位互换,0,1互换,2,3互换,4,5互换。。。
最后与指定字符串比较。

bool __fastcall Java_com_testjava_jack_pingan2_cyberpeace_CheckString(JNIEnv *a1, jobject a2, jstring a3)
{
  const char *v3; // x20
  __int64 v4; // x0
  signed int v5; // w21
  unsigned __int64 v6; // x22
  _BYTE *v7; // x0
  _BYTE *v8; // x19
  size_t v9; // w2
  unsigned __int64 v10; // x20
  _BYTE *v11; // x8
  char v12; // w9
  char v13; // w10
  char v14; // w9
  __int64 v15; // x20
  _BYTE *v16; // x8
  char v17; // w10
  unsigned __int64 v18; // x0
  unsigned __int64 v19; // x8

  v3 = (*a1)->GetStringUTFChars(a1, a3, 0LL);   // 输入字符串
  v4 = strlen(v3);                              // 字符串长度
  v5 = v4;
  v6 = ((v4 << 32) + 0x100000000LL) >> 32;      // v6 = v4 +1
  v7 = malloc(((v4 << 32) + 0x100000000LL) >> 32);
  v8 = v7;
  if ( v6 > v5 )
    v9 = v6 - v5;                               // v9 = 1
  else
    v9 = 0;
  memset(&v7[v5], 0, v9);
  memcpy(v8, v3, v5);                           // 输入字符复制到v8
  if ( strlen(v8) >= 2uLL )
  {
    v10 = 0LL;
    do
    {
      v11 = &v8[v10];                           // v11 = &v8[0]--循环1--v10=1, v11 = v8[1]
      v12 = v8[v10 + 16];                       // v12 = v8[16]--循环1--v12 = v8[17]
      v13 = v8[v10++];                          // v13 = v8[0],v10=1--循环1--v13 = v8[1],v10  =2
      *v11 = v12;                               // v11 = v8[16] --循环1--v11 = v8[17]
      v11[16] = v13;                            // v11[16] = v8[0] --循环1-- v8[17] = v8[1]
    }                                           // v8[0]与v8[16]互换,循环1--v8[1]与v8[17]互换。。。
                                                // 这段循环的逻辑就是前16位与后16位互换
    while ( strlen(v8) >> 1 > v10 );            // v8的长度/2 > v10 , 就是循环v8的长度/2
  }
  if ( *v8 )
  {
    v14 = v8[1];                                // v14 = v8[1]
    v8[1] = *v8;                                // v8[1] = v8[0]
    *v8 = v14;                                  // v8[0] = v8[1]
                                                // 这段逻辑就是v8[0]与v8[1]互换
    if ( strlen(v8) >= 3uLL )
    {
      v15 = 0LL;
      do
      {
        v16 = &v8[v15];                         // v16 = &v8[0]
        v17 = v8[v15 + 2];                      // v17 = v8[2]
        v16[2] = v8[v15 + 3];                   // v8[2] = v8[3]
        v16[3] = v17;                           // v8[3] = v8[2]
        v18 = strlen(v8);
        v19 = v15 + 4;                          // v19 = 4
        v15 += 2LL;                             // v15 = 2
      }                                         // 这一段循环的逻辑就是单双位互换,0,1互换,2,3互换,4,5互换。。。
      while ( v18 > v19 );                      // v18是v8的长度,v19 = v15 + 4, v15是自加2,那v19也是自加2,也就是循环是自加2循环
    }
  }
  return strcmp(v8, "f72c5a36569418a20907b55be5bf95ad") == 0;// 最后v8与指定字符串比较
}

算法还原

还原过程就是指定的字符串“f72c5a36569418a20907b55be5bf95ad”先单双位互换得到“7fc2a5636549812a90705bb55efb59da”
然后前16位与后16位互换得到
flag{90705bb55efb59da7fc2a5636549812a}

    public static void main(String[] args) {
        String string = "f72c5a36569418a20907b55be5bf95ad";
        char[] chars = new char[string.length()];
        for (int i = 0; i < string.length(); i+=2) {
            chars[i] = string.charAt(i+1);
            chars[i+1] = string.charAt(i);
        }

        char[] ch2 = new char[chars.length];
        for (int i = 0; i < 16; i++) {
            ch2[i] = chars[i+16];
            ch2[i+16] = chars[i];
        }
        System.out.println(ch2);
    }
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android逆向小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值