Android逆向题解 攻防世界难度4- Android2.0

Jeb打开apk

关键代码在Native函数getResult
在这里插入图片描述

IDA 打开 so

发现代码比较简单,可以直接静态分析。
输出字符串也就是flag 长度是15,然后分成三段,第一段是可以整除3,第二段是除3取余=1,第三段是除3取余等于2;

bool __fastcall Java_com_example_test_ctf03_JNI_getResult(JNIEnv *a1, int a2, int a3)
{
  int v3; // r4
  const char *v4; // r8
  char *v5; // r6
  char *v6; // r4
  char *v7; // r5
  int i; // r0
  int j; // r0


  v3 = 0;
  v4 = (*a1)->GetStringUTFChars(a1, a3, 0); //输入字符串
  if ( strlen(v4) == 15 )                   //判断输入字符串长度==15
  {
    v5 = malloc(1u);
    v6 = malloc(1u);
    v7 = malloc(1u);
    Init(v5, v6, v7, v4, 15);       //输入字符串分成三段
    if ( !First(v5) )               //第一部分比较
      return 0;
    for ( i = 0; i != 4; ++i )
      v6[i] ^= v5[i];
    if ( !strcmp(v6, " 5-\x16a") )  //第二部分比较
    {
      for ( j = 0; j != 4; ++j )
        v7[j] ^= v6[j];
      return strcmp(v7, "AFBo}") == 0;  //第三部分比较
    }
    else
    {
      return 0;
    }
  }
  return v3;
}

Init 字符串分成三段
int __fastcall Init(int result, char *a2, char *a3, const char *a4, int a5)
{
  int v5; // r5
  int v6; // r10
  int v7; // r6
  if ( a5 < 1 )
  {
    v6 = 0;
  }
  else
  {
    v5 = 0;
    v6 = 0;
    do
    {
      v7 = v5 % 3;
      if ( v5 % 3 == 2 )   //除3取余 == 2 是第3段
      {
        a3[v5 / 3u] = a4[v5];
      }
      else if ( v7 == 1 ) //除3取余 == 1 是第2段
      {
        a2[v5 / 3u] = a4[v5];
      }
      else if ( !v7 )
      {
        ++v6;
        *(result + v5 / 3u) = a4[v5];  //除3是第1段
      }
      ++v5;
    }
    while ( a5 != v5 );
  }
  *(result + v6) = 0;
  a2[v6] = 0;
  a3[v6] = 0;
  return result;
}

计算第一段

就是一个异或运算,注意这里只计算了4位,第5位不用算就是“l”;

First处理第一段
bool __fastcall First(char *a1)
{
  int i; // r1
  for ( i = 0; i != 4; ++i )
    a1[i] = (2 * a1[i]) ^ 0x80;  //经过运算后判断是否== LN^dl ,先乘以2再异或0x80, 反推就是用 LN^dl先异或0x80再除以2
  return strcmp(a1, "LN^dl") == 0;
}

可以算出第一段的值是 fgorl

        char[] chars = new char[]{'L','N','^','d','l'};
        char[] res = new char[5];
        for (int i = 0; i < 4; i++) {
            res[i] = (char) ((chars[i] ^ 0x80)/2);
        }
        res[4] = 'l';
        System.out.println(res);

计算第二段

第二段也是一个异或,同样也只算4位,第5位不用异或计算。注意这里的v5 不是上面计算出来的第一段的值,是上面异或之后的也就是“LN^dl” ,

for ( i = 0; i != 4; ++i )
      v6[i] ^= v5[i];
    if ( !strcmp(v6, a5A) )

可以算出第二段的值 是 l{sra

        char[] c2 = new char[]{0x20,0x35,0x2D,0x16,0x61}; //a5A
        char[] r2 = new char[5];
        for (int i = 0; i < 4; i++) {
            r2[i]  = (char) (chars[i]^c2[i]); //chars 是上面的 LN^dl
        }
        r2[4] = 0x61;
        System.out.println(r2);

计算第三段

一样的套路,还是异或计算4位,第5位直接照搬是“}”

      for ( j = 0; j != 4; ++j )
        v7[j] ^= v6[j];
      return strcmp(v7, "AFBo}") == 0;

可以计算出第三段 是 asoy}

        char[] c3 = new char[]{0x41, 0x46, 0x42, 0x6F, 0x7D}; // "AFBo}"
        char[] r3 = new char[5];
        for (int i = 0; i < 4; i++) {
            r3[i] = (char) (c2[i] ^  c3[i]);
        }
        r3[4] = 0x7D;
        System.out.println(r3);

组合起来就是flag

三段数据组合起来就是flag了
第一段:fgorl -------------整除3,对应的下标就是0,3,6,9,12
第二段:l{sra -------------除3余1,对应下标就是1,4,7,10,13
第三段:asoy} -------------除3余2,对应下标就是2,5,8,11,14
组合结果就是:flag{sosorryla}
完整计算代码:

    public static void main(String[] args) {
        char[] chars = new char[]{'L','N','^','d','l'};
        char[] res = new char[5];
        for (int i = 0; i < 4; i++) {
            res[i] = (char) ((chars[i] ^ 0x80)/2);
        }
        res[4] = 'l';
        System.out.println(res);

        //第二段
        char[] c2 = new char[]{0x20,0x35,0x2D,0x16,0x61};
        char[] r2 = new char[5];
        for (int i = 0; i < 4; i++) {
            r2[i]  = (char) (chars[i]^c2[i]);
        }
        r2[4] = 0x61;
        System.out.println(r2);

        //第三段
        char[] c3 = new char[]{0x41, 0x46, 0x42, 0x6F, 0x7D};
        char[] r3 = new char[5];
        for (int i = 0; i < 4; i++) {
            r3[i] = (char) (c2[i] ^  c3[i]);
        }
        r3[4] = 0x7D;
        System.out.println(r3);

        //还原
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 5; i++) {
            stringBuilder.append(res[i]);
            stringBuilder.append(r2[i]);
            stringBuilder.append(r3[i]);
        }
        System.out.println(stringBuilder);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Android逆向小菜鸡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值