欢迎新同学的光临
… …
人若无名,便可专心练剑
我不是一条咸鱼,而是一条死鱼啊!
动态调试是在没有软件源代码的情况下,通过调试程序来跟踪分析汇编代码,查看寄存器的值,了解软件的执行流程,反馈程序执行时的中间结果
动态调试一般与静态分析结合使用,尤其是在静态分析难以取得突破时,需要使用动态调试进行辅助分析。主流调试工具包括DDMS、IDA Pro、AndBug、gdb等,主要涉及两种调试方法:
打印Log法:
栈跟踪法:
Method Profiling:
UI查看:
所谓信息反馈法,是指先运行目标程序,然后根据程序运行时给出的反馈信息作为突破口寻找关键代码。例如运行目标程序并输入错误的注册码时,会弹出提示“无效用户名或注册码”,这就是程序反馈给我们的信息。通常情况下,程序中用到的字符串会存储在String.xml文件或者硬编码到程序代码中,如果是前者的话,字符串在程序中会以id 的形式访问,只需在反汇编代码中搜索字符串的id 值即可找到调用代码处;如果是后者的话,在反汇编代码中直接搜索字符串即可。
如果想快速找到某一个按钮或者某个界面的相关代码,即仍旧是找到ID值,再通过JEB等工具进行查找,那么如何找到id值,这里可以使用工具uiautomatorviewer.bat(SDK)
通俗的来说就是,根据程序正常运行的提示信息进行定位,例如:错误提示,运行提示等等。可以在程序中直接搜索字符串,当提示信息在 String.xml 资源文件中的时候,可以根据 R.java 的映射文件,查找对应的资源id,然后在 smali 或者在 ida 窗口中进行搜索
这种定位代码的方法与信息反馈法类似。在信息反馈法中,无论程序给出什么样的反馈信息,终究是需要调用Android SDK 中提供的相关API 函数来完成的。比如,弹出注册码错误的提示信息就需要调用Toast.MakeText().Show()方法,在反汇编代码中直接搜索Toast应该很快就能定位到调用代码,如果 Toast在程序中有多处的话,可能需要分析人员逐个甄别
通俗的来说就是,根据程序提示信息的方法,在对应的 Android 的 API 下断点,通过 API 来检索相关的代码
顺序查看法是指从软件的启动代码开始,逐行的向下分析,掌握软件的执行流程,这种分析方法在病毒分析时经常用到
通俗的来说就是,从 AndroidManifest.xml 中找到 主 Activity 界面,然后顺序分析代码,通常在分析病毒软件时使用。( 通过 UI 进行分析, adb shell dumpsys activity top )
动态调试,又叫插桩,即在关键反汇编代码处插入可以输出 logcat 调试信息的代码
例如,smali代码注入或者动态修改程序,一般都可归结为代码注入
栈跟踪法属于动态调试的方法,原理是输出运行时栈调用跟踪信息,然后查看函数调用序列来理解方法的执行流程
通俗的来说就是,利用输出时的栈跟踪信息,通过查看栈上的函数调用序列来理解方法的执行流程
Method Profiling 动态调试方法,主要用于热点分析和性能优化。除了可以记录每个函数赵勇的CPU时间外,还可以跟踪所有的函数调用关系,并提供比栈跟踪法更详细的函数调用序列报告
Method Profiling 动态调试方法,主要是使用ptrace来进行,相应的有hook等等技术
常见环境:
IDA pro + DDMS 主要用来调试so文件,当然也可以调试dex文件
linux环境:
其他:
Hook技术:
Smali注入又称Smali插桩(Smali Instrumentation),WIKI解释:它是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为“探测仪”),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。这几个词(保证程序原有逻辑性、插入探针、抛出特征数据)也是samli注入需要关注的几个关键点所在
SDK提供Android.util.Log
类输出调试信息,总共有五种调试方法(v(),d(),i(),w(),e())
,六种调试状态(verbose,debug,info,warning,error,assert)
。在插入时可以插入对应的方法进行调试,如果仅是输出对象的值,可以是v或者d()方法,这里需要注意,六种调试状态存在等级之分,依顺序排序,高一级的状态会覆盖低级的状态,这个如果对java语言比较熟悉的话,可以类比java语言的exception异常类
Android中的日志工具类是Log(android.util.Log)
,这个类中提供了如下5个方法打印日志:
package com.example.mytest;
import android.util.Log;
public class MyCrackTest {
public static void Logd(String v0){
Log.d ("hash", "testtest"+v0);
}
}
PS:要用static进行修饰,之后我们反编译代码后会在onCreate中进行调用,如下smali:
const-string v0, "The Orangey blog welcomes you!!!-test"
invoke-static {v0}, LMyCrackTest;->Logd(Ljava/lang/String;)V
smali对应的java代码如下:
MyCrackTest.Logl("The Orangey blog welcomes you!!!-test");
java -jar apktool.jar d -f app-debug.apk -o app-debug
java -jar apktool_2.6.1.jar b app-debug -o app-debug1.apk
java -jar signapk.jar testkey.x509.pem testkey.pk8 app-debug1.apk app-debug_qm.apk
adb logcat
运行结果如下:
案例APK下载:https://www.wandoujia.com/apps/280375/history_v100991744
将下载好的APK重命名为bd.apk
java -jar apktool.jar d -f bd.apk -o bd
打开AndroidManifest.xml文件,找到App最先启动的Activity
通过查看AndroidManifest.xml中的Activity的配置信息,可以判定LogoActivity就是最先启动的Activity,也就是后面我们所需要修改的欢迎界面
那么,如何判断是否为最先启动的呢?可以看有没有如下内容:
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
# 决定应用的入口Activity,也就是我们启动应用时首先显示哪一个Activity
android.intent.action.MAIN
# 表示activity应该被列入系统的启动器(launcher)(允许用户启动它)
# Launcher是安卓系统中的桌面启动器,是桌面UI的统称
android.intent.category.LAUNCHER
intent-filter 标签中这两个值:
intent-filter 标签中(MAIN和LAUNCHER)具体作用如下:
打开\smali\com\baidu\tieba\LogoActivity.smali文件,定位到onCreate方法
为什么要修改呢?因为smali是基于寄存器的,所有的操作都要经过寄存器,所以在进行smali代码注入时首先要适当修改寄存器的个数。因为构造和显示Toast函数至少需要3个寄存器,所以我们应该先将onCreate方法中的.locals值由7修改为10
android.widget.Toast 是android提供的一个用于快显信息的类
invoke-super{p0,p1},Lcom/baidu/tbadk/BaseActivity;->onCreate(Landroid/os/Bundle;)V
这条语句后面添加构造和显示Toast的代码invoke-super {p0, p1}, Lcom/baidu/tbadk/BaseActivity;->onCreate(Landroid/os/Bundle;)V
const-string v7, "The Orangey blog welcomes you!!!" # 构造toast显示的字符串
const/4 v8, 0x1 # 构造Toast 的显示时间,0表示Toast.LENGTH_SHORT;1表示Toast.LENGTH_LONG
invoke-static {p0, v7, v8}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; # 调用Toast.makeText方法
move-result-object v9 # 将前面的Toast.makeText方法的返回值保存到v9寄存器中
invoke-virtual {v9}, Landroid/widget/Toast;->show()V # 调用Toast.show方法弹出Toast信息
apktool b out -o 3.apk
java -jar apktool.jar b bd -o bd_log1.apk
java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 bd_log1.apk bd_log1_qm.apk
丢到模拟器安装
编写自定义的log类的samli代码,然后只要将其放入smali文件的根目录文件夹下,然后,在smali代码中插入一句调用代码即可(步骤跟上面说的Android Studio 差不多,只是多了个编写log类的APK反编译后把log类的smali代码放到我们需要插入log类代码的APK的smali文件下)
具体内容,请前往之前写的文章有介绍:
[车联网安全自学篇] 二十三. Android安全之静态方式逆向APK应用浅析【手动注入smali+】+【IDA Pro静态分析so文件】+【IDA Pro基础使用讲解】
参考链接:
https://blog.csdn.net/pengyan0812/article/details/44568147
http://www.tasfa.cn/index.php/2016/05/18/smali-instrumentation/
我自横刀向天笑,去留肝胆两昆仑