native层函数没有导出时,如何获得相应函数地址?

文章讲述了在Android应用中,由于native函数的地址在每次App运行时可能会变化,但相对于基地址的偏移保持不变。通过Frida的Module.findBaseAddress和add方法可以获取函数地址。以一个具体的例子展示了如何动态注册native方法stringFromJNI3,并使用Frida的hook(RegisterNatives)脚本来找到函数的偏移地址,然后编写hookNative.js脚本进行函数拦截。强调了App重新编译可能导致函数偏移地址改变,需要更新hook脚本。

前言

每次App重新运行后native函数加载的绝对地址是会变化的,唯一不变的是函数相对于基地址的偏移,因此我们可以在获取模块的基地址后加上固定的偏移地址获取相应函数的地址,Frida中也正好提供了这种方式:先通过Module.findBaseAddress(name)或Module.getBaseAddress(name)两个API函数获取对应模块的基地址,然后通过add(offset)函数传入固定的偏移offset获取最后的函数绝对地址。以下使用stringFromJNI3中的stringFromJNI3作为具体案例讲解下思路和注意的点。

动态注册的函数

// MainActivity.java
package com.roysue.ndktest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.roysue.ndktest.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {
   
   

    // Used to load the 'ndktest' library on application startup.
    static {
   
   
        System.loadLibrary("ndktest");
    }

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
   
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater()
<think>好的,用户想了解如何查看DLL文件中导出函数名称,以便在Qt工程中正确调用第三方库。根据之前的对话,用户已经知道需要显式加载DLL,但可能遇到了如何确定函数名的问题。现在需要详细说明工具和方法。首先,用户提到的引用中提到了Dependency Walker(depends.exe),这是一个常用的工具。需要详细说明使用步骤,包括下载、打开DLL、查看导出函数部分。同,引用里还提到了dumpbin工具,这是Visual Studio自带的命令行工具,可以列出导出函数。这部分需要分步骤说明,包括如何打开VS开发人员命令提示符,运行命令。另外,用户可能使用的是其他工具,比如Objdump(MinGW/GCC)或第三方工具如PE Explorer,这些可以作为补充方法。需要简要介绍这些工具的用法,确保用户有多个选择。注意事项部分,需要强调调用约定和名称修饰的问题,比如C++的name mangling会导致函数名复杂,这候可能需要使用extern "C"或者查看修饰后的名称。同,位数匹配(32/64位)也很重要,否则加载会失败。 最后,相关问题需要覆盖用户可能的后续问题,比如如何处理C++导出的类,如何跨平台加载,或者如何逆向分析没有文档的DLL。这些扩展问题能帮助用户更全面地解决问题。</think>### 如何查看DLL导出函数名称 通过以下工具和方法可准确列出DLL文件中导出函数名称,为Qt工程动态加载提供必要信息: --- #### 一、使用 **Dependency Walker**(推荐) 1. **下载工具** - 官网地址:[Dependency Walker Home Page](http://www.dependencywalker.com/) - 支持Windows系统,绿色版无需安装 2. **查看导出函数** ```plaintext 1. 打开depends.exe 2. 菜单栏选择 文件 → 打开 → 选择目标DLL 3. 在右侧"Export Functions"(E列)查看所有导出函数 ``` - **函数名称显示规则**: - C语言导出函数直接显示原始名称(如`add`)[^2] - C++导出函数显示修饰名(如`?add@@YAHHH@Z`)[^3] - **关键信息**:函数序号(Ordinal)、调用约定(调用约定符号如`_stdcall`) --- #### 二、使用 **Visual Studio命令工具** 通过`dumpbin`命令直接解析DLL导出表: 1. **打开开发者命令提示符** - 搜索并运行 **"x64 Native Tools Command Prompt"**(根据DLL位数选择32/64位) 2. **执行导出分析** ```bash dumpbin /exports your.dll ``` - **输出示例**: ```plaintext ordinal hint RVA name 1 0 00001000 ?add@@YAHHH@Z 2 1 00002000 func2 ``` - **注意**:若函数名含C++修饰,需结合`.def`文件或逆向分析还原原始名称[^3] --- #### 三、其他工具 1. **Objdump(MinGW/GCC环境)** ```bash objdump -p your.dll | grep "Export" ``` 2. **第三方工具** - **PE Explorer**:商业工具,可解析复杂名称修饰 - **CFF Explorer**:免费工具,支持导出函数反编译 --- ### 四、关键注意事项 1. **C++名称修饰问题** - 若DLL使用C++编写且未用`extern "C"`,需通过修饰名调用[^3] - 示例:`typedef int (*Func)(int);`对应修饰名`?Func@@YAHH@Z` 2. **调用约定匹配** - 导出函数若使用`__stdcall`,名称可能带后缀(如`_add@8`,`8`表示参数总字节数) 3. **位数匹配** - 确保工具与DLL的架构一致(32位工具无法解析64位DLL) --- ### 示例:Qt中加载含修饰名的函数 ```cpp QLibrary lib("mydll.dll"); if (lib.load()) { // 加载C++修饰函数 typedef int (*DecoratedFunc)(int); DecoratedFunc func = (DecoratedFunc)lib.resolve("?add@@YAHHH@Z"); if (func) { int result = func(3, 5); } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗雅颂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值