美文网首页
Android逆向 之 IDA静态分析so(一)

Android逆向 之 IDA静态分析so(一)

作者: Sharkchilli | 来源:发表于2020-06-10 17:00 被阅读0次

概述

本文使用IDA对android调用so进行静态分析,以此实验掌握so层的一些分析技巧。

前置条件

ARM 汇编 (虚拟机为armebi-v7a)
IDA的基本使用
JNI开发基础

Android中调用so

# direct methods
# 加载so库
.method static constructor <clinit>()V
    .locals 1

    .prologue
    .line 26
    const-string v0, "verify"

    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

    .line 27
    return-void
.end method

#定义native 方法
.method public native verify([B)Ljava/lang/String;
#调用so层方法
invoke-virtual {v1, v2}, Lcom/example/cctf/MainActivity;->verify([B)Ljava/lang/String;

当我们反编译java代码为smali代码,看到以上类似的代码,就应该能猜得其关键逻辑是在so层进行处理的,这个时候我们就需要对so进行调试分析。

静态分析

so文件一般在apk中的lib文件夹中,将其解压出来,丢到IDA进行静态分析。


image.png image.png image.png

进入Exports

image.png
可以看到有一个JNI_OnLoad且没有以java开头的导出函数,所以这里基本可以断定是动态注册。

进入后代码如下:

image.png
我们先使用IDA 导入C/C++头文件,添加头文件中的结构体,使用此结构体中的函数替换反汇编中的偏移,使文件可读性更好
点击IDA Pro 主界面上的“Structures”选项卡 然后按下Insert键打开“Create structure/union”对话框,点击界面上的"Add standard structure"按钮,在打开的结构体选择对话框中选择JNINativeInterface并点击OK返回,同理JNIInvokeInterface结构体_JNIEnv和_JavaVm也导入进来;
image.png
image.png

如果没有结构体请导入jni.h头文件,可参考以下教程:
报错的h文件都注释掉就好了。
https://blog.csdn.net/u010382106/article/details/44960243

这时候回到汇编窗口,右键相关函数就可以转成对应的方法了:


image.png

按F5进入,c/c++窗口:
将函数的参数转化为正确的参数,鼠标点击参数,然后右键选中 Convert to Struct *

image.png

这里当然转成JavaVM


image.png
#其中代码如下,我们可以猜测到v6为JNIEnv
!a1->functions->GetEnv((JavaVM *)a1, (void **)&v6, 65540)

将v6转成JNIEnv

#这句可以知道v3也是JNIEnv
v3 = v6

最终分析代码如下:

int __fastcall JNI_OnLoad(_JavaVM *a1, int a2, int a3)
{
  _JNIEnv *v3; // r5@2
  int v4; // r1@3
  int result; // r0@4
  _JNIEnv *v6; // [sp+4h] [bp-14h]@1
  int v7; // [sp+8h] [bp-10h]@1

  v7 = a3;
  v6 = 0;
  if ( !a1->functions->GetEnv((JavaVM *)a1, (void **)&v6, 65540)
    && (v3 = v6) != 0
    && (v4 = ((int (*)(void))v6->functions->FindClass)()) != 0 )
  {
  //这里RegisterNatives原型为functions->RegisterNatives(this, clazz, methods, nMethods); 
  //由此可以知道 
  //v4是类名称
  //off_4014是注册native数组的地址
  //1 是数组的个数
    result = (((int (__fastcall *)(_JNIEnv *, int, char **, signed int))v3->functions->RegisterNatives)(
                v3,
                v4,
                off_4014,
                1) >> 31) | 0x10004;
  }
  else
  {
    result = -1;
  }
  return result;
}

我们现在知道了off_4014是注册native数组的地址,我们就进去看看它组成的函数地址在哪

image.png
可以看出这个就是Android代码中调用的函数
刚好都是4个字节,直接进入byte_CA5中,这个就是我们的verify函数地址: image.png

这里大家应该都看不懂了,我也看不懂了0.0。
这是因为ida把它识别为了数据,我们先设置一下16进制代码显示。
在Option->General中,设置为4bytes:


image.png

效果如下:


image.png

现在我们在函数开始地址按快捷键C将代码翻译为,ARM汇编。


image.png
结果是这样的,这汇编代码一看就不对劲啊!
这是因为这一段代码是thumb指令,而ida识别为arm指令集了

修改:按alt+G,然后让value=1 为thumb指令,= 0为arm指令。


image.png

修改后如下:


image.png

在代码入口,右键creat fun
按F5进入c和c++代码

image.png

这个其实依然不是真正的代码,所以要结合下一章动态调试分析

相关文章

网友评论

      本文标题:Android逆向 之 IDA静态分析so(一)

      本文链接:https://www.haomeiwen.com/subject/aimutktx.html