zoukankan      html  css  js  c++  java
  • 安卓逆向10-ida,动态调试

    ###

    动态调试的准备工作:

    IDA动态调试:
    配置:
    #把本地文件推送进手机目录

    将ida文件夹里面的dbgsrv下的android_server放入真机的/data/local/tmp/下
    adb push android_x86_server(cpu型号要对应 模拟器是x86) /data/local/tmp/

     

     如果是64位,就选64位的,


    #进入手机shell
    adb shell
    #真机要使用 su 命令 切换到root用户,模拟器不用
    #进入手机tmp目录
    cd /data/local/tmp/
    #修改权限
    chmod 777 android_server
    #运行
    ./android_server
    #在本地执行adb 做端口转发
    adb forward tcp:23946 tcp:23946

    要动态调试,要用真机调试,最好使用安卓6,7,安卓5会问题很多,

    ####

    IDA动态调试

    目的:找到自毁程序的内置密码

    第一步,我们再开一个ida程序,不要关闭静态调试的那个窗口

    这就是ida双开,

    本地打开IDA,选中Go

    然后连接到手机的服务,确保上面的配置,是正确的,服务是开启的,

    第二步:

    点击上面的连接真机,然后弹出下面的弹框,然后输入127.0.0.1,因为都是本地调试,所以就是输入这个本地ip就可以了,

    第三步,

    点击上面的,如果正常,就会弹出选择app的页面了,

    这是把所有的进程都展示出来了,还可以搜索,

    如果找不到这个app,那就重新打开一下app,

    ###

    第四步,上面一步打开app可能有点慢,要等一等,

    然后进行ctrl+s,进行搜索我们要调试的so文件,

     注意后面的权限,我们选择第一个有X权限的,就是有可执行权限,我们要调试这种的,

    start就是内存地址,我们叫做基地址, 

    ##

    第五步,

    我们看到有很多个,怎么找到我们要调试的方法的那个地址??

    按键盘G键, 输入绝对地址,跳转到要调试的函数处
    如何计算要调试函数的绝对地址:
    绝对地址 = so文件的基地址 + 该函数的偏移量
    so文件的基地址在哪儿找:
    快捷键 ctrl + s 找到目标so文件 Start 那一项就是 基地址

    DC9E6000
    函数的偏移量在哪儿找:
    以静态方式打开so文件,函数列表里

     这个就是函数的偏移量,

    000011A8

    ####

    你要动态调试,你还是要先看懂了静态调试,才好去调试,

    看看静态调试的c代码,

    你逆向,不能从头看,你要有逻辑,不能从第一行看,你这样看不懂的,

    可以从return看,

     上面我们已经分析过了,

    v5就是我们输入的密码

    v7就是真实密码,而v7是来自于v6,所以v6就是真正的密码,而v是一个常量

    所以我们的目的就是调出来v6这个常量,

    ####

    然后我们动态调试,怎么跳,

    怎么加

    用16进制的计算器,DC9E6000+000011A8  =DC9E71A8

    然后使用快捷键 g  输入地址,DC9E71A8

    然后就调到这里了,

    第六步,上面的面板

    是有很多的分支流程的,这就是条件语句,

    F8是单步调试,这个就是不进入函数

    F7单步调试,这个是要进入函数,

    一般我们就是使用F8,因为F7进入之后太多了,调试难度大,

    你要调试,你要先打断点,然后才可以单步调试,

    选中然后进行右键,添加断点,就可以了,添加之后会标红的

    然后让程序恢复执行

    如果你点击了之后报错,一直报错,可能就是加入了反调试了,

    #####

    下面介绍一下反调试,

    so反调试
    IDA调试原理 是利用Linux系统 ptrace 来实现
    当应用被调试时,应用内存里的TracerPid 字段就不为0

    如果为什么会有反调试,

    就是因为ida是利用的Linux的pTrace来实现的,

    而调试的时候,TracerPid 字段就不为0


    进入设备查看ptrace字段:
    //进入设备
    adb shell
    //获得APP的进程ID
    ps | grep 包名
    //打印该APP里内存状态信息
    cat /proc/pid(进程ID)/status

    TracerPid为 0 代表 没有被调试,不为0代表在被调试。
    反调试,既检测TracerPid是否被占用
     
    so文件反调试的手段就是:
    新建一个线程 不停的检测TracerPid这个字段是否不为0, 不为0,就立即退出程序。
    //linux中创建进程的函数
    pthread_create()
    演示有反调试检测的crackme 

    ###

    反反调试
    动态调试,找到检测TracerPid的代码,不执行此代码
    方法:
    此检查代码一般在.init_arra 和 JNI_OnLoad两处
    在JNI_OnLoad函数出打断点调试,找到检测TracerPid的代码,不执行此代码
    IDA调试反调试小经验 如何找到反调试代码:
    结合IDA静态时的代码,观察程序逻辑
    指令一般会整过执行完,直到函数末尾。

    多次IDA中,如果指令在中途某个地方退出了,说明该处就是反调试指令。

    ####


    如何在JNI_OnLoad函数打断点:
    so文件在加载阶段会执行JNI_ONLoad,此后不再执行,要在so文件加载阶段才能给

    JNI_OnLoad打断点
    1).修改APP AndroidMenifest.xml文件, APP加上可调试权限,android:debuggable="true",

    重新打包APP,

    apktool.sh b ./AliCrackme_密码在so文件debug模式

    签名,keytool -genkey -keystore my-release-key.keystore -alias my_alias -keyalg RSA -keysize 4096 -validity 10000

    打包,jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore -signedjar AliCrackme_密码在so文件sign.apk AliCrackme_密码在so文件.apk my_alias

    安装,

    如果有签名校验,你还要过校验,这是一个复杂的事情,


    2).检查flags中是否有应许debug项
    adb shell dumpsys package com.yaotong.crackme

    3).以调试模式启动APP APP此时会挂住
    adb shell am start -D -n 包名/.类名
    adb shell am start -D -n com.yaotong.crackme/.MainActivity

    让app停在这里,不要动,

    然后把ida动态调试失败的页面关闭,不要保存

    路径:file-close,

     然后重新来一遍上面的流程,

    这个时候你是看不到so文件的,因为app现在是卡住的状态,

    然后进入下一步


    4).在debugger-DebuggerOptions

    DebuggerOptions里勾选 Suspend on thread start/exit Suspend on library load/unload
    JNI_OnLoad函数是lib刚加载时就会执行,必须要在lib载入时就让程序停下来,才能调试JNI_OnLoad

    5).点击运行按钮


    6).在设备里查看APP的进程ID
    要adb shell先进入设备运行如下命令,过滤出该应用信息
    ps | grep 应用包名

    7). 使用JDB命令让APP 恢复运行
    adb forward tcp:8700 jdwp:873(APP的PID)

    adb forward tcp:8700 jdwp:29404
    jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700


    8).在so文件被加载时,IDA会停止住,使用ctrl+s 查看目标so文件是否加载

    一开始肯定是搜不到的,因为还没有加载进来,

    然后你点击ida右上角的运行按钮,一步一步的运行,这个时候要很小心,
    若加载点选目标so文件,

    找地址JNI_OnLoad

    计算JNI_OnLoad的绝对地址,按G键跳转到JNI_OnLoad出设置断点,

    打断点

     

    恢复APP执行,

     会变成蓝色

    ###

    找到反调试代码处,pthread_create(),
    如何找到反调试代码处?(关键地方,可按f5,把汇编代码转成C语言辅助)
    反复按F8单步执行,程序退出处(前面),既为反调试处

     如果按F8,继续往下走,说明没有问题,如果有地方不往下走了,往回走了,这个地方就有问题了,

     继续往下F8,就直接退出了,

    下面我们就是把指令不执行,

    ####


    如何让反调试代码不执行?
    让该指令变为空指令,既 NOP,NOP指令的16进制是 00 00 00 00

     我们要做的就是把这个BLX R7,变成空,

    记住反调试处的汇编指令,这个时候我们就要回到这个静态调试了,

    同时以静态方式再打开一个IDA(也叫双开IDA 以动态和静态方式各打开一个IDA ),

    打开so文件,在静态ida里查找到此汇编指令,鼠标选中后面寄存器,然后切换到Hex View,会显示该指令的16进制,

     然后copy下来,

    37 FF 2F E1

    去改so文件的二进制代码

    然后又要重新打包so文件,上面的都要重新来一遍,

    ###

    因为你已经找到反调试的地方,并且干掉了

    所以就不需要从debugger模式运行了

    我们直接运行app,直接调试我们的加密的方法那里,不需要调试JNI_OnLoad方法了,

    1,启动ida动态 调试,

    2,找到app,

    3,找到so文件,直接进入

    4,计算地址,跳转到加密方法那里

    5,打断点

    然后我手机输入密码,点击一下,才会触发这个方法,到这个so文件里面来

    这一点要注意,你要去触发,

     

     到了这一步,发现了不往下走了,会有跳到下一个,

    这个地方就有问题了,

     然后是出现了R1就是我们输入的密码1111,

    说明R3就是真实的密码了,因为有一个比较,

    这个时候可以点击R3查看,

    还可以按F5,转成c代码,看看,

     这个时候,把鼠标放到v6,我们看到就密码已经出来了,

    ####

    动态调试libcrackme拿到密码:
    1.分析出密码判断的函数是哪一个
    2.IDA静态分析此函数,理清脉络
    3.在此函数处下断点调试
    4.单步调试,观察指令执行流程
    5.密码不对时,指令会跨越执行,不再顺序执行
    6.动态调试时,在关键指令处按F5,把指令转成c代码辅助分析
    7.动态调试时鼠标移动到寄存器上,会显示该寄存器里的值
    8.动态调试时,把指令转换成C代码,把鼠标移动到C代码的变量上,会显示该变量的值

    ###

  • 相关阅读:
    MOSS 2010:Visual Studio 2010开发体验(16)——客户端对象模型
    MOSS 2010:Visual Studio 2010开发体验(15)——LINQ to SharePoint
    文字中间加横线效果
    android 滑动加载数据
    使用scrollview不让键盘覆盖编辑框
    java数据结构分析
    android listview onitemclick
    Android通过Intent发送电子邮件含附件
    简易的按钮事件
    使用google chart生成动态图
  • 原文地址:https://www.cnblogs.com/andy0816/p/15100811.html
Copyright © 2011-2022 走看看