c++ 动态二进制插桩 c++如何使用intel pin或dynamorio

云丽酱_4389

云丽酱_4389

2026-03-28

562人浏览

原创

intel pin 和 dynamorio 是二进制插桩框架,非普通 c++ 库,需编译为共享对象并注册特定回调;插桩时机、粒度与内存监控受限于运行时行为与框架机制,调试需规避递归插桩与寄存器污染。

c++ 动态二进制插桩 c++如何使用intel pin或dynamorio

Intel Pin 和 DynamoRIO 本质不是 C++ 库,不能直接 #include 调用

很多人以为装好 Pin 或 DynamoRIO 就能像普通 C++ 第三方库一样链接使用,结果编译报错:undefined reference to PIN_Init 或找不到头文件。这不是你代码写错了,是根本没搞清它们的运行模型——它们是二进制插桩框架,靠在运行时动态加载你的 tool(一个编译好的共享对象),再由框架自身接管目标程序的执行流。

实操建议:

  • Pin 工具必须编译为 .so(Linux)或 .dll(Windows),且入口函数固定为 main(实际由 PIN_StartProgram() 启动),不能写成普通可执行程序
  • DynamoRIO 的 tool 必须用它提供的 drbuild 或 CMake 工具链构建,直接 g++ 编译会缺 -ldrt 和运行时符号重定向
  • 头文件路径不是系统默认路径:Pin 需指定 $PIN_ROOT/source/include,DynamoRIO 需 $DR_HOME/ext 和 $DR_HOME/src

Instrumentation callback 注册时机决定你能看到什么指令

插桩不是“把所有指令都给你看一遍”,而是靠注册回调,在特定时刻被框架触发。注册太早或太晚,都会漏掉关键指令——比如 INS_AddInstrumentFunction(Pin)或 dr_register_bb_event(DynamoRIO)只对后续 JIT 翻译的代码块生效,而进程刚启动时的 libc 初始化代码可能已被跳过。

常见错误现象:

  • 想监控 malloc 却始终收不到对应 INS —— 因为 malloc 在 Pin/DynamoRIO 自身初始化阶段就被调用了,你的回调还没注册上
  • 只看到 main 之后的指令,看不到 _start 或 PLT stub —— 默认不开启 SYSCALL 或 indirect branch 插桩

实操建议:

  • Pin 中用 PIN_AddApplicationStartFunction 注册 early init;DynamoRIO 用 dr_register_init_event 并配合 dr_enable_executable_alloc 才能覆盖初始代码段
  • 若需监控系统调用,Pin 要显式调用 SYSRET_AddInstrumentFunction,DynamoRIO 需启用 -inject_into_syscalls 并处理 dr_register_syscall_event
  • 注意指令粒度:Pin 的 INS_InsertCall 插入的是运行时 call,不是编译期函数调用;DynamoRIO 的 instrlist_meta_append 插入的是 IR 指令,不是原始 x86

内存访问监控(如 INS_MemoryRead)极易误触发或漏触发

想记录每次 mov rax, [rbx] 的读地址?别急着套 INS_IsMemoryRead + INS_InsertPredicatedCall。真实情况是:很多读操作被 CPU 优化掉(如寄存器重命名)、被 micro-op 合并、或发生在非用户态(如页表遍历),插桩点根本捕获不到。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

使用场景限制:

  • 仅对用户态、已映射、非原子、非 SSE/AVX 寄存器间接寻址的内存操作有效
  • Pin 中 INS_MemoryReadSize 返回 0 表示该指令无显式内存读(哪怕有 [rax])—— 它只识别真正生成 memory operand 的指令
  • DynamoRIO 的 opnd_is_memory_reference 判断的是汇编语义,不是运行时行为;实际访问是否发生,还得靠 dr_insert_clean_call 里用 dr_read_saved_reg 取值后检查

性能影响显著:

  • 每个内存访问插桩平均增加 10–50 倍执行开销,高频分配(如 vector push_back)会让程序慢到无法交互
  • 建议先用 INS_AddressTaken 过滤出真正取地址的指令,再结合 INS_HasFallThrough 排除跳转指令干扰

调试 tool 本身比调试目标程序还难

你的 tool 出了段错误,是 Pin/DynamoRIO 框架崩了?是你插桩逻辑改坏了栈帧?还是 target 程序触发了反调试?三者混在一起,gdb attach 后看到的堆栈全是框架内部符号,bt 没几行是你写的。

容易踩的坑:

  • 在 Pin 的 INS_InsertCall 里调用 printf 或 std::string —— 这些函数内部会再次触发插桩,造成无限递归或锁死
  • DynamoRIO 的 clean call 必须用 dr_save_reg/dr_restore_reg 保护寄存器,否则目标程序恢复执行时寄存器值错乱
  • 忘记关闭 ASLR(echo 0 | sudo tee /proc/sys/kernel/randomize_va_space)会导致每次重跑地址偏移不同,日志对不上

实操建议:

  • Pin 下用 -log 生成 trace 文件,比实时 printf 更可靠;DynamoRIO 用 -loglevel 3 -logfile dr.log
  • 工具初始化阶段先 dr_register_exit_event 写个 cleanup handler,避免 SIGINT 杀进程时资源没释放
  • 真要 gdb,Pin 加 -pause_tool 30 等待 attach;DynamoRIO 用 -debug 启动后 dr_attach_to_process

最麻烦的从来不是怎么插,而是插完之后——你拿到的那串地址、寄存器值、指令编码,到底对应哪一行源码、哪个优化后的变量、甚至是不是已经被编译器彻底优化掉了。这时候符号表、debug info、inlining 层级,全得手动对齐。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5899

3

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

2023.06.20

728

5

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.28

1009

10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5347

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2348

6

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5347

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2348

6

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

2023.07.31

11705

4

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2024.08.14

5507

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习