最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在C++中使用HOOK修改sleep函數(shù)的方法

 更新時(shí)間:2025年12月15日 09:00:19   作者:koddnty  
Hook(鉤子)是一種編程機(jī)制,它允許開發(fā)者在程序執(zhí)行的特定點(diǎn)插入自定義代碼,從而攔截、處理或修改原有的函數(shù)調(diào)用、消息傳遞或系統(tǒng)事件,本篇文章將以sleep函數(shù)為例子介紹如何在c++中使用hook修改系統(tǒng)函數(shù),需要的朋友可以參考下

HOOK是什么

Hook(鉤子)是一種編程機(jī)制,它允許開發(fā)者在程序執(zhí)行的特定點(diǎn)插入自定義代碼,從而攔截、處理或修改原有的函數(shù)調(diào)用、消息傳遞或系統(tǒng)事件。

通俗地說,Hook就像是給程序安裝了一個(gè)“監(jiān)聽器”或“攔截器”。當(dāng)目標(biāo)函數(shù)被調(diào)用時(shí),控制權(quán)會(huì)先轉(zhuǎn)移到你的Hook代碼,你可以在執(zhí)行原有操作之前或之后插入自定義邏輯,甚至完全替換原有行為。例如游戲外 掛通過hook來對(duì)游戲運(yùn)行時(shí)用到的函數(shù)或其他API進(jìn)行修改來實(shí)現(xiàn)外 掛的功能。同時(shí),hook也常與協(xié)程搭配使用,修改系統(tǒng)函數(shù)來為類似sleep等阻塞線程的函數(shù)添加協(xié)程的功能。

如何使用hook來修改sleep函數(shù)

下面的代碼是最簡(jiǎn)單的hook的實(shí)現(xiàn)

#include <iostream>
#include <unistd.h>

extern "C" unsigned int sleep(unsigned int seconds)
{
    std::cout << "我們成功修改了系統(tǒng)提供的sleep函數(shù)!" << std::endl;
    return 0;
}

void test1()
{
    std::cout << "使用sleep函數(shù)睡2s"<< std::endl;
    sleep(2);
    std::cout << "sleep函數(shù)睡完了"<< std::endl;
}

調(diào)用函數(shù)test1(),程序運(yùn)行結(jié)果如下:

使用sleep函數(shù)睡2s
我們成功修改了系統(tǒng)提供的sleep函數(shù)!
sleep函數(shù)睡完了

在上面的代碼中,我們僅做了兩件事

  • 實(shí)現(xiàn)一個(gè)sleep函數(shù),與unistd.h中的sleep函數(shù)簽名一致
  • 使用extern "C"告訴C++編譯器"按C語言的方式處理這個(gè)函數(shù)"

定義一個(gè)相同簽名的sleep為什么鏈接過程中不會(huì)產(chǎn)生重定義問題呢?在鏈接器鏈接過程中,函數(shù)符號(hào)有類似強(qiáng)弱符號(hào)之分,在動(dòng)態(tài)庫中的函數(shù)會(huì)被新目標(biāo)文件的函數(shù)替換,因此此處程序運(yùn)行時(shí)會(huì)運(yùn)行我們重新寫的sleep函數(shù)而不是unistd.h內(nèi)的。

至于加extern "C"的作用,在c++編譯過程中,為了區(qū)分不同的重載函數(shù),編譯器會(huì)給同名函數(shù)加入隨即字符進(jìn)行區(qū)分,我們的目的是重寫sleep函數(shù),因此要確保函數(shù)名與unistd.h中相同,通過加入extern "C"來做到這一點(diǎn)

對(duì)上述代碼的改進(jìn)

上述代碼存在很大的缺陷,最主要的是它失去了sleep函數(shù)最基本的功能。通常我們利用hook修改函數(shù)時(shí),我們需要維持其原有功能。我們不可能真的去實(shí)現(xiàn)一個(gè)完整的sleep,但我們可以獲得原sleep的函數(shù)指針

在不同的平臺(tái)有不同的獲取庫函數(shù)指針的方法,下面時(shí)在linux平臺(tái)來獲取sleep函數(shù)指針的例子:

獲取sleep函數(shù)指針

linux為獲取庫函數(shù)指針提供了特定的函數(shù)dlsym,定義在<dlfcn.h>中。其函數(shù)簽名為:

void *dlsym(void *restrict handle, const char *restrict symbol);

dlsym返回值是函數(shù)指針,其第一個(gè)參數(shù)是指定查找的庫,第二個(gè)參數(shù)傳入函數(shù)名稱。

在hook場(chǎng)景中,handle參數(shù)常取RTLD_NEXT,表示跳過當(dāng)前庫查找其他庫。也就是說,當(dāng)symbol傳入"sleep"時(shí),dlsym跳過當(dāng)前庫我們定義的sleep,找到了unistd.h定義的sleep函數(shù),并返回其函數(shù)指針。

代碼改進(jìn)

有了上邊提供的函數(shù),我們可以保存原有sleep函數(shù)并給他加點(diǎn)"小料",代碼如下:

#include <iostream>
#include <unistd.h>
#include <dlfcn.h>
using sleep_fun_type = unsigned int (*)(unsigned int seconds);

sleep_fun_type original_sleep = NULL;

extern "C" unsigned int sleep(unsigned int seconds)
{
    std::cout << "我們成功修改了系統(tǒng)提供的sleep函數(shù)!" << std::endl;
    return original_sleep(seconds);                             // <-----這里調(diào)用我們保存下來的原始的sleep
}

void test1()
{
    original_sleep = (sleep_fun_type)dlsym(RTLD_NEXT, "sleep"); // <-----這里獲得了unistd中的sleep

    std::cout << "使用sleep函數(shù)睡2s"<< std::endl;
    sleep(2);                                                   // <-----這里調(diào)用我們自己寫的sleep
    std::cout << "sleep函數(shù)睡完了"<< std::endl;
}

代碼相較于開始,只做了一點(diǎn)改進(jìn),即保存原始sleep函數(shù),并在我們自己定義的sleep函數(shù)中調(diào)用保存的原始sleep函數(shù)。

需注意的是,編譯時(shí)應(yīng)加上-ldl選項(xiàng)鏈接動(dòng)態(tài)庫

總結(jié)

上述代碼仍有許多不完善的地方,實(shí)際過程中要檢查dlsym返回值是否為NULL等問題,同時(shí)代碼對(duì)初始化并不規(guī)范,可以使用下面的初始化方法(gcc編譯器),也可以使用其他更兼容的方法進(jìn)行初始化。

__attribute__((constructor)) void init_hook()       // gcc編譯器提供,main函數(shù)運(yùn)行前,庫和內(nèi)存初始化完成后運(yùn)行
{
    // 在main函數(shù)執(zhí)行前先初始化—original_sleep。
    original_sleep = (SleepFunc)dlsym(RTLD_NEXT,"sleep");
}

最后,需要注意的是,如果采用上述方法重新定義sleep,會(huì)使所有庫運(yùn)行的sleep函數(shù)都改變成我們自己定義的sleep,如果返回值與原sleep存在差異,可能導(dǎo)致一些其他的隱含問題。

以上就是在C++中使用HOOK修改sleep函數(shù)的方法的詳細(xì)內(nèi)容,更多關(guān)于C++ HOOK修改sleep函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于C++和MFC開發(fā)象棋程序

    基于C++和MFC開發(fā)象棋程序

    這篇文章主要為大家詳細(xì)介紹了基于C++和MFC開發(fā)象棋程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Linux系統(tǒng)下C語言中的標(biāo)準(zhǔn)IO總結(jié)

    Linux系統(tǒng)下C語言中的標(biāo)準(zhǔn)IO總結(jié)

    最近用到了C語言的標(biāo)準(zhǔn)IO庫,由于對(duì)其中的一些細(xì)節(jié)不是非常清楚,導(dǎo)致了許多Bug,花了好長時(shí)間來調(diào)試,所以在此做個(gè)筆記,這篇文章主要給大家介紹了關(guān)于Linux系統(tǒng)下C語言中標(biāo)準(zhǔn)IO的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • C++ COM編程之QueryInterface函數(shù)(一)

    C++ COM編程之QueryInterface函數(shù)(一)

    這篇文章主要介紹了C++ COM編程之QueryInterface函數(shù)(一),QueryInterface是組件本身提供對(duì)自己查詢的一個(gè)接口,需要的朋友可以參考下
    2014-10-10
  • C++11中std::future的具體使用方法

    C++11中std::future的具體使用方法

    這篇文章主要介紹了C++11中std::future的具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • VC雙畫布消除屏幕閃爍實(shí)例詳解

    VC雙畫布消除屏幕閃爍實(shí)例詳解

    這篇文章主要介紹了VC雙畫布消除屏幕閃爍實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C語言的循環(huán)小練習(xí)詳解

    C語言的循環(huán)小練習(xí)詳解

    這篇文章主要為大家介紹了C語言的循環(huán)小練習(xí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • C++ Qt之halcon讀取像素項(xiàng)目過程詳解

    C++ Qt之halcon讀取像素項(xiàng)目過程詳解

    這篇文章主要介紹了C++ Qt之halcon讀取像素項(xiàng)目過程詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 詳解C++構(gòu)造函數(shù)

    詳解C++構(gòu)造函數(shù)

    這篇文章主要為大家介紹了C++構(gòu)造函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • C++ Boost實(shí)現(xiàn)數(shù)字與字符串轉(zhuǎn)化詳解

    C++ Boost實(shí)現(xiàn)數(shù)字與字符串轉(zhuǎn)化詳解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個(gè)可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • 手把手帶你學(xué)習(xí)C++的數(shù)據(jù)類型

    手把手帶你學(xué)習(xí)C++的數(shù)據(jù)類型

    這篇文章主要為大家介紹了C++的數(shù)據(jù)類型,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助,希望能夠給你帶來幫助
    2021-11-11

最新評(píng)論

翁牛特旗| 达尔| 阿拉善左旗| 嵊州市| 家居| 海兴县| 沈丘县| 天长市| 沂南县| 淅川县| 平阳县| 中阳县| 连山| 平乐县| 榕江县| 商南县| 梓潼县| 合山市| 朝阳县| 武功县| 墨脱县| 黔江区| 扎兰屯市| 边坝县| 凤阳县| 高州市| 朝阳县| 砀山县| 英德市| 福贡县| 乌兰浩特市| 明水县| 旌德县| 德江县| 永寿县| 伽师县| 武安市| 十堰市| 株洲县| 陆河县| 陆川县|