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

Jeb打开apk

关键代码在Native函数getResult

IDA 打开 so

发现代码比较简单,可以直接静态分析。

输出字符串也就是flag 长度是15,然后分成三段,第一段是可以整除3,第二段是除3取余=1,第三段是除3取余等于2;

cpp 复制代码
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";

cpp 复制代码
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

java 复制代码
        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" ,

cpp 复制代码
for ( i = 0; i != 4; ++i )
      v6[i] ^= v5[i];
    if ( !strcmp(v6, a5A) )

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

java 复制代码
        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位直接照搬是"}"

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

可以计算出第三段 是 asoy}

java 复制代码
        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}

完整计算代码:

java 复制代码
    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);
    }
相关推荐
丘狸尾2 小时前
[cisco 模拟器] ftp服务器配置
android·运维·服务器
van叶~4 小时前
探索未来编程:仓颉语言的优雅设计与无限可能
android·java·数据库·仓颉
Crossoads8 小时前
【汇编语言】端口 —— 「从端口到时间:一文了解CMOS RAM与汇编指令的交汇」
android·java·汇编·深度学习·网络协议·机器学习·汇编语言
li_liuliu9 小时前
Android4.4 在系统中添加自己的System Service
android
C4rpeDime11 小时前
自建MD5解密平台-续
android
鲤籽鲲13 小时前
C# Random 随机数 全面解析
android·java·c#
m0_5485147717 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯17 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯17 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐18 小时前
Handle
android