非首发- 作者本人
由一道ctf题目来学习一下这项基本的技术。
本次题目来自NSSCTF-2nd
想到了可以用smali修改来做,顺带记录了一下(两种方法)
smali日志打印本质在于打印输出关键信息,先介绍一下smali语法
smali学习
Smali是一种基于Java语法的反汇编语言,用于描述Android应用程序的Dalvik虚拟机指令集。它可以被用来反编译已安装在Android设备上的应用程序,或者对APK(Android安装包)文件进行静态分析。
Smali代码是一种基于文本的格式,它将Dalvik指令和Java代码结合起来,以可读的方式表示Android应用程序的类、方法、字段等信息。Smali代码使用了逆波兰表示法(Reverse Polish Notation)来表示指令和操作数。
以下是一个简单的Smali代码示例,展示了一个计算两个整数之和的方法:
.class public HelloWorld
.super Ljava/lang/Object;
.method public static add(II)I
.registers 3
add-int/2addr v0, v1 ; 将v0和v1相加,并将结果保存在v0中
return v0 ; 返回结果
.end method
上述代码定义了一个名为HelloWorld的公共类,其中包含一个名为add的静态方法。该方法接受两个整数参数,并返回它们的和。在方法体中,使用了指令add-int/2addr将两个寄存器中的值相加,并将结果保存在第一个寄存器中,然后使用return指令将结果返回。
通过编写和阅读Smali代码,可以深入了解Android应用程序的内部结构和运行机制,并进行诸如应用逆向工程、代码分析和修改等操作。
Android的debuggable属性
在Android开发中,debuggable是一个应用程序清单文件(AndroidManifest.xml)中的属性,用于控制应用程序是否可以进行调试。
当将debuggable属性设置为true时,应用程序将允许使用调试器进行调试,包括在开发环境中使用Android Studio进行断点调试、查看变量值和执行步骤等操作。
以下是一个示例的应用程序清单文件(AndroidManifest.xml),展示了如何设置debuggable属性:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:debuggable="true"
...>
...
</application>
</manifest>
需要注意的是,将debuggable属性设置为true可能会增加应用程序的安全风险
一般开发的app设置为false
log日志插桩技术
Log插桩指的是反编译APK文件,在对应的smali文件里添加相应的smali代码,将程序中的关键信息,以log日志的形式进行输出。
我们要注意参数问题
然后使用Android killer 插件来插入
使用ddms工具即可看到回显:
一定要注意插入过程中的寄存器问题哦
下面开始实现
1、samli修改跳转+赋值
app自己开了debug
使用aapt获得启动包名
smali修改,调用目标函数直接传参数
我的Android killer有点小问题,只能结合jdax来进行定位分析
Android killer上手修改
if-ne v1,v2 ;v1!=v2则跳转
if-eq v1,v2 ;v1==v2则跳转
改为相反条件即可
将v5赋值为对应的值
Android killer 保存编译
flag:
NSSCTF{1a74ee530fafa690dcddd0ce38260755}
2、smali动态插桩
前面的准备工作都是一样的
(动态插桩的做法在这道题,显得比较鸡肋,但是顺带练习一下哈哈哈)
在某些题目,动态插桩的做法会输出很多重要的值,帮助我们来进行分析
前面的修改不要动
动态插桩的模板:
(注意:v0在原samli中可能会被用到,此时v0要替换为任意一个非重要寄存器,本题的v0在后面用到了,因此我替换为v4)
move-result-object v6 #v6是某个重要的值,需要我们来输出的值
const-string v0,"自定义:" #v0自定义标签值,方便我们观察
invoke-static {v0,v6}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #传入对应的值(string类型)
move-result v0 #调用即可
不报错的动态插桩smali代码
const-string v4, "myobject_soso:"
invoke-static {v4,v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
move-result v4
然后在logcat里面查看输出
adb logcat | find "myobject_soso:"
分享结束~!