win原理Day006.zip
TestDll
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved                     ){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        MessageBox(0, L"注入成功", L"good", 0);    case DLL_THREAD_ATTACH:    case DLL_THREAD_DETACH:    case DLL_PROCESS_DETACH:        break;    }    return TRUE;}
消息钩子
消息钩子DLL
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <stdio.h>HHOOK g_hook;HMODULE g_mod;LRESULT CALLBACK KeyboardProc(    _In_  int code,    _In_  WPARAM wParam,    _In_  LPARAM lParam    ){    // 判断是否wParam与lParam都有键盘消息,是的话则执行打印操作    if (code == HC_ACTION){        // 将256个虚拟键的状态拷贝到指定的缓冲区中,如果成功则继续        BYTE KeyState[256] = { 0 };        if (GetKeyboardState(KeyState)) {            // 得到第16–23位,键盘虚拟码            LONG  KeyInfo = lParam;            UINT  keyCode = (KeyInfo >> 16) & 0x00ff;            WCHAR wKeyCode = 0;            ToAscii((UINT)wParam, keyCode, KeyState, (LPWORD)&wKeyCode, 0);            // 将其打印出来            CHAR szInfo[10] = { 0 };            sprintf_s(szInfo, _countof(szInfo), "Hook_%c", wKeyCode);            OutputDebugStringA(szInfo);            return 0;        }    }//     char str[10] = {};//     str[0] = wParam;//     OutputDebugStringA(str);    return CallNextHookEx(g_hook, code, wParam, lParam);}void OnHook(){    g_hook = SetWindowsHookEx(WH_KEYBOARD,                 KeyboardProc, g_mod, 0);//     if ()//     {//     }}void UnHook(){    if (!g_hook)    {        UnhookWindowsHookEx(g_hook);    }}BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved                     ){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        MessageBoxW(0, 0, 0, 0);        g_mod = hModule;//模块句柄        OnHook();    //case DLL_THREAD_ATTACH:    //case DLL_THREAD_DETACH:    //case DLL_PROCESS_DETACH:        //UnHook();        break;    }    return TRUE;}
内联HOOK
// 内联HOOK.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>void UnHook();void OnHook();char g_OldCode[5];char g_NewCode[5] = { 0xE9 };int WINAPI MyMessageBoxW(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType){    lpText = L"你被HOOK\n";    lpCaption = L"嘿嘿";    //先卸载    UnHook();    //调用MessageBoxW    int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType);    //再次挂上钩子    OnHook();    return nRet;}void OnHook(){    //1.保存原函数被修改的代码    memcpy(g_OldCode, MessageBoxW, 5);    //2.计算偏移量    DWORD dwOffset = (DWORD)MyMessageBoxW - (DWORD)MessageBoxW - 5;    //3.写入指令    memcpy(g_NewCode + 1, &dwOffset, 4);    //修改内存属性(代码段没有可写属性)    DWORD dwOld;    VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);    memcpy(MessageBoxW, g_NewCode, 5);    VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}void UnHook(){    DWORD dwOld;    VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);    memcpy(MessageBoxW, g_OldCode, 5);    VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}int _tmain(int argc, _TCHAR* argv[]){    MessageBoxW(0, 0, 0, 0);    OnHook();    MessageBoxW(0, 0, 0, 0);    return 0;}
内联HOOK_DLL
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>void UnHook();void OnHook();char g_OldCode[5];char g_NewCode[5] = { 0xE9 };int WINAPI MyMessageBoxW(    _In_opt_ HWND hWnd,    _In_opt_ LPCWSTR lpText,    _In_opt_ LPCWSTR lpCaption,    _In_ UINT uType){    lpText = L"你被HOOK\n";    lpCaption = L"嘿嘿";    //先卸载    UnHook();    //调用MessageBoxW    int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType);    //再次挂上钩子    OnHook();    return nRet;}void OnHook(){    //1.保存原函数被修改的代码    memcpy(g_OldCode, MessageBoxW, 5);    //2.计算偏移量    DWORD dwOffset = (DWORD)MyMessageBoxW - (DWORD)MessageBoxW - 5;    //3.写入指令    memcpy(g_NewCode + 1, &dwOffset, 4);    //修改内存属性(代码段没有可写属性)    DWORD dwOld;    VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);    memcpy(MessageBoxW, g_NewCode, 5);    VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}void UnHook(){    DWORD dwOld;    VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);    memcpy(MessageBoxW, g_OldCode, 5);    VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);}BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved                     ){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        OnHook();    //case DLL_THREAD_ATTACH:    //case DLL_THREAD_DETACH:    //case DLL_PROCESS_DETACH:    //    UnHook();        break;    }    return TRUE;}
IAT_HOOK
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include <windows.h>DWORD g_IatAddr;DWORD g_FunOldAddr;typedef int (WINAPI* FP_MessageBoxW)(    _In_opt_ HWND hWnd,    _In_opt_ LPCWSTR lpText,    _In_opt_ LPCWSTR lpCaption,    _In_ UINT uType);int WINAPI MyMessageBoxW(    _In_opt_ HWND hWnd,    _In_opt_ LPCWSTR lpText,    _In_opt_ LPCWSTR lpCaption,    _In_ UINT uType){    lpText = L"你被HOOK\n";    lpCaption = L"嘿嘿";    FP_MessageBoxW FpMsg = (FP_MessageBoxW)g_FunOldAddr;    return FpMsg(hWnd, lpText, lpCaption, uType);}void OnHook(char* pFunName, char* pDllName){    //遍历导入表(INT)    HMODULE hMod = GetModuleHandle(NULL);    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hMod;    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)hMod);    DWORD dwImportRVA = pNt->OptionalHeader.DataDirectory[1].VirtualAddress;    PIMAGE_IMPORT_DESCRIPTOR pImport =         (PIMAGE_IMPORT_DESCRIPTOR)        (dwImportRVA + (DWORD)hMod);    while (pImport->Name)    {        char* pDll = (char*)(pImport->Name + (DWORD)hMod);        if (!_stricmp(pDll,pDllName))        {            //遍历INT            IMAGE_THUNK_DATA* pInt =                (IMAGE_THUNK_DATA*)                (pImport->OriginalFirstThunk + (DWORD)hMod);            IMAGE_THUNK_DATA* pIat =                (IMAGE_THUNK_DATA*)                (pImport->FirstThunk + (DWORD)hMod);            while (pInt->u1.AddressOfData)            {                if (!IMAGE_SNAP_BY_ORDINAL(pInt->u1.AddressOfData))                {                    PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(pInt->u1.AddressOfData + (DWORD)hMod);                    if (!_stricmp(pName->Name,pFunName))                    {                        //函数地址                        g_FunOldAddr = pIat->u1.Function;                        g_IatAddr = (DWORD)pIat;                        //修改地址                        //修改内存属性                        DWORD dwOld;                        VirtualProtect(pIat, 4, PAGE_READWRITE, &dwOld);                        *(DWORD*)pIat = (DWORD)MyMessageBoxW;                        VirtualProtect(pIat, 4, dwOld, &dwOld);                        return;                    }                }                //下一个函数                pInt++;                pIat++;            }        }        //下一个模块        pImport++;    }}void UnHook(){    DWORD dwOld;    VirtualProtect((LPVOID)g_IatAddr, 4, PAGE_READWRITE, &dwOld);    *(DWORD*)g_IatAddr = g_FunOldAddr;    VirtualProtect((LPVOID)g_IatAddr, 4, dwOld, &dwOld);}BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved                     ){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        OnHook("MessageBoxW", "user32.dll");    case DLL_THREAD_ATTACH:    case DLL_THREAD_DETACH:    case DLL_PROCESS_DETACH:        break;    }    return TRUE;}
注入工具代码
// win原理Day006.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <windows.h>#define DLL_MESSAGE "D:\\ProgramVS\\win原理Day006\\Debug\\消息钩子DLL.dll"#define DLL_PATH "D:\\ProgramVS\\win原理Day006\\Debug\\TestDll.dll"#define DLL_INLINE "D:\\ProgramVS\\win原理Day006\\Debug\\内联HOOK_DLL.dll"#define DLL_IAT "D:\\ProgramVS\\win原理Day006\\Debug\\IAT_HOOK.dll"//远程线程注入void Inject(char* pDllPath, DWORD dwPid){    //1.打开进程获取句柄    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);    if (!hProcess)    {        printf("句柄打开失败\n");        return;    }    //2. 再目标进程中申请足够大的内存,存储DLL的全路径    LPVOID lpBuf = VirtualAllocEx(hProcess, NULL,        strlen(pDllPath), MEM_COMMIT, PAGE_READWRITE);    if (!lpBuf)    {        printf("内存申请失败\n");        CloseHandle(hProcess);        return;    }    //3.把DLL全路径写入进去    DWORD dwWrite;    WriteProcessMemory(hProcess, lpBuf,          pDllPath, strlen(pDllPath), &dwWrite);    //4.创建远程线程    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL,        (LPTHREAD_START_ROUTINE)LoadLibraryA, lpBuf, NULL, NULL);    //5.等待线程结束    WaitForSingleObject(hThread, -1);    //6.释放内存    VirtualFreeEx(hProcess, lpBuf, 0, MEM_RELEASE);    CloseHandle(hProcess);}//注入代码void InjectCode(char* pCode, DWORD dwSize,DWORD dwPid){    //1.打开进程获取句柄    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);    if (!hProcess)    {        printf("句柄打开失败\n");        return;    }    //2. 再目标进程中申请足够大的内存,存储DLL的全路径    LPVOID lpBuf = VirtualAllocEx(hProcess, NULL,        strlen(pCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);    if (!lpBuf)    {        printf("内存申请失败\n");        CloseHandle(hProcess);        return;    }    //3.把DLL全路径写入进去    DWORD dwWrite;    WriteProcessMemory(hProcess, lpBuf,        pCode, dwSize, &dwWrite);    //4.创建远程线程    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL,        (LPTHREAD_START_ROUTINE)lpBuf, NULL, NULL, NULL);    //5.等待线程结束    WaitForSingleObject(hThread, -1);    //6.释放内存    VirtualFreeEx(hProcess, lpBuf, 0, MEM_RELEASE);    CloseHandle(hProcess);}int _tmain(int argc, _TCHAR* argv[]){    //HMODULE hMod = LoadLibraryA(DLL_MESSAGE);    int nPid;    printf("输入PID:");    scanf_s("%d", &nPid);    Inject(DLL_IAT, nPid);    //DWORD dwAddr;//     __asm//     {//         push 0;//         push 0;//         push 0;//         push 0;//         mov eax, 0x99999999;//         call eax;//     }// //      char pCode[] = "\x6A\x00\x6A\x00\x6A\x00\x6A\x00\xB8\x99\x99\x99\x99\xFF\xD0";//     DWORD dwAddr;//     scanf_s("%x", &dwAddr);//     *(int*)(pCode + 9) = dwAddr;//     DWORD dwPid;//     scanf_s("%d", &dwPid);//     InjectCode(pCode, sizeof(pCode),dwPid);//测试//     printf("MessageBoxW:0x%08X\n", (DWORD)MessageBoxW);    system("pause");    return 0;}