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;
}