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);
    }
相关推荐
百锦再1 小时前
Android Studio开发 SharedPreferences 详解
android·ide·android studio
青春给了狗1 小时前
Android 14 修改侧滑手势动画效果
android
CYRUS STUDIO1 小时前
Android APP 热修复原理
android·app·frida·hotfix·热修复
火柴就是我2 小时前
首次使用Android Studio时,http proxy,gradle问题解决
android
limingade2 小时前
手机打电话时电脑坐席同时收听对方说话并插入IVR预录声音片段
android·智能手机·电脑·蓝牙电话·电脑打电话
浩浩测试一下3 小时前
计算机网络中的DHCP是什么呀? 详情解答
android·网络·计算机网络·安全·web安全·网络安全·安全架构
青春给了狗4 小时前
Android 14 系统统一修改app启动时图标大小和圆角
android
pengyu5 小时前
【Flutter 状态管理 - 柒】 | InheritedWidget:藏在组件树里的"魔法"✨
android·flutter·dart
居然是阿宋6 小时前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin
凉、介6 小时前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci