目标

打开app:

image.png

我们的目标是模拟点击LV2按钮所执行的 so 中的算法逻辑。

IDA分析

反汇编代码如下:

int __fastcall Java_com_sec_udemo_MainActivity_sign_1lv2(_JNIEnv *a1, int a2, int a3)
{
  const char *v3; // r0
  int v5; // [sp+4h] [bp-8Ch]
  const char *v6; // [sp+Ch] [bp-84h]
  int StringUTFChars; // [sp+28h] [bp-68h]
  char v10[12]; // [sp+38h] [bp-58h] BYREF
  char v11[64]; // [sp+44h] [bp-4Ch] BYREF

  StringUTFChars = _JNIEnv::GetStringUTFChars(a1, a3, 0);
  sub_9D84(v10, StringUTFChars);
  _JNIEnv::ReleaseStringUTFChars(a1, a3, StringUTFChars);
  memset(v11, 0, sizeof(v11));
  v3 = (const char *)sub_9DE6(v10);
  sign_lv2(v3, v11);
  v6 = (const char *)sub_9DE6(v10);
  _android_log_print(3, "udemo", "sign_1lv2 was called. sign data:%s sign:%s", v6, v11);
  v5 = _JNIEnv::NewStringUTF(a1, v11);
  std::string::~string(v10);
  return v5;
}

在LV1里面,我们模拟的方式是很取巧的,绕过了很多方法的调用。

这次,我们的目标是完整的模拟 Java_com_sec_udemo_MainActivity_sign_1lv2 这个 JNI 函数。

模拟so中的指令需要准备什么

选择架构

Android 上常见的架构是:

加载内存和段

.so 文件通常是 ELF 格式,包含多个段(如 .text.data.bss)。你需要解析 ELF 文件并将段加载到模拟器内存中,还要处理 so 中的符号解析。

初始化寄存器

根据模拟目标,设置必要的寄存器: