C++单元测试之一种简单打桩方式的实现

论坛 期权论坛 期权     
大连飞创   2018-11-16 19:22   2803   0




  此篇文章涉及大量代码示例更适合作为参考手册,需要时查查用法。对于技术人员代码是最好的解释。

  桩,或称桩代码,是指用来代替关联代码或者未实现代码的代码。如果用函数B1来代替B,那么,B称为原函数,B1称为桩函数。打桩就是调用B的地方变成调用B1。
  打桩主要涉及两点:
  第一如何获取原函数地址
  第二如何用桩函数替换原函数

  源码:
  https://pan.baidu.com/s/
1-vGdA49ez6WLiOmkWZ-o6Q


桩函数替换原函数的原理介绍
  主要用到inline hook技术,核心思想,通过替换目标函数头部指令,实现在函数执行之前跳转到其他的指令区域,执行完毕跳转回到原来的函数,跳转到的指令区域通常是我们自己编写的函数。
  图1所示,如果原函数和桩函数同在32地址空间里,则采用JMP指令实现,占5字节。
  图2所示,如果原函数和桩函数不同在32地址空间里,则采用MOV、PUSH、RET指令实现,占12字节。

图1

图2

关键替换源码解释:




获取原函数地址,
各种函数的打桩用法
  各种类函数地址的获取方式各不相同,不同平台同种类的获取方式也不同,下面将会列举一些常见类型函数的地址获取方式。
  桩函数写法基于调用约定,C++中常见的调用约定有stdcall、cdecl、fastcall和thiscall
普通函数打桩(非static)

静态成员函数打桩

实例成员函数打桩



模板函数打桩(实例成员函数)


重载函数打桩(实例成员函数)


虚函数打桩



内联函数打桩

第三方库私有成员函数打桩




static函数打桩


  说明:
  只适用linux,和windows的x86、x64架构
  不可以打桩的情况:
  不可以对exit函数打桩,编译器做了特殊优化
  不可以对纯虚函数打桩,纯虚函数没有地址
  linux下单元测试一些编译选项:



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3174
帖子:645
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP