Frida-Hook-Native层操作大全

前期准备

  • 使用 jadx 进行逆向工程的基础知识。
  • 能够理解 Java 代码。
  • 能够编写简短的 JavaScript 代码片段。
  • 熟悉 adb。
  • 已 root 的设备。
  • 对 x86/ARM64 汇编和逆向工程有基础了解。

1、Hook Native层中调用的函数并且读取传入的参数

对于Native层的函数Hook,我们使用如下模板

Interceptor.attach(targetAddress, {onEnter: function (args) {console.log('Entering ' + functionName);// Modify or log arguments if needed},onLeave: function (retval) {console.log('Leaving ' + functionName);// Modify or log return value if needed}
});
  • Interceptor.attach:将回调函数附加到指定的函数地址。targetAddress 应该是我们想要挂钩的本地函数的地址。
  • onEnter:当挂钩的函数被调用时,调用此回调。它提供对函数参数 (args) 的访问。
  • onLeave:当挂钩的函数即将退出时,调用此回调。它提供对返回值 (retval) 的访问。
    需要获取targetAddress我们可以方便的使用如下API
  1. Module.enumerateExports()
    通过调用 Module.enumerateExports(),我们可以获取到导出函数的名称、地址以及其他相关信息。这些信息对于进行函数挂钩、函数跟踪或者调用其他函数都非常有用。
  2. Module.getExportByName()
    当我们知道要查找的导出项的名称但不知道其地址时,可以使用 Module.getExportByName()。通过提供导出项的名称作为参数,这个函数会返回与该名称对应的导出项的地址。
  3. Module.findExportByName()
    这与 Module.getExportByName() 是一样的。唯一的区别在于,如果未找到导出项,Module.getExportByName() 会引发异常,而 Module.findExportByName() 如果未找到导出项则返回 null。让我们看一个示例。
  4. Module.getBaseAddress()
    通过调用 Module.getBaseAddress() 函数,我们可以获取指定模块的基址地址,然后可以基于这个基址地址进行偏移计算,以定位模块内部的特定函数、变量或者数据结构
  5. Module.enumerateImports()
    通过调用 Module.enumerateImports() 函数,我们可以获取到指定模块导入的外部函数或变量的名称、地址以及其他相关信息。

例题 Frida-Labs 0x8

MainActivity

file
可以发现,程序从EditText控件中获取到了用户的输入,然后调用了native层中的cmpstr函数进行比较。

Navtive层逻辑

file
程序在cmpstr中使用了strcmp函数,那么我们只需要拿到strcmp函数的传入参数就可以知道程序的正确输入了

Hook begin

首先我们使用Module.enumerateImports(“libfrida0x8.so”)查看导入表
file
可以发现strcmp来自于libc.so,那么我们就可以使用Module.findExportByName(“libc.so”,“strcmp”);来获取strcmp的地址了
file

获取了strcmp的地址就可以使用之前给的模板进行Hook了

function hook(){var targetAddress = Module.findExportByName("libc.so","strcmp");console.log("Strcmp Address: ",targetAddress.toString(16));Interceptor.attach(targetAddress,{onEnter:function (args){},onLeave:function(retval){}})console.log("success!");
}function main(){Java.perform(function (){hook();})
}
setImmediate(main);

但是我们需要注意的是strcmp可能不止调用一次,因此我们需要判断strcmp的第一个参数是否为0我们才进行操作,不然hook可能会一直循环输出
file
因此我们可以使用Memory.readUtf8String(args[0]);来获取我们的输入字符串,平且使用 if (input.includes(“111”))来判断

hook代码

function hook(){var targetAddress = Module.findExportByName("libc.so","strcmp");console.log("Strcmp Address: ",targetAddress.toString(16));Interceptor.attach(targetAddress,{onEnter:function (args){var input = Memory.readUtf8String(args[0]);if (input.includes("111")){console.log(Memory.readUtf8String(args[1]));}},onLeave:function(retval){}})console.log("success!");
}function main(){Java.perform(function (){hook();})
}
setImmediate(main);

file

2、Hook修改native层程序返回值

首先还是给出hook的模板如下:

Interceptor.attach(functionaddr, {onEnter: function (args) {},onLeave: function (retval) {}
});

可以看到在onLeave中有一个参数retval,这个retval,就是我们hook上的程序的返回值,我们可以使用retval.replace(val)来修改返回值。

例题 Frida-labs 0x9

MainActivity

file
可以发现程序根据native层的check_flag 方法的返回值

check_flag

file
只是简简单单的返回了一个1

hookbegin

首先使用Module.enumerateExports(“liba0x9.so”),查看导出表,看看check_flag方法的偏移地址
file
然后就可以使用模板一把梭了

hook代码
function hook(){var check_flag = Module.enumerateExports("liba0x9.so")[0]["address"];console.log("Func address = ",check_flag);Interceptor.attach(check_flag,{onEnter:function (args){},onLeave:function (retval){console.log("Origin retval : ",retval);retval.replace(1337);}})
}
function main(){Java.perform(function (){hook();})
}
setImmediate(hook);

file

3、调用native层中未被调用的方法

让我提供一个模板。

var native_adr = new NativePointer(<address_of_the_native_function>);
const native_function = new NativeFunction(native_adr, '<return type>', ['argument_data_type']);
native_function(<arguments>);

让我逐行解释。

var native_adr = new NativePointer(<address_of_the_native_function>);

要在 Frida 中调用一个本地函数,我们需要一个 NativePointer 对象。我们应该将要调用的本地函数的地址传递给 NativePointer 构造函数。接下来,我们将创建 NativeFunction 对象,它表示我们想要调用的实际本地函数。它在本地函数周围创建一个 JavaScript 包装器,允许我们从 Frida 调用该本地函数。

const native_function = new NativeFunction(native_adr, '<return type>', ['argument_data_type']);

第一个参数应该是 NativePointer 对象,第二个参数是本地函数的返回类型,第三个参数是要传递给本地函数的参数的数据类型列表。现在我们可以像在 Java 空间中那样调用该方法了。

native_function(<arguments>);

好的,我们明白了。让我们来看看例题。

例题Frida-labs 0xA

MainActivity

file
发现就是在主函数中加载了stringFromJNI

native

file
没有关于flag的信息,但是有未被调用的flag函数,我们直接使用hook调用它输出log
file

hook代码
function hook(){var a = Module.findBaseAddress("libfrida0xa.so");var b = Module.enumerateExports("libfrida0xa.so");var get_flagaddress = null;var mvaddress = null;for(var i = 0 ; b[i]!= null ; i ++ ){// console.log(b[i]["name"])if(b[i]["name"] == "_Z8get_flagii"){console.log("function get_flag : ",b[i]["address"]);console.log((b[i]["address"] - a).toString(16));//       mvaddress = b[i]["address"] - a;get_flagaddress = b[i]["address"];}}console.log(ptr.toString(16));var get_flag_ptr = new NativePointer(get_flagaddress);const get_flag = new NativeFunction(get_flag_ptr,'char',['int','int']);var flag = get_flag(1,2);console.log(flag)//console.log(b);
}function main(){Java.perform(function (){hook();})
}
setImmediate(main)

file

4、更改Native层方法的汇编指令

首先我们先看来自x86指令集的frida使用模板

var writer = new X86Writer(opcodeaddr);
Memory.protect(opcodeaddr, 0x1000, "rwx");
try {writer.flush();} finally {writer.dispose();
}

X86Writer的实例化:

  • var writer = new X86Writer(<指令的地址>);
  • 这将创建一个X86Writer类的实例,并指定我们要修改的指令的地址。这设置了写入器以操作指定的内存位置。

**插入指令 **

  • try { /* 在此处插入指令 */ }
  • try块内,我们可以插入要修改/添加的x86指令。X86Writer实例提供了各种方法来插入各种x86指令。我们可以查阅文档以了解详情。

刷新更改:

  • writer.flush();
  • 插入指令后,调用flush方法将更改应用到内存中。这确保修改后的指令被写入内存位置。

清理:

  • finally { /* 释放X86Writer以释放资源 */ writer.dispose(); }
  • finally块用于确保X86Writer资源得到适当清理。调用dispose方法释放与X86Writer实例关联的资源。

解除段只读权限
Memory.protect 。我们可以使用这个函数来修改内存区域的保护属性。Memory.protect 函数的语法如下:

Memory.protect(地址, 大小, 保护属性);
  • 地址:要更改保护的内存区域的起始地址。
  • 大小:内存区域的大小,以字节为单位。
  • 保护属性:内存区域的保护属性。

那么如何使用进行覆写呢
对于x86系统而言我们首先需要查看官方文档中的使用方法
https://frida.re/docs/javascript-api/#x86writer

file
对与arm64系统而言,我们使用如下api
https://frida.re/docs/javascript-api/#arm64writer

file
接下来让我用一个用例程序来讲一下这个指令的用法,我们示范的内容为arm64架构

例题Frida-labs 0xB

MainActivity

首先我们看到MainActivity函数内容
file
发现MainActivity就是在用户点击按钮后调用了getflag方法,但是正常点击getflag方法并不会返回flag值。

Native层内容

file
惊讶的发现MainActivity中什么都没有,显然这是不存在的。接下来我们到控制流窗口中查看。
file
查看控制流发现程序出现了永假条件跳转。导致导致ida识别不到输出flag的功能。那么我们可以把这个B.NE给Nop掉即可
首先我们需要计算B.NE的偏移地址
file
可以发现就是基地址增加15248,然后我们覆写为Nop就可以了

Hook代码
function hook(){var Base =  Module.getBaseAddress("libfrida0xb.so");console.log("Base address : ",Base);var BNE = Base.add(0x15248);Memory.protect(Base,0x1000,"rwx");var writer = new Arm64Writer(BNE);try{writer.putNop();writer.flush();console.log("Success!!");}finally {writer.dispose();}
}function main(){Java.perform(function (){hook();})
}setTimeout(main,1000);

file

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/271151.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.3.7

1、基于UDP的网络聊天室 服务器&#xff1a; #include<myhead.h>//定义一个结构体存储成员信息 typedef struct Node {struct sockaddr_in cin;struct Node *next; }*Linklist;//定义一个结构体表示消息类型 typedef struct _msg {char code; //L:登录&#xff0c;C…

vue3+element plus 实现百度地图显示路径

添加依赖 <!-- index.html --><script type"text/javascript" src"//api.map.baidu.com/getscript?v3.0&akyI6kBeC9G4LntEWXklE2iNHwRUrmFEQc"></script><script type"text/javascript" src"//api.map.baidu.co…

利用Python爬取高德地图全国地铁站点信息

利用Python中的requests库进行地铁站点信息的获取,同时将数据保存在本机excel中 # 首先引入所需要的包 import requests from bs4 import BeautifulSoup import pandas as pd import json# 发送 GET 请求获取网页内容 url http://map.amap.com/subway/index.html response r…

【算法沉淀】刷题笔记:并查集 带权并查集+实战讲解

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

ospf虚链路实验简述

1、ospf虚链路实验简述 ospf虚链路配置 为解决普通区域不在骨干区域旁&#xff0c;通过配置Vlink-peer实现不同区域网络设备之间建立逻辑上的连接。 实验拓扑图 r1: sys sysname r1 undo info enable int loopb 0 ip add 1.1.1.1 32 ip add 200.200.200.200 32 quit int e0/0/…

模拟实现std::string类(包含完整、分文件程序)

std库中的string是一个类&#xff0c;对string的模拟实现&#xff0c;既可以复习类的特性&#xff0c;也可以加深对std::string的理解。 &#x1f308;一、搭建框架 ☀️1.新命名空间 本质上string是一个储存在库std里面的类&#xff0c;现在需要模拟实现一个string类&#…

python基础——入门必备知识

&#x1f4dd;前言&#xff1a; 本文为专栏python入门基础的第一篇&#xff0c;主要带大家先初步学习一下python中的一些基本知识&#xff0c;认识&#xff0c;了解一下python中的一些专有名词&#xff0c;为日后的学习打下良好的基础,。本文主要讲解以下的python中的基本语法&…

力扣706:设计哈希映射

题目&#xff1a; 不使用任何内建的哈希表库设计一个哈希映射&#xff08;HashMap&#xff09;。 实现 MyHashMap 类&#xff1a; MyHashMap() 用空映射初始化对象void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中&#x…

tcpdump使用pcap-filter抓Vxlan包内数据

目录 1. 背景2. 参考3. 概念4. 环境5. 用法5.1 抓vxlan通讯中的icmp包5.2 tcpdump抓包命令解析5.2.1 tcpdump命令说明5.2.2 Vxlan协议报文解析 5.3 其他抓包例子5.3.1 抓包示例15.3.2 抓包示例2 1. 背景 看vxlan协议时&#xff0c;发现可以使用tcpdump高级用法&#xff08;pca…

Unity Samples和帧动画的问题

拖动序列帧图片和自己创建clip的帧率不同 我今天在创建帧动画的时候用了两种方式第一种是直接拖动序列帧图片到Hierachy&#xff0c;然后生成的第二种是这样我发现两者播放的动画速率不一样最后查了半天查不到原因。最后发现是Samples的原因&#xff0c;而且Unity把Samples这个…

智能控制:物联网智能插座对接文档

介绍 一开始买的某米的插座&#xff0c;但是好像接口不开放&#xff0c;所以找到了这个插座&#xff0c;然后自己开发了下&#xff0c;用接口控制插座开关。wifi的连接方式&#xff0c;通电后一般几秒后就会连接上wifi&#xff0c;这个时候通过接口发送命令给他。 产品图片 通…

b站小土堆pytorch学习记录—— P25-P26 网络模型的使用和修改、保存和读取

文章目录 一、修改1.方法2.代码 二、保存和读取1.方法2.代码&#xff08;1&#xff09;保存&#xff08;2&#xff09;加载 3.陷阱 一、修改 1.方法 add_module(name: str, module: Module) -> None name 是要添加的子模块的名称。 module 是要添加的子模块。 调用 add_m…

Android车载开发之AAOS快速入门

一、概述 在正式介绍Android Automotive OS之前,我们先弄清两个概念:Android Auto和Android Automotive OS。 Android Auto Android Auto 不是操作系统,而是一个应用或一个服务。当 Android 手机通过无线或有线方式连接到汽车时,Android 系统会将使用 Android Auto 服务…

python爬虫(一)

一、python中的NumPy模块&#xff08;数据的存储和处理&#xff09; 这里是下载完成之后的表现 &#xff08;1&#xff09;创建数组 1、使用array&#xff08;&#xff09;函数创建数组 使用array函数可以创建任意维度的的数组 下面是一个创建二维数组的代码示例 下面是代码…

每日五道java面试题之springMVC篇(一)

目录&#xff1a; 第一题. 什么是Spring MVC&#xff1f;简单介绍下你对Spring MVC的理解&#xff1f;第二题. Spring MVC的优点第三题. Spring MVC的主要组件&#xff1f;第四题. 什么是DispatcherServlet?第五题. 什么是Spring MVC框架的控制器&#xff1f; 第一题. 什么是S…

unity学习(49)——服务器三次注册限制以及数据库化角色信息4--角色信息数据库化

1.此处下断开始调试,list函数内就有问题&#xff1a; 2. 现在的问题是只读不写&#xff01;32行就是写入部分的代码&#xff1a; 3. 很奇怪&#xff0c;调试的时候确实是写进来了 程序正常执行后&#xff0c;文件中数据也没有消失 关闭服务器文件内容依旧正常。 players包含所…

安装sqlserver2022最新版只能使用.\SQLEXPRESS登录数据库怎么修改成.

.\SQLEXPRESS “服务器名称 localhost\SQLEXPRESS”中的 “SQLEXPRESS”就是数据库的实例名称/数据库名/服务器名&#xff0c; “localhost”即登录本计算机安装的数据库 安装sqlserver2022最新版只能使用.\SQLEXPRESS登录数据库怎么修改成. 2、查看SQL Server数据库的实例名…

Python从0到100(二):Python语言介绍及第一个Pyhon程序

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

导数与微分错题本

《1800》 1 缺乏构造函数的技巧 2 3 等价无穷小+构造函数 4

请说明Vue中的Error Boundaries

当我们开发基于Vue框架的应用时&#xff0c;我们经常会遇到各种错误处理的情况。Vue提供了一种非常强大且简单的方式来处理这些错误&#xff0c;那就是Error Boundaries&#xff08;错误边界&#xff09;。本文将从概念、用法和示例代码三个方面来详细介绍Vue中的Error Boundar…