学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1168

主题
发表于 2020-6-11 00:27:27 | 查看: 7413| 回复: 0

相关题目:


安卓动态调试smali  安装smalidea # 下载链接: https://bitbucket.org/JesusFreke ... s/smalidea-0.05.zip
  •   下载
  •   Android Studio安装smalidea。
    进入Settings->Plugins点击Install plugin from disk选中下载好的压缩包
  •   安装完成 解包并配置AS
  •   反编译成smali代码 apktool d 应用调试.apk 2. AS打开
  •   设置smali根目录
  •   配置AS调试环境

  配置调试环境
  •   打开安卓模拟器
  •   安装待调试程序到模拟器
    adb install aaa.apk
  •   开启调试状态
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity
  •   转发端口

  # 查看待调试程序pid
adb shell ps | grep hfdcxy
  # 转发端口
# [pid]为pid值
adb forward tcp:8700 jdwp:[pid]
  开始调试 # 1. 下断点
  打开AS中代码,点击调试行的左侧,点击处生成一个小红点,即为断点。
  \2. 开始调试 点击右上⻆按钮,开始调试。模拟器显示如图。
  然后输入内容,即可看到AS中变化。
安卓动态调试Frida的使用:  1、安装
sudo pip install frida

  2、下载frida-server文件
  在frida官方Github下载server文件,如果是真机,选择 frida-server-版本-android-arm.xz;如果是模拟器,选择 frida-server-版本-android-x86.xz。如果操作系统是64位,则选择后缀为_64的文件。下载完成后需要解压。(下载很慢或无法下载可尝试用手机连4G下载, 亲测可行)
  3、将解压后的frida-server文件push到真机或模拟器中
# 不一定要放在data/local/tmp目录下,但该目录所需权限较低
adb push "frida-server文件路径" data/local/tmp

  4、依次运行以下命令,修改server文件权限
adb shell

# 获取root权限
su

# 切换至frida-server文件所在目录
cd data/local/tmp

# 查看该目录下的所有文件
ls

# 修改权限
chmod 777 frida-server

# 测试能否启动,若无任何报错则代表启动成功
./frida-server

  这里就安装完成了,接着我们开始实现hook操作:
  1、端口转发
adb forward tcp:27042 tcp:27042

  2、然后进入 shell 并切换到data/local/tmp目录下来启动rida-server:
adb shell 

cd data/local/tmp

./frida-server

  3、运行脚本即可
import frida,sys

jscode = """
Java.perform(function(){
var hook_cls = Java.use('hfdcxy.com.myapplication.MainActivity')
hook_cls.check.implementation = function(a,b){
console.log("Hook Start...");
send(arguments);
a = "hfdcxy";
b = "1234";
send("Success!");
send("name:" + a +"    "+ "passwaord:" + b);
return this.check(a,b);
}
}
);
"""

def message(message,data):
if message["type"] == 'send':
print("
  • {0}".format(message["payload"])) else: print(message) device = frida.get_usb_device() pid = device.spawn("hfdcxy.com.myapplication") process = device.attach(pid) script = process.create_script(jscode) script.on("message",message) script.load() device.resume(pid) sys.stdin.read()

  • 安卓动态调试程序的4种方法

    安卓动态调试程序的4种方法
      解析下这里的原理:
    Java.perform(function(){
    var hook_cls = Java.use('hfdcxy.com.myapplication.MainActivity')//获取进程包
    hook_cls.check.implementation = function(a,b){//hook相应的函数,接口的转移
    console.log("Hook Start...");//终端打印log信息
    send(arguments);.//将信息发送到终端,回显出来
    a = "hfdcxy";
    b = "1234";
    send("Success!");
    send(a);
    return this.check(a,b);//让程序继续执行的话,需要有返回值
    }
    }
    );

    安卓jeb动态调试apk  1、jeb下载安装(在吾爱破解上有,3.0.0的jeb即可)
      2、直接以动态调试形式打开apk
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity

      3、然后打开jeb,进行点击那个进程进行调试即可
    smali语言语法初探:关键字  .field private isFlag:z --- 定义变量
    .method --- 方法
    .parameter --- 方法参数
    .prologue --- 方法开始
    .line 12 --- 此方法位于第12行
    invoke-super --- 调用父函数
    const/high16  v0, 0x7fo3 --- 把0x7fo3赋值给v0
    invoke-direct --- 调用函数
    return-void --- 函数返回void
    .end method --- 函数结束
    new-instance --- 创建实例
    iput-object --- 对象赋值
    iget-object --- 调用对象
    invoke-static --- 调用静态函数
    数据类型  java里面包含两种数据类型,基本数据类型和引用类型(包括对象),同时映射到smali也是有这两大类型。
      基本数据类型
    • B --- byte
    • C --- char
    • D --- double (64 bits)
    • F --- float
    • I --- int
    • J --- long (64 bits)
    • S --- short
    • V --- void    只能用于返回值类型
    • Z --- boolean
      对象类型
    • Lxxx/yyy/zzz; --- object
      L表示这是一个对象类型
    xxx/yyy是该对象所在的包
    zzz是对象名称
    ;标识对象名称的结束
      数组类型
    • [XXX --- array
    [I`表示一个int型的一维数组,相当于`int[]`
    增加一个维度增加一个`[`,如`[[I`表示`int[][]`
    数组每一个维度最多255个;
    对象数组表示也是类似,如String数组的表示是`[Ljava/lang/String
    寄存器与变量  java中变量都是存放在内存中的,android为了提高性能,变量都是存放在寄存器中的,寄存器为32位,可以支持任何类型,其中long和double是64为的,需要使用两个寄存器保存。
    寄存器采用v和p来命名
    v表示本地寄存器,p表示参数寄存器,关系如下
    如果一个方法有两个本地变量,有三个参数
      v0第一个本地寄存器
    v1第二个本地寄存器
    v2=p0(this)
    v3=p1第一个参数
    v4=p2第二个参数
    v5=p3第三个参数
      当然,如果是静态方法的话就只有5个寄存器了,不需要存this了。
    .registers使用这个指令指定方法中寄存器的总数
    .locals使用这个指定表明方法中非参寄存器的总数,放在方法的第一行。
    方法和字段  方法签名
    methodName(III)Lpackage/name/ObjectName;
    如果做过ndk开发的对于这样的签名应该很熟悉的,就是这样来标识一个方法的。上面methodName标识方法名,III表示三个整形参数,Lpackage/name/ObjectName;表示返回值的类型。
      方法的表示
    Lpackage/name/ObjectName;——>methodName(III)Z
    即 package.name.ObjectName中的 function boolean methondName(int a, int b, int c) 类似这样子
      字段的表示
    Lpackage/name/ObjectName;——>FieldName:Ljava/lang/String;
    即表示: 包名,字段名和各字段类型
      方法的定义
    比如下面的一个方法
    指令执行  smali字节码是类似于汇编的,如果你有汇编基础,理解起来是非常容易的。
    比如:
    move v0, v3 #把v3寄存器的值移动到寄存器v0上.
    const v0, 0x1 #把值0x1赋值到寄存器v0上。
    invoke-static {v4, v5}, Lme/isming/myapplication/MainActivity;->sum(II)I #执行方法sum(),v4,v5的值分别作为sum的参数。
    条件跳转分支  "if-eq vA, vB, :cond_x" --- 如果vA等于vB则跳转到:cond_x
    "if-ne vA, vB, :cond_x" --- 如果vA不等于vB则跳转到:cond_x
    "if-lt vA, vB, :cond_x" --- 如果vA小于vB则跳转到:cond_x
    "if-ge vA, vB, :cond_x" --- 如果vA大于等于vB则跳转到:cond_x
    "if-gt vA, vB, :cond_x" --- 如果vA大于vB则跳转到:cond_x
    "if-le vA, vB, :cond_x" --- 如果vA小于等于vB则跳转到:cond_x
    "if-eqz vA, :cond_x" --- 如果vA等于0则跳转到:cond_x
    "if-nez vA, :cond_x" --- 如果vA不等于0则跳转到:cond_x
    "if-ltz vA, :cond_x" --- 如果vA小于0则跳转到:cond_x
    "if-gez vA, :cond_x" --- 如果vA大于等于0则跳转到:cond_x
    "if-gtz vA, :cond_x" --- 如果vA大于0则跳转到:cond_x
    "if-lez vA, :cond_x" --- 如果vA小于等于0则跳转到:cond_x
      参考连接:
    链接:https://www.jianshu.com/p/ba9b374346dd
    终端操作的常见命令行:
    cd Library/Android/sdk/tools #进入模拟器的终端目录
    emulator -avd 666 -writable-system #开机
    cd ..
    cd Library/Android/sdk/platform-tools
    adb root #root权限获取(手机必须是root的,安卓6.0以下即可)
    adb remount #获取读写权限
    adb install /xxx/xxx.apk #安装apk软件
    adb reboot #重启安卓模拟器
    adb shell #进入特权模式
    adb push Users/v1ct0r/Downloads/xxx.apk  data/local/tmp #PC往安卓模拟器中传文件
    adb pull /system/framework/framework.jar  Users/v1ct0r/Downloads#从安卓模拟器中传文件到PC中
    adb forward tcp:27042 tcp:27042 #端口转发
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity  #调试模式打开程序,程序必须是可debug的才行,不行就改成true然后重新打包
    adb shell ps | grep hfdcxy #查看调试的进程id

    如果是native方法的话,只能看.so库文件,用ida动态调试:  1、将apk解压,然后将x86下的libc库拖到ida中进行动态分析
      2、将a1+668这种类型通过y,一键转成JNIEnv *ptr类型,即可很清晰看出来东西
      3、shift+F12和Hex View中去找可用的字符串,可以定位到关键逻辑点5216CCB620
      4、开始配置环境
    adb push xxx/xxx/android__x86_server /data/local/tmp/  看具体的版本而定有arm也有x86的
    adb shell
    # cd /data/local/tmp
    /data/local/tmp # chmod 755 android_x86_server
    /data/local/tmp # ./android_x86_server
    IDA Android 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017
    Listening on 0.0.0.0:23946...

      这样就配置好了ida的调试程序环境
      现在开始调试工作:
    1、开启调试服务
    /data/local/tmp # ./android_x86_server
    IDA Android 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017
    Listening on 0.0.0.0:23946...

    2、设置端口转发  这时候android_server已经在监听Android设备的23946端口,我们还需要将这个端口转发到我们的电脑上:
    adb forward tcp:23946 tcp:23946

    3、以调试模式启动Activity  现在,我们可以开始着手调试程序了,我们先以调试模式启动程序的主Activity,命令格式为:
    adb shell am start -D -n hfdcxy.com.myapplication/hfdcxy.com.myapplication.MainActivity    包名/类名

      启动程序后(也可以不同调试状态)就可以开始调试了,我们找到IDA的Debugger菜单,选择Attach process,在弹出的窗口中选择我们的被调试进程hfdcxy.com.myapplication,当IDA进入调试状态后,就已经成功附加到目标进程。
      IDA会首先断在程序刚开始执行的地方,这时候可以选择继续运行让程序继续向下执行。然后就可以在手机上操作了。一般来说下断点直接在调试前的汇编中下断点即可,在执行到断点时候也可以以伪代码的形式调试。
      在源程序断点下来,然后再安卓重新启动一次apk,就可以在ida中选择debugger/attach process/程序进程,即可实现动态调试。
      这样就可以直接定位到关键逻辑处!
    总结:  jeb动态调试查看寄存器和内存信息+frida动态调试hook函数修改信息+ida动态调试.so文件


    温馨提示:
    1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
    2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
    3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
    论坛交流群:672619046

    小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

    GMT+8, 2024-11-22 10:04 , Processed in 0.148813 second(s), 40 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表