android逆向基本常用操作

本篇总结于2018.5.12的ctf与安卓逆向看雪书籍1,2,8章

adb用法:http://xn--74q78i15hxv3arigm4e.cn/2018/04/24/root%E4%B8%8Eadb/

静态分析

手动分析

apk拆包

一般使用官方的apktool即可
指令:apktool d apk名 -o 输出文件名

mali/baksmali 针对单个dex文件更好。

拆包后

含有smail代码及资源,注意其对string资源的引用为id索引。目前修改java层的代码只能在这里改smail

静态ida HexView改so的内容后,点击”Edit->Plugins->modifyfile”,然后就可以保存新的so文件了。

问题:改dex的其它方案?如何dump内存内的dex/so?。

apk打包

apktool b 文件名
会把打包好的文件输出到文件下的dist目录

签名

用已加好的bat脚本启动signapk.jar
signapk apk名 即可完成签名
注意一点在win下不加入path的程序,当前目录要写全才可以运行(./xxx)和linux下一样。
win下\分割 linux下/分割

一键式分析

java-拖入jeb
c/c++-拖入ida

动态分析

java层

AS动态调试smali
成功
参见之前的博客:android动态调试-java层http://xn--74q78i15hxv3arigm4e.cn/2018/04/29/android%E5%8A%A8%E6%80%81%E8%B0%83%E8%AF%95-java%E5%B1%82/
用AS加插件或者jeb都好使的很
DDMS:log可设置过滤器查看。点击Start Method Profiling可以获取一段时间的函数调用过程。

原理:java代码调试接口:JDWP是传统java虚拟机调试java的协议,dalvik也实现了该接口。启用调试的da虚拟机(需要指令adb shell am start -D -n)会启动JDWP调试线程,系统属性ro.debuggable为1时所有程序都可以开启调试支持(不用分别改android:debuggable了),我个人理解为adb负责转发android环境到DDMS,DDMS自带端口转发功能,将对java的调试信息通过指定端口(8700)转发到对应的调试线程中。
线程->adb->DDMS转发端口->java调试器

jeb
成功
jeb可调试smali,不可调试java与so。
最初adb shell am start -D -n packageName/ActivityName或者debugger开启下直接运行,之后找到pid附加即可。注意以下几点:先下断点在smali再attach,断点才可以使用。可查看线程与运行时数据,F6为单步

c/c++层

ida的debugger->run/attach选项只有不加载文件时才有。
前提:
将ida的android_server复制到android设备中执行。并转发本地端口到设备端口。

1
2
3
4
5
6
7
8
放server这个文件路径随意
adb push android_server /data/local/tmp
adb shell chmod 777 /data/local/tmp/android_server
运行server
adb shell su /data/local/tmp/android_server
转发端口
adb forward tcp:23946 tcp:23946

执行android_server提示中指明了端口号,用adb forward tcp:xxx tcp:xxx 转发pc端口(参一)到android(参二)。

执行已有原生程序:
成功
注意生成native程序时Android.mk加如下语句,否则Android 5.0 and later only support position-independent executables (-fPIE).是android5.0之后随机分配程序的内存地址机制

1
2
LOCAL_CFLAGS += -pie -fPIE
LOCAL_LDFLAGS += -pie -fPIE

  1. 前提完成,且要调试的文件放入android并保证可以运行
  2. 打开ida不加载文件。
  3. debugger->Run->Remote即可运行调试原生程序。需要填入目标程序在android的全路径和目标程序所在目录,本地端口填localhost 之前写的那个pcXXX。ida会自动加载分析该文件并执行(知道模块的文件位置即可加载分析)

调试so库俩种方式
直接附加app的开始
成功
此方法一般脱壳用,从应用的一开始加载调试。dump(自己写ida脚本)内存取出正确的dex与so

  1. 前提完成,apk安装
  2. adb shell am start -D -n packageName/ActivityName开启android进程调试状态
  3. adb forward tcp:8700 jdwp:PID(目标应用的进程号)转发pc端口到android指定调试进程(这就是DDMS的功能之一)
  4. ida->debugger->attach->localhost(此时可设置debug options设置ida断点位置,比如在加载so时停下,可分析一个app的所有过程经测试不管用,要在进入调试窗口后的debugger->debugger options中设置有用,加载so时会直接断在linker中)->指定目标进程附加,此时该进程会处于ida调试之中。
  5. jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700(jdb进行附加)这个就是java层的调试原理,通过java调试协议JDWP运行该应用,此时jdb调试与应用一起被ida中断
  6. 此时ida中就可以使用od调试方法了。

静态分析so后附加进程
成功
此方法用于已经有了so文件,停在so文件指定的位置。

  1. 前提完成,apk安装。
  2. 首先打开ida加载指定so,找到需要调试的函数并记住函数的地址
  3. 运行应用并保证要调的模块已经加载(此时JNI_Onload()什么的已经执行了)
  4. ida->debugger->selectdebugger->..->process option设置localhost。但其他的不用改,那是指定应该匹配什么so文件用的之后会匹配对应模块
  5. ida->debugger->Attach to process。之后选择要附加的进程进行附加,附加成功后弹出模块找不到错误(大概为ida找不到模块的代码文件(已加载进程序的so,ida不知其路径,而对于之前的可执行程序有路径就可分析文件中的代码))但是有一个模块可选same按钮,这是识别出进程中某模块和本地ida分析的文件名相同
  6. ctrl+s找到与目标so同名的模块code区记住其start地址,按G跳到该地址加之前记住的函数地址处即可找到该函数,断点即可。
  7. android中触发原生函数,即可中断开始调试