Toast.makeText(this, "Toast text", 1).show();
const-string v0, "Toast text"
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
利用Log日志输出
Log.v("android_log","test")
smail代码
const-string v0, "test"
const-string v3, "android_log"
invoke-static {v3,v0}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
整数转字符串代码
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v5
new Exception("print trace").printStackTrace();
smail代码
new-instance v0, Ljava/lang/Exception;
const-string v1, "print trace"
invoke-direct {v0,v1}, Ljava/lang/Exception;-><init>(Ljava/lang/String;)V
invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V
android.os.Debug.startMethodTracing("123")
func():
android.os.Debug.stopMethodTracing():
smai代码
可以插入OnCreate()方法中
const-string v0, "123"
invoke-static {v0}, Landroid/os/Debug;->startMethodTracing(Ljava/lang/String;)V
插入OnStop()方法
invoke-static {}, Landroid/os/Debug;->stopMethodTracing()V
注入需要加sd写入权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
adb pull /mnt/sdcard/123.trace
traceview 123.trace
20段:是否带S标志位,如果不带该位为0,指令带S标志位为1
16-19段:保留位,一般都设置为0000
12-15段:指令中目的寄存器,根据R0-R15对应0-15比如r1对应为0001,R0对应0000
0-11段:指令的操作数,如果为立即数有十进制转换为二进制代码即可,如果是寄存器,同R0-R15对应0-15
例如下面两个指令
指令一 mov r1, #107
对应机器码
1110 00 1 1101 0 0000 0001 000001101011
对应十六进制
E3 A0 10 6B
对应十六进制编辑器中的值
6B 10 A0 E3
指令二 mov r2,r1
对应机器码
1110 00 0 1 101 0 0000 0010 000000000001
对应十六进制
E1 A0 20 01
对应十六进制编辑器中的值
01 20 A0 E1
下面是arm指令的标准格式如下:
常用的跳转指令B和机器码直接的转换
28-31段cond: 指令执行的条件编码
pediy上的一个例子:
.text:00637C80 E5 34 42 EB BL __mulsf3
.text:016C501C EXPORT __mulsf3
BL __mulsf3的机器码为((0x16C501C-0x637C80)-8)/4=4234E5
BL为带连接无条件跳转机器码为1110 1011 对应16进制为EB故BL __mulsf3对应的机器码为EB4234E5,在十六进制编辑器中显示的情况就是E5 34 42 EB。也就是第一条之类中间的机器码相同。
动态调试
利用IDA动态调试方法(来自:Android软件安全与逆向分析)
调试原生程序
1.动态调试一般的Android原生程序
实例程序:debugnativeapp
在Android设备中添加、配置android_server程序
先将IDA目录下的./dbgsrv/android_server程序拷贝到Android设备下:
adb push ./dbgsrv/android_server /data/local/tmp/
配置文件权限属性,使其为可执行文件:
adb shell chmod 755/data/local/tmp/android_server
2将实例程序添加到Android设备
adb push debugnativeapp/data/local/tmp/
adb shell chmod 755/data/local/tmp/debugnativeapp
3启动调试服务
adb shell/data/local/tmp/android_server
4进行端口转发,使PC端口与Android端口可进行交互
adb forward tcp:23946tcp:23946
5启动IDA,进行程序调试
启动IDA的32bit程序,点击:Debugger-Run-RemoteArmLinux/Android debugger,打开调试程序的设置对话框:
Application:对应调试程序所在的路径
Directory:对应调试程序所在的目录路径
HostName:输入localhost,Port:PC端口
调式动态链接库
实例:debugjniso.apk
1.将apk安装在设备中,运行后界面如下,点击“设置标题”按钮,便会调用动态链接库libdebugjniso.so中的jniString()方法返回一个修改标题栏的字符串。在分析加壳程序的壳时,应以调试方式来启动调试程序(adb shell am start-D -n packagename/activityname)
2.启动调试服务,进行端口转发
adb shell /data/local/tmp/android_server
adb forward tcp:23946 tcp:23946
3.启动IDA进行程序调试
点击Debugger-Attach-RemoteArmLinux/Android debugger,打开设置框
HostName:输入localhost,Port:对应PC端口
点击OK,便会弹出附加Android进程的对话框,选中进程com.droider.debugjniso
4.使用jdb来连接上apk的java层
jdb -connectcom.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8601
5.确定jniString()方法当前的基地址
回到调试的IDA,使用Ctrl+S快捷键打开段选择对话框,可查找到libdebugjniso.so当前的基地址为:4B1F2000(随加载改变)
6.定位到jniString()方法的程序位置
由内存地址=基地址+偏移地址(4b1f2000:00000c38),可得当前jniString()方法的内存地址为:0x4b1f2c38,使用快捷键G打开地址跳转框,输入内存地址
7.设定断点,进行调试
跳转在jniString()方法的程序位置,在0x4b1f2c38行设置断点(F2)