<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    x64dbg插件編寫基礎

    VSole2023-04-13 09:28:19

    ?

    一、x64dbg擴展功能的三種方式

    x64dbg擴展功能的方式有三種:

    ① 寫腳本(python或者idc)。

    ② 腳本DLL,就是編寫一個DLL導出 AsyncStart() or Start(),然后通過命令scriptdll/dllscript來加載DLL執行代碼。

    ③ 編寫插件。

    在x64dbg的文檔中并沒有說明 "插件" 到底是一個什么東西,只是說插件的后綴名叫dp32或者dp64,通過觀察其他的插件發現其實就是DLL,只不過是導出了一些指定函數的DLL。

    本文的目的就是說明編寫x64dbg插件的步驟,然后編寫一個簡單的x64dbg插件。

    二、環境配置

    本機環境:win11 21h2、vs2022、x64dbg(snapshot_2023-01-25_11-53)

    2.1 x64的SDK

    要給x64dbg編寫插件肯定需要x64dbg提供的sdk包,sdk包就在x64dbg的根目錄之下的pluginsdk文件夾中:

    ├───pluginsdk│   ├───dbghelp│   ├───DeviceNameResolver│   ├───jansson│   ├───lz4│   ├───TitanEngine│   └───XEDParse└───release    ├───...
    

    在pluginsdk中有x64dbg自己提供的頭文件和lib文件,以及它使用的其他第三方庫的頭文件和lib文件,比如XEDParse、TitanEngine等。

    2.2 配置vs工程

    先創建一個VS的DLL工程,這一步不必多說。

    將整個pluginsdk文件夾拷貝到工程目錄之下,雖然多了很多東西,但是比少拷貝了文件去找要好。

    然后配置頭文件目錄和lib文件的目錄以及引入lib文件:

    在工程屬性->vc++目錄->外部包含目錄加入pluginsdk路徑;

    在工程屬性->vc++目錄->庫目錄加入pluginsdk路徑;

    在工程屬性->鏈接器->輸入->附加依賴項中添加 x32bridge.lib和x32dbg.lib,這也是pluginsdk下唯二的兩個lib。

    三、基本導出函數

    3.1 pluginit

    函數聲明:

    extern "C" __declspec(dllexport) bool pluginit(PLUG_INITSTRUCT* initStruct);
    

    pluginit函數是x64dbg插件必須導出的一個函數。

    在整個函數中,要做的事件就是填充參數initStruct:

    struct PLUG_INITSTRUCT{    [IN] int pluginHandle; //插件的句柄    [OUT] int sdkVersion; //填 PLUG_SDKVERSION 即可    [OUT] int pluginVersion; // 填插件的版本    [OUT] char pluginName[256]; // 填插件指針};
    

    所以在pluginit中要做的事情就是填寫插件的基本信息:

    //必需的,插件初始化函數extern "C" __declspec(dllexport) bool pluginit(PLUG_INITSTRUCT * initStruct){    _plugin_logprintf("[%s] pluginit\r", TAG);//打印日志     memcpy_s(        initStruct->pluginName,        sizeof(initStruct->pluginName),        TAG,        strlen(TAG));    initStruct->sdkVersion = PLUG_SDKVERSION;    initStruct->pluginVersion = 1;     if (!InitPlugin())//做一些初始化動作    {        _plugin_logprintf("[%s] pluginit Failed\r", TAG);//打印日志        return false;    }    return true;}
    

    3.2 plugstop和plugsetup

    這兩個導出函數不是必須的,但是可以在里面做一些事情:

    plugstop:插件被移除的時候被調用,可以用來清除注冊的回調和命令,清理資源。

    plugsetup:當插件初始化成功的時候調用,可以在這里添加菜單、做其他的界面相關的事情。

    本例在plugsetup中添加了兩個子菜單,代碼如下:

    //非必需,插件被移除時調用extern "C" __declspec(dllexport) bool plugstop(){    _plugin_logprintf("[%s] plugstop\r", TAG);    return true;} //非必需,啟動插件時調用//在這里執行UI操作,比如增加菜單extern "C" __declspec(dllexport) void plugsetup(PLUG_SETUPSTRUCT * setupStruct){    _plugin_logprintf("[%s] plugsetup\r", TAG);     //添加子菜單    _plugin_menuaddentry(setupStruct->hMenu, 0, "enable UEH");    _plugin_menuaddentry(setupStruct->hMenu, 1, "disable UEH");}
    

    四、事件回調函數

    當我們添加了插件的子菜單之后,要如何響應菜單的點擊呢?

    導出以CB開頭的函數就可以去接收到對應的事件,比如:

    extern "C" __declspec(dllexport) void CBINITDEBUG(CBTYPE cbType, PLUG_CB_INITDEBUG* info); //初始化調試extern "C" __declspec(dllexport) void CBSTOPDEBUG(CBTYPE cbType, PLUG_CB_STOPDEBUG* info); //停止調試extern "C" __declspec(dllexport) void CBEXCEPTION(CBTYPE cbType, PLUG_CB_EXCEPTION* info); //異常extern "C" __declspec(dllexport) void CBDEBUGEVENT(CBTYPE cbType, PLUG_CB_DEBUGEVENT* info); //調試事件extern "C" __declspec(dllexport) void CBMENUENTRY(CBTYPE cbType, PLUG_CB_MENUENTRY* info); //點擊子菜單
    

    參數中所用到的結構體可以在這里找到:https://help.x64dbg.com/en/latest/developers/plugins/Callbacks/index.html,只要是滿足CB*的導出函數,且屬于這里面的類型。https://help.x64dbg.com/en/latest/developers/plugins/API/registercallback.html,應該都可以注冊成功,注意函數名中不要有下劃線。

    本例中,我們只需要簡單的響應一下子菜單的點擊:

    //菜單響應回調extern "C" __declspec(dllexport) void CBMENUENTRY(    CBTYPE bType,    PLUG_CB_MENUENTRY * pEntry){    switch (pEntry->hEntry)    {    case 0:    //注冊時填的菜單ID        EnableUeh();        break;    case 1:        DisableUeh();        break;    default:        break;    }}
    

    五、庫函數

    在插件中,我們可以調用Dbg開頭的函數來輔助功能,函數列表:https://help.x64dbg.com/en/latest/developers/functions/debug/index.html

    比如讀寫被調試進程可以使用:

    bool DbgMemRead(  duint va,  void* dest,  duint size); bool DbgMemWrite(duint va,void* dest,duint size);
    

    其他功能就暫時還沒探索,本例中用這兩個就夠啦。

    六、對UnhandledExceptionFilter打補丁

    本例中的插件需要實現對UnhandledExceptionFilter打補丁的功能,實現調試器可以調試UEH回調

    6.1 為什么要打補丁

    下面是筆者的通過測試的一點淺薄理解,沒有跟蹤系統的代碼,如有不對的地方還請大佬們指出。

    應用層派發異常的流程大致如下:

    根據上面的流程圖,在異常從SEH中出來的時候,根據是否有調試器,要么派發給調試器,要么派發給UEH回調,二選一,所以在調試的過程中不會之下UEH回調的代碼。

    為了能在調試器中調試UEH回調,我們需要改變一下系統異常分發的流程,使其走到另一個分支去。

    這個分支出現在kernelbase/kernel32!UnhandledExceptionFilter 中,所以需要對其打補丁。

    6.2 實現功能

    剩下的步驟就很簡單了,首先在插件初始化時,判斷系統版本,獲取UnhandledExceptionFilter 的地址,通過特征碼找到需要打補丁的地址。

    bool InitPlugin(){    //獲取版本號    DWORD dwBuildVer = GetVerSion();     PUCHAR pFuncBegin = (PUCHAR)GetProcAddress(        GetModuleHandleA("kernelbase"),        "UnhandledExceptionFilter");    if (pFuncBegin == NULL)    {        pFuncBegin = (PUCHAR)GetProcAddress(            GetModuleHandleA("kernel32"),            "UnhandledExceptionFilter");         if (pFuncBegin == NULL)        {            _plugin_logprintf("[%s] Get kernelbase!UnhandledExceptionFilter Addr Failed\r", TAG);            bIsEnabledUeh = false;            return false;        }    }     //獲取特征碼    if (dwBuildVer >= 22000)    {        //win11        g_pUehSig = UehSigWin11;        _plugin_logprintf("[%s] OS Build Number: %d\r", TAG, dwBuildVer);    }    else if (dwBuildVer == 7600 || dwBuildVer == 7601)    {        //win7        g_pUehSig = UehSigWin7;        _plugin_logprintf("[%s] OS Build Number: %d\r", TAG, dwBuildVer);    }     g_pUehPatchPoint = FindSignatureCode(pFuncBegin, 0x100, g_pUehSig);     if (g_pUehPatchPoint == NULL)    {        _plugin_logprintf("[%s] Signatrue Not Found!\r", TAG);        bIsEnabledUeh = false;        return false;    }     return true;}
    

    然后響應菜單事件,當點擊EnableUeh時,打補丁,點擊DisableUeh時,恢復補丁。

    void EnableUeh(){    //保存原來的數據    DbgMemRead((duint)g_pUehPatchPoint, UehPatchRawData, strlen((const char*)g_pUehSig) / 2);     //打補丁    if (DbgMemWrite((duint)g_pUehPatchPoint, UehPathCode, sizeof(UehPathCode)))    {        _plugin_logprintf("[%s] Enable UEH Success!\r", TAG);        bIsEnabledUeh = true;    }    else    {        _plugin_logprintf("[%s] Enable UEH Failed!\r", TAG);        bIsEnabledUeh = false;    }} void DisableUeh(){    if (bIsEnabledUeh == true)    {        //Patch        if (DbgMemWrite((duint)g_pUehPatchPoint, UehPatchRawData, strlen((const char*)g_pUehSig) / 2))        {            _plugin_logprintf("[%s] Enable UEH Success!\r", TAG);            bIsEnabledUeh = false;        }        else        {            _plugin_logprintf("[%s] Enable UEH Failed!\r", TAG);        }    }}
    

    一個簡單的插件框架就這樣完成了。

    extern
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    --第一行是XML聲明-->. --這是XML處理指令的例子。后的第一個單詞是處理指令名,在本例中是xml-->. --處理指令一定要頂格寫,前面不能有任何空白-->. XML文檔必須有且只有一個根元素。version特性表明這個文檔符合XML 1.0規范。0x02:實體實體叫ENTITY,實體的作用是避免重復輸入。0x03:處理指令PI處理指令用于XML解析器傳遞信息到應用程序。這些文本將被解析器檢查實體以及標記。
    日前,奇安信入圍國際權威咨詢機構Forrester發布的《The External Threat Intelligence Service Providers Landscape, Q1 2023》。
    CAASM網絡資產攻擊面管理(Cyber asset attack surface management)和EASM外部攻擊面管理(External attack surface management)概念由Gartner首次提出,隨著關鍵信息基礎設施遭受網絡攻擊的安全事件愈發頻繁與IoT、5G、云原生等技術的發展,物聯網行業對CAASM和EASM技術的需求更為迫切,且目前只有少數企業開展了相關技
    近日,國家信息安全漏洞庫(CNNVD)收到關于微信支付SDK XXE(XML External Entity)漏洞(CNNVD-201807-083)情況的報送。成功利用該漏洞的攻擊者可以遠程讀取服務器文件,獲取商戶服務器上的隱私數據,甚至可以支付任意金額購買商品。
    GitLab的安裝和使用
    2022-05-08 07:13:44
    近期目標是整明白用GitLab玩兒CI/CD,本周先從安裝和使用開始, 安裝非常簡單,ubuntu20.04, curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash, sudo apt install gitlab-ce,
    kubesphere的安裝部署
    2021-09-25 16:08:00
    書接上回,本周把kubesphere的安裝部署記錄發出來, 首先要安裝部署storageclass, 需要在每個node上安裝nfs客戶端軟件,sudo apt install nfs-common, 然后下載storageclass的安裝部署yaml模板, wget https://raw.githubusercontent.com/kubernetes-incubator/extern
    Android Java層源碼調試編譯idegen成功會在源碼根目錄生成android.iml 和 android.ipr兩個文件。編輯導入配置sudo deepin-editor android.iml搜索excludeFolder,在下面加入這些配置。過濾不需要的源碼模塊。排除tests 目錄 右鍵mark Directory as Excluded配置 Android源碼項目點擊File -> Project Structure–>SDKs配置項目的JDK、SDK。根據源碼版本選擇對應API級別 這里使用的Android10 對應29。配置 VScode 運行和調試獲取vscodelunch.json 配置注意先選擇C/C++ 源碼 下好斷點 此時按F5 觸發。
    此時,如果你使用的是Linux系統,可以使用mingw-w64-gcc編譯器:CC=x86_64-w64-mingw32-gcc GOOS=windows RSSH_HOMESERVER=192.168.1.1:2343 make client_dll. 當RSSH服務器啟用了Webserver之后,我們也可以使用下列命令進行編譯:./server --webserver :3232. 這種情況適用于無文件注入的場景。WebhookRSSH服務器可以通過命令行終端接口并使用webhook命令發送原始HTTP請求。
    微軟表示,它將讓企業安全運營中心 (SOC) 更廣泛地訪問其每天收集的大量威脅情報。
    對于應用程序來說,零信任支持辦公室內的安全通信,EASM有助于實時反映暴露的資產,并清晰地列出面向外部的應用程序、用戶遠程連接和網絡基礎架構。最后,零信任是針對每個已知來源部署的,而通過EASM則可以不斷梳理出暴露的外部端口和IT系統,以便網絡安全團隊管理。EASM可以讓企業深入、及時地了解外部攻擊面的現狀,是實施完整零信任策略的前提和基礎。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类