【HookAPI】

#include <IOSTREAM>
#include <WINDOWS.H>

using namespace std;



void main()
{

//與靜態庫相關聯
    HMODULE hDll = LoadLibrary("HookAPIDll.dll");

    printf("被鉤掉的那個API,MessageBox,如今變成了打開calc.exe\n");
    printf("你如今看的是一個計算器,對不對,哈哈!\n");


 //第一個MessageBox
    MessageBox(NULL,"這是第一個MessageBox","Test",0);

    printf("觀察發現,會出現第二個MessageBox\n");

//若是在靜態庫DLL中 沒有    調用HookOff();的話,全部的messagebox都會被改掉,若是調用了的話,
//    那麼下面這個messagebox將能正常使用



//第二個MessageBox
    MessageBox(NULL,"這是第二個MessageBox,若是你只看到這一個MessageBox的話,說明第一個MessageBox已經被鉤掉了。,你能看到第二個MessageBox,那是由於這裏用了OffHook,將地址又弄回去了,其實這裏我也搞不太清楚,不過你能夠去試試,若是不調用OffHook()函數的話,全部的MessageBox都出不來的,病毒思想,哈哈哈!","Test",0);
}


void Add()
{

}


 

// HookAPIDll.cpp : Defines the entry point for the DLL application.
//

#include "stdAfx.h"


//咱們在這裏定一個全局的函數指針能夠用來保存原來的函數的地址

PROC g_Func = NULL;
BYTE g_NewFunc[5]; 
BYTE g_OldFunc[5];

//定義一個全局的句柄
HANDLE g_hProcess = NULL;


void WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
void WINAPI MyMainProc();

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        {
            
            MyMainProc();
            
            break;
        }


    case DLL_PROCESS_DETACH:
        {
            break;
        }
    }

    return TRUE;
}


void HookAPI(LPCTSTR ModuleName,LPCTSTR ApiName,FARPROC lpNewFunc)
{

    //後面調用是這樣的
    //    HookAPI("user32.dll","MessageBoxA",(FARPROC)MyMessageBox);
    // 這裏傳進來的是咱們本身寫的MyMessageBox,
    // 整個函數的功能就是(還要結合後面的兩個函數)
    // 在user32.dll模塊中,去找到MessageBox這個函數,
    // 而後計算出咱們本身寫的那個函數MyMessageBox 的偏移,
    // 最後將它蓋掉原來的函數,也就是執行MessageBox 的時候實際上執行的是咱們本身的MyMessageBox函數


    //FARPROC 是一個4字節指針,指向一個函數的內存地址


    //這裏須要那個庫 還有就是API函數的名字

    g_NewFunc[0] = 0xe9;   //這是咱們構建的字符數組中的第一個字節

    //咱們經過兩個函數能夠獲得原來的那個API函數的地址

    g_Func=GetProcAddress(GetModuleHandle(ModuleName),ApiName);
    //給我一個模塊,給我一個函數,GetProcAddress的返回值就是這個函數的偏移地址
    //這步驟執行以後,g_Func中保存的就是原先函數的地址,,也就是還沒被鉤掉的MessageBox函數的地址

    //e8 10ab
    memcpy(g_OldFunc,(void*)g_Func,5);



    g_hProcess = GetCurrentProcess();    //咱們要這個值是爲了可以往進程的內存中寫值

    //GetCurrentProcess 得到當前進程,獲開進程以後(得到進程的地址空間),須要把地址寫進去,
    //g_hProcess是一個全局的句柄

    //覆蓋函數的jmp後的4個字節指令

    DWORD* pStart = NULL;

    pStart = (DWORD*)&g_NewFunc[1] ; //pStart指向的是0xe9,也就是jmp後面的那個地址

    *pStart = (DWORD)lpNewFunc - (DWORD)g_Func - 5;   //計算咱們實際要運行的函數和原來函數的偏移
    
    //這裏lpNewFunc是一個 FARPROC 類型的指針,指向函數的內存地址,


}


void SetHook()
{
    DWORD dwFlag;
    WriteProcessMemory(g_hProcess,(void*)g_Func,(void*)g_NewFunc,5,&dwFlag);
    //把g_NewFuc中保存的5個字節的內容,寫到g_Func中去,
    //這裏的意思,就是把咱們本身寫的MyMessaBox函數,去替換原來的MessageBox函數
    //由於經過HookAPI函數,g_Func存放的是原來函數的地址(0xe8 .....),
    //                       g_NewFunc存放的是如今函數的偏移地址以及一個jmp(0xe9 .....)
    //因此,進程中的內存地址空間的這5個字節就被改寫了。
    //因此原本要執行系統的MessaBox,就變爲執行咱們本身寫的MessagBox了。
}


//功能和SetHook相反
void HookOff()
{
    DWORD dwFlag;
    WriteProcessMemory(g_hProcess,(void*)g_Func,(void*)g_OldFunc,5,&dwFlag);
}



void WINAPI MyMainProc()
{
    HookAPI("user32.dll","MessageBoxA",(FARPROC)MyMessageBox);

    SetHook();

}



void WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
    
    
    HookOff();
//    MessageBoxA(hWnd,"Hooking MessageBox","Test",MB_OK); 

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    CreateProcess("C:\\Windows\\System32\\calc.exe", // No module name (use command line). 
        NULL, 
        NULL,          
        NULL,           
        FALSE,          
        0,              
        NULL,          
        NULL,            
        &si,           
        &pi );

//    SetHook();    //這裏能夠繼續設置而後繼續抓API函數
}

相關文章
相關標籤/搜索