IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Linux下C++中可使用的3种Hook方法 -> 正文阅读

[C++知识库]Linux下C++中可使用的3种Hook方法

? ? ? Hook即钩子,截获API调用的技术,是将执行流程重定向到你自己的代码,类似于hack。如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数。这里介绍下Linux下C++中可使用的3中Hook方法:

? ? ? 1. GNU C库允许你通过指定适当的钩子函数(hook function)来修改malloc、realloc和free的行为,钩子函数的声明在malloc.h文件中,如__malloc_hook, __free_hook,你可以使用这些钩子来帮助你调试使用动态内存分配的程序,但是用GCC编译时会提示这些接口已被废弃。

? ? ? 测试代码如下:

#include <malloc.h>
#include <stdio.h>

/* reference:
	http://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html
	https://stackoverflow.com/questions/11356958/how-to-use-malloc-hook
*/
void* (*old_malloc_hook)(size_t, const void*);
void (*old_free_hook)(void* __ptr, const void*);
void my_free_hook(void* ptr, const void* caller);

void* my_malloc_hook(size_t size, const void* caller)
{
	void *result;
	// Restore all old hooks
	__malloc_hook = old_malloc_hook;
	__free_hook = old_free_hook;
	// Call recursively
	result = malloc(size);
	// Save underlying hooks
	old_malloc_hook = __malloc_hook;
	old_free_hook = __free_hook;
	// printf might call malloc, so protect it too.
	printf("malloc (%u) returns %p\n", (unsigned int) size, result);
	// Restore our own hooks
	__malloc_hook = my_malloc_hook;
	__free_hook = my_free_hook;
	return result;
}

void my_free_hook(void *ptr, const void *caller)
{
	// Restore all old hooks
	__malloc_hook = old_malloc_hook;
	__free_hook = old_free_hook;
	// Call recursively
	free(ptr);
	// Save underlying hooks
	old_malloc_hook = __malloc_hook;
	old_free_hook = __free_hook;
	// printf might call free, so protect it too.
	printf("freed pointer %p\n", ptr);
	// Restore our own hooks
	__malloc_hook = my_malloc_hook;
	__free_hook = my_free_hook;
}

void my_init(void)
{
	old_malloc_hook = __malloc_hook;
	old_free_hook = __free_hook;
	__malloc_hook = my_malloc_hook;
	__free_hook = my_free_hook;
}

int main()
{
	my_init();

	void* p = malloc(10);
	free(p);

	fprintf(stdout, "test finish\n");
	return 0;
}

? ? ?build.sh内容如下:

#! /bin/bash

g++ test.cpp
echo -e "**** start run ****\n"
./a.out

? ? ? 执行结果如下:

?

? ? ? 2. 使用LD_PRELOAD环境变量:可以设置共享库的路径,并且该库将在任何其它库之前加载,即这个动态库中符号优先级是最高的。如果系统库函数使用内联优化,如strcmp,则在编译程序时,可能需添加-fno-builtin-strcmp。

? ? ? 测试代码test.cpp如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

int main()
{
	srand(time(NULL));
	for (int i = 0; i < 2; ++i)
		fprintf(stdout, "value: %02d\n", rand() % 100);

	const char* str1 = "https://blog.csdn.net/fengbingchun";
	const char* str2 = "https://github.com/fengbingchun";
	fprintf(stdout, "are they equal: %d\n", strcmp(str1, str2));

	fprintf(stdout, "test finish\n");
	return 0;
}

? ? ? 测试代码hook.cpp如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int rand()
{
	fprintf(stdout, "_^_ set rand function to a constant: 88 _^_\n");
	return 88;
}

int strcmp(const char* str1, const char* str2)
{
	fprintf(stdout, "_^_ set strcmp function to a constant: 0 _^_\n");
	return 0;
}

? ? ? build.sh内容如下:

#! /bin/bash

g++ -shared -fPIC -o libhook.so hook.cpp
g++ test.cpp
echo -e "**** start run ****\n"
LD_PRELOAD=${PWD}/libhook.so ./a.out

? ? ? 执行结果如下:

?

? ? ? 3. 使用GCC的--wrap选项:对symbol使用包装函数(wrapper function),任何对symbol未定义的引用(undefined reference)会被解析成__wrap_symbol,而任何对__real_symbol未定义的引用会被解析成symbol。即当一个名为symbol符号使用wrap功能时,程序中任何用到symbol符号的地方实际使用的是__wrap_symbol符号,任何用到__real_symbol的地方实际使用的是真正的symbol。注意:当__wrap_symbol是使用C++实现时,一定要加上extern “C”,否则将会出现”undefined reference to __wrap_symbol”。

? ? ? 测试代码test.cpp如下:

#include <stdio.h>
#include <stdlib.h>

extern "C" {

void* __real_malloc(size_t size);
void __real_free(void* ptr);
extern void foo();
void __real_foo();

void* __wrap_malloc(size_t size)
{
	fprintf(stdout, "_^_ call wrap malloc function _^_\n");
	return __real_malloc(size);
}

void __wrap_free(void* ptr)
{
	fprintf(stdout, "_^_ call wrap free function _^_\n");
	__real_free(ptr);
}

void __wrap_foo()
{
	fprintf(stdout, "_^_ call wrap foo function _^_\n");
}

} // extern "C"

int main()
{
	foo();
	__real_foo();

	void* p1 = malloc(10);
	free(p1);

	fprintf(stdout, "test finish\n");
	return 0;
}

? ? ? 测试代码foo.cpp如下:

#include <stdio.h>

extern "C" {

void foo()
{
	fprintf(stdout, "call foo function\n");
}

} // extern "C"

? ? ? build.sh内容如下:

#! /bin/bash

g++ foo.cpp test.cpp -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=foo
echo -e "**** start run ****\n"
./a.out

? ? ? 执行结果如下:

?

? ? ? Windwos上的Hook是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其它进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理Windows消息或特定事件。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。

? ? ? GitHubhttps://github.com/fengbingchun/Linux_Code_Test

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:04:14  更:2021-12-06 15:06:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:48:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码