逆向 | inlinehook 简单实践
逆向 | inlinehook 简单实践
好久之前就学过了,结果代码找不到了,今儿留个档。
总结一下就是:
- 整个被注入的dll,在里头进行hook的操作
- 整个exe来注入上面那个dll
代码如下:
测试的被注入程序(test.exe):
#include <stdio.h>
#include <windows.h>
int main(){
while (1){
getchar();
MessageBoxA(0,"啊哈",0,0);
}
return 0;
}
被注入的dll(关键部分,inject_dll.dll):
我在调试的时候不知道咋地一开始memcpy过不了,然后过了会儿它自己就好了。。。
// inject_dll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <stdio.h>
#include <gl/glut.h>
DWORD g_dwOldAddr; // 原始函数地址
DWORD g_dwNewAddr; // Hook函数地址
DWORD g_dwHookFlag; // 标志有没有被hook
#define PATCH_LENGTH 5
DWORD dwRetAddress;
BOOL setInlineHook(DWORD dwOldAddr, DWORD dwNewAddr){
BOOL bRet = FALSE;
dwRetAddress = dwOldAddr + PATCH_LENGTH; // hook结束以后的返回地址
BYTE byJmpCode[PATCH_LENGTH] = {0xe9};
DWORD dwOldProtect;
// 之前的字节码
static BYTE byOriginalCode[PATCH_LENGTH] = {0};
static BOOL bHookFlag = FALSE;
// 测试用
char buf[1024] = {0};
// 1. 初始化byJmpCode
memset(&byJmpCode[1], 0x90, PATCH_LENGTH-1);
// 2. 存储跳转地址
*(DWORD*)&byJmpCode[1] = (DWORD)dwNewAddr - (DWORD)dwOldAddr - 5;
// 3. 备份被覆盖的code
memcpy(byOriginalCode, (LPVOID)dwOldAddr, PATCH_LENGTH);
// 4. 开始patch
if (!bHookFlag)
{
// hook
VirtualProtect((LPVOID)dwOldAddr,
PATCH_LENGTH, PAGE_EXECUTE_READWRITE, &dwOldProtect); // 这个是成功执行的
// 好了它又没问题了,不知道咋回事之前会崩溃
memcpy((LPVOID)dwOldAddr, byJmpCode, PATCH_LENGTH); // 这里拷贝的时候有问题,会出现不可写的问题
VirtualProtect((LPVOID)dwOldAddr, PATCH_LENGTH, dwOldProtect, 0);
bHookFlag = TRUE;
bRet = TRUE;
}else{
// 取消hook
VirtualProtect((LPVOID)dwOldAddr,
PATCH_LENGTH, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy((LPVOID)dwOldAddr, byOriginalCode, PATCH_LENGTH);
VirtualProtect((LPVOID)dwOldAddr, PATCH_LENGTH, dwOldProtect, 0);
bHookFlag = FALSE;
bRet = TRUE;
}
return bRet;
}
char szNewText[] = "Hook!";
void __declspec(naked) MyglBegin(GLenum mode){
__asm{
// 1. 保存寄存器
pushad;
pushfd;
// 2. 修改数据
lea eax, dword ptr ds:[szNewText];
mov dword ptr ss:[esp+0x24+8], eax;
// 3. 恢复寄存器
popfd;
popad;
// 4. 执行覆盖的代码
mov edi, edi;
push ebp;
mov ebp, esp;
// 5. 返回执行
jmp dwRetAddress;
}
}
/*
void WINAPI MyglBegin(GLenum mode)
{
MessageBox(0,"获取到调用",0,0);
if(mode==GL_TRIANGLE_STRIP||mode==GL_TRIANGLE_FAN)
{
glDisable(GL_DEPTH_TEST);
MessageBox(0,"获取到调用",0,0);
}
glBegin(mode);
}
*/
// 线程函数
DWORD WINAPI ThreadProc(LPVOID lpParameter){
// 保存原始函数地址
//DWORD pOldFuncAddr = (DWORD)GetProcAddress(LoadLibrary("opengl32.dll"), "glBegin");
DWORD pOldFuncAddr = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA");
char buf[1024] = {0};
sprintf(buf, "获取到函数地址:%p ", pOldFuncAddr);
MessageBox(0, buf, 0, 0);
// 安装或者卸载HOOK
BOOL ret;
if (!g_dwHookFlag){
ret = setInlineHook(pOldFuncAddr, (DWORD)MyglBegin);
if (ret){
MessageBox(0, "安装hook成功!", 0, 0);
}else{
MessageBox(0, "安装hook失败!", 0, 0);
}
}
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch ( ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)ThreadProc,
NULL, 0,NULL);//创建新线程执行代码
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
注入用的程序,常规操作远程线程注入:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
DWORD GetPid(char* szName){
HANDLE hprocessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hprocessSnap = CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0);//捕捉所有进程的快照
if (hprocessSnap == INVALID_HANDLE_VALUE){
//快照失败
return 0;
}
//初始化pe32结构体
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hprocessSnap, &pe32)){
do{
if (!strcmp(szName, pe32.szExeFile)){
printf("Process Found, PID: %d \n", (int)pe32.th32ProcessID);
return (int)pe32.th32ProcessID;
}
//遍历查找进程名
}while (Process32Next(hprocessSnap, &pe32));
}else{
CloseHandle(hprocessSnap);
}
return 0;
}
//远程线程注入
BOOL load_dll(DWORD dwProcessID, char* szDllPathName)
//进程PID和dll完整的路径
{
BOOL bRet;
HANDLE hProcess;
HANDLE hThread;
DWORD dwLength;
DWORD dwLoadAddr;
LPVOID lpAllocAddr;
DWORD dwThreadID;
HMODULE hModule;
//获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID);
printf("%x \n", hProcess);
if (hProcess == NULL)
{
OutputDebugString("fail to open process \n");
return FALSE;
}
//把DLL文件路径字符串存入被注入进程的内存空间
//计算dll路径名字长度,并且加上结尾0的空间
dwLength = strlen(szDllPathName)+1;
//远程申请内存空间
lpAllocAddr = (LPVOID)VirtualAllocEx(hProcess,NULL,dwLength,MEM_COMMIT,PAGE_READWRITE);
if (lpAllocAddr == NULL){
OutputDebugString("VirtualAllocEx error \n");
CloseHandle(hProcess);
return FALSE;
}
//拷贝dll路径名字到目标进程的内存
bRet = WriteProcessMemory(hProcess, lpAllocAddr,szDllPathName,dwLength,NULL);
if (bRet == NULL){
OutputDebugString("bRet error \n");
CloseHandle(hProcess);
return FALSE;
}
//获取kernel32.dll的地址
hModule = GetModuleHandle("Kernel32.dll");
if (!hModule)
{
OutputDebugString("GetModuleHandle error \n");
CloseHandle(hProcess);
return FALSE;
}
//获取LoadLibraryA函数地址
dwLoadAddr = (DWORD)GetProcAddress(hModule, "LoadLibraryA");
if (!dwLoadAddr )
{
OutputDebugString("GetProcAddress error \n");
CloseHandle(hProcess);
CloseHandle(hModule);
return FALSE;
}
//创建远程线程,加载dll
hThread = CreateRemoteThread(hProcess, NULL, 0, (unsigned long (__stdcall *)(void *))dwLoadAddr, lpAllocAddr, 0, NULL);
printf("%x \n", hThread);
if (hThread == NULL)
{
OutputDebugString("fail to open RomoteThread \n");
CloseHandle(hProcess);
return FALSE;
}
CloseHandle(hProcess);
return TRUE;
}
void main(){
load_dll(GetPid("test.exe"),
"C:\\Users\\thinkpad\\Desktop\\hookopengl\\inject_dll\\inject_dll\\Debug\\inject_dll.dll");
}
本文来自博客园,作者:Mz1,转载请注明原文链接:https://www.cnblogs.com/Mz1-rc/p/16586411.html
如果有问题可以在下方评论或者email:mzi_mzi@163.com