日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Linux下C++中可使用的3种Hook方法

發布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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.htmlhttps://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 recursivelyresult = malloc(size);// Save underlying hooksold_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 recursivelyfree(ptr);// Save underlying hooksold_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/bashg++ 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/bashg++ -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/bashg++ foo.cpp test.cpp -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=foo
echo -e "**** start run ****\n"
./a.out

? ? ? 執行結果如下:

?

? ? ? Windwos上的Hook是Windows消息處理機制的一個平臺,應用程序可以在上面設置子程以監視指定窗口的某種消息,而且所監視的窗口可以是其它進程所創建的。當消息到達后,在目標窗口處理函數之前處理它。鉤子機制允許應用程序截獲處理Windows消息或特定事件。鉤子實際上是一個處理消息的程序段,通過系統調用,把它掛入系統。

? ? ? GitHub:https://github.com/fengbingchun/Linux_Code_Test

總結

以上是生活随笔為你收集整理的Linux下C++中可使用的3种Hook方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。