当前位置: 首页 > news >正文

Rust:实现仅通过索引(序数)导出 DLL 函数的功能

在 Rust 中,可以通过手动控制导出来实现仅通过索引(序数)导出 DLL 函数的功能。以下是具体方法和完整步骤:


解决方案

通过结合 .def 文件(模块定义文件)和 MSVC 链接器参数来实现函数名隐藏,只暴露序数编号。


具体步骤

1. 创建 Rust 动态库项目

Cargo.toml 中配置 cdylib 类型:

[lib]
crate-type = ["cdylib"]
2. 编写 Rust 函数

使用 #[no_mangle]extern "C" 定义导出函数:

// src/lib.rs
#[no_mangle]
pub extern "C" fn secret_function1() -> i32 {42
}#[no_mangle]
pub extern "C" fn secret_function2(x: i32) -> i32 {x * 2
}
3. 创建模块定义文件(.def

创建 exports.def 文件,用 NONAME 隐藏函数名并分配序数:

EXPORTS; 语法: 函数名 @序数 NONAMEsecret_function1 @1 NONAMEsecret_function2 @2 NONAME
4. 设置编译链接参数

修改 .cargo/config.toml,添加 MSVC 链接器标志:

# .cargo/config.toml
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "link-args=/DEF:exports.def /EXPORT:NONE"]

注意:路径需根据项目结构调整(也可用绝对路径)

5. 编译项目
cargo build --release

生成的 target/release/your_lib.dll 将隐藏函数名。


验证导出结果

使用 dumpbin 工具检查导出表(确保 VS Developer Command Prompt 中运行):

dumpbin /EXPORTS target/release/your_lib.dll

输出应类似:

ordinal hint RVA      name1    0 00001000 [NONAME]2    1 00001010 [NONAME]

从调用方通过索引加载

在 C/C++ 中通过序数加载函数(示例):

#include <windows.h>
#include <stdio.h>typedef int (*Func1)();
typedef int (*Func2)(int);int main() {HINSTANCE hDll = LoadLibraryA("your_lib.dll");if (!hDll) return 1;// 通过序数1加载第一个函数Func1 f1 = (Func1)GetProcAddress(hDll, (LPCSTR)1);// 通过序数2加载第二个函数Func2 f2 = (Func2)GetProcAddress(hDll, (LPCSTR)2);printf("f1: %d\n", f1());    // 输出 42printf("f2: %d\n", f2(10));  // 输出 20FreeLibrary(hDll);return 0;
}

关键点说明

  1. NONAME 关键字
    .def 文件中强制使用序数导出,隐藏函数名称。

  2. /EXPORT:NONE
    禁止 Rust 的默认名称导出规则,确保只有 .def 中的定义生效。

  3. 序数分配
    序数必须唯一且从 1 开始(序数 0 保留)。

  4. 工具链限制
    此方案仅适用于 MSVC 工具链x86_64-pc-windows-msvc)。如需 GNU 工具链,需改用 dlltool(流程较复杂)。


替代方案

如果需要在 GNU 工具链(如 x86_64-pc-windows-gnu)实现:

  1. 使用 dlltool 生成 .a 导入库
  2. 手动控制 .defdlltool 参数
    但 GNU 方案较为复杂,推荐优先使用 MSVC 链。

通过以上步骤,可在 Rust 中编译出仅通过索引导出的 DLL 文件,有效隐藏内部符号名称。

http://www.lryc.cn/news/623391.html

相关文章:

  • Node.js导入MongoDB具体操作
  • Kafka 面试题及详细答案100道(23-35)-- 核心机制2
  • 【前端面试题】前端面试知识点(第三十一题到第六十一题)
  • 计算机毕设选题推荐-基于大数据的全面皮肤病症状数据可视化分析系统【Hadoop、spark、python】
  • day42_2025-08-16
  • ArrayList的contains问题
  • 大模拟 Major
  • 扫地机器人(2025蓝桥杯省A组 H题)
  • 【P14 3-6 】OpenCV Python——视频加载、摄像头调用、视频基本信息获取(宽、高、帧率、总帧数),视频保存在指定位置
  • LeetCode 刷题【43. 字符串相乘】
  • 安卓11 12系统修改定制化_____修改运营商版本安装特定应用时的默认规则
  • 美国服务器环境下Windows容器工作负载基于指标的自动扩缩
  • 基于 LoRA的广义知识蒸馏(GKD)训练
  • 【总结型】c语言中的位运算
  • Java -- 泛型-自定义泛型
  • 在职老D渗透日记day18:sqli-labs靶场通关(第26关)get报错注入 过滤or和and基础上又过滤了空格和注释符 ‘闭合 手动注入
  • Qt 动态属性(Dynamic Property)详解
  • 牛 CDR3 单抗:抗病毒领域的 “纳米级精准导弹”
  • 系统思考—啤酒游戏经营决策沙盘认证
  • 第二十五天:构造函数/析构函数/拷贝构造
  • SpringBoot 整合 Langchain4j:系统提示词与用户提示词实战详解
  • 小白学习《PCI Express体系结构导读》——第Ⅰ篇第1章PCI总线的基本知识
  • 《A Practical Guide to Building Agents》文档学习
  • Nginx蜘蛛请求智能分流:精准识别爬虫并转发SEO渲染服务
  • 23. CommonJS 和 ES6 Module 区别
  • 第6问 数据分析领域主要的岗位有哪些?
  • autofit.js: 自动调整HTML元素大小的JavaScript库
  • Java设计模式详细解读
  • 安卓四大组件基础题
  • AI搜索:大模型商业落地的“第一束光”,照见了什么?