DuiLib逆向分析の按鈕事件定位


DuiLib逆向分析の按鈕事件定位

0x00 前言

記錄自己學習Duilib逆向分析的筆記。

DuiLib介紹

DuiLib官方介紹,Duilib是一個Windows下免費開源的DirectUI界面庫,由於簡約易擴展的設計以及穩定高效的實現被各大互聯網公司普遍接受,廣泛應用於包括IM、視頻客戶端、股票行情軟件、導航軟件、手機輔助軟件、安全軟件等多個行業的眾多pc客戶端軟件。Duilib還在不斷的發展中,在文檔、例子、動畫、渲染引擎等多個方面將持續改進。

DirectUI介紹,直接在父窗口上繪圖,構建易於擴展的界面。(DirectUI意為直接在父窗口上繪圖(Paint on parent dc directly)。即子窗口不以窗口句柄 的形式創建(windowless),只是邏輯上的窗口,繪制在父窗口之上。)

Duilib是一個自繪控件界面庫,可以很方便的構建高效,絢麗的,非常易於擴展的界面。

國外如微軟,國內如騰訊百度等公司的客戶端產品多采用這種方式來組織界面,從而很好的將界面和邏輯分離,同時易於實現各種超炫的界面效果如換色,換膚,透明等。

DuiLib安裝

安裝DuiLib推薦用C++庫管理器vcpkg來安裝,這東西我感覺類似Python的pip。可以很方便的安裝管理第三方庫

vcpkg官方安裝教程,安裝vcpkg非常簡單,就如下幾條命令就搞定:

git clone https://github.com/microsoft/vcpkg
#將vcpkg目錄添加到環境變量
RefreshEnv.cmd          #更新環境變量
bootstarp-vcpkg.bat     #vcpkg初始化相關文件
vcpkg integrate install #配置到VS相關環境中
vcpkg search  [庫名]    #搜索相關第三方庫
vcpkg install [庫名]    #安裝第三方庫

安裝DuiLib庫:

vcpkg install DuiLib #安裝DuiLib庫

DuiLib Hello,World!

裝好了庫后,我們來寫第一個DuiLib程序,經典的Hello,World!

//DuiLib庫頭文件
#include <DuiLib/UILib.h>
//命名空間
using namespace DuiLib;

//重寫Windows窗口類,繼承自->CWindow -> INotifyUI
class CDuilibWnd : public CWindowWnd,public INotifyUI
{
    
    public:
    //虛函數
    virtual LPCTSTR GetWindowClassName() const {return _T("DuiWnd");}//窗口類
    //重寫響應消息
    virtual void Notify(TNotifyUI& msg)
    {
        if(msg.sType == _T("click"))
        {
            if(msg.pSender->GetName() == _T("Hello_btn"))
            {
                MessageBoxA(NULL,"Hello,World!","Dui逆向の按鈕事件定位",MB_OK);
            }
        }
    }
    //重寫消息處理
    virtual LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam)//回調函數
    {
        LRESULT lRes = 0;
        if(uMsg == WM_CREATE)
        {
            m_PaintManager.Init(m_hWnd);
            //利用XML布局生成界面
            CDialogBuilder builder;
            CControlUI* pRoot = builder.Create(_T("duilib.xml"),0,NULL,&m_PaintManager);
            ASSERT(pRoot && "Failed to parse XML");
            m_PaintManager.AttachDialog(pRoot);
            //用於處理消息
            m_PaintManager.AddNotifier(this);
            return lRes;
        }
        if(m_PaintManager.MessageHandler(uMsg,wParam,lParam,lRes)) return lRes;
        return __super::HandleMessage(uMsg,wParam,lParam);
    }
    
    protected:
    CPaintManagerUI m_PaintManager;
}

int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
    CPaintManagerUI::SetInstance(hInstance);//綁定窗口句柄
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());//加載XML
    //創建並顯示窗口
    CDuilibWnd duilibWnd;
    duilibWnd.Create(NULL,_T("Dui逆向の按鈕事件定位"),UI_WNDSTYLE_FRAME,WS_EX_WINDOWEDGE);
    duilibWnd.ShowModal();//監聽消息
    return 0;
}

duilib.xml 界面布局文件

<?xml version="1.0" encoding="UTF-8"?>
<Window size="320,100">
    <HorizontalLayout bkcolor="#FFFFFFFF">
		<Button name="Hello_btn" text="按鈕"  height="40" width="80"  bordersize="1,1,1,1" bordercolor="#0079DE" padding="111,10,0,0"/>
    </HorizontalLayout>
</Window>

編譯生成后的界面如下,並且點擊按鈕后觸發了事件:

image-20211210141430317

Duilib逆向分析之定位按鈕事件

碎碎念

所以我覺得做逆向開發,不能盲目的一開始就去看OD,去IDA F5反編譯,而是應該擅長利用搜索引擎去學習了解相關:框架、庫、模型、開發等知識,有了這些知識后逆向就如魚得水。

第一步:獲取xml布局文件

首先切入點是從duilib.xml文件開始,所以我們在逆向Duilib相關程序時候應該先拿到他的布局文件。

而在我們的demo中duilib.xml是在本地的,而在源碼中可以看到builder.Create來加載使用duilib.xml

image-20211210142047876

如果xml在本地的話則很簡單直接找到路徑即可,但是常規逆向分析中基本都是在內存中的,那這種要如何獲取到他的xml布局文件呢?

思路還是一樣,先定位到這個builder.Create函數,然后跟進去一步步調試,看堆棧信息,看經過哪一句匯編代碼或Call后出現xml內容。

image-20211210150307646

第二步:按鈕事件分金點穴

當我們拿到布局后,找到對應按鈕的名稱,例子中的按鈕對應的名稱是Hello_btn,然后去調試軟件中搜索相關字符串Hello_btn

image-20211210150422786

並且下上斷點。

image-20211210150543271

當我們點擊按鈕后,成功的斷到如下位置:

image-20211210150711936

111

斷點斷到后,查看上下文中的匯編就已經很明顯了,在je下面 (je那一句是判斷當前btn按鈕事件是否是Hello_btn的按鈕事件),對應的源碼就是:

if(msg.pSender->GetName() == _T("Hello_btn"))
{
    MessageBoxA(NULL,"Hello,World!","Dui逆向の按鈕事件定位",MB_OK);
}

感謝觀看我的筆記,如有問題請指出謝謝。

逆向、PWN學習交流

Pwn菜雞學習小分隊群聊二維碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM