包含要注入的Demo与dll,与注入的程序。
要注入的Demo.exe程序代码
#include <iostream>
#include <Windows.h>
using namespace std;
int showAge(int age) {
int a = 0;
cout << a << age << endl;
return age;
}
int main() {
SetConsoleTitle("Demo");
cout << "Hello, World!" << endl;
showAge(18);
cin.get();
return 0;
}
注入程序的Dll
#include <Windows.h>
#include <iostream>
#include "tchar.h"
#include "tlhelp32.h"
BOOL getProcessAddr(DWORD dwPID, DWORD &baseAddr);
DWORD retAddr;
char oldCode[5] = {0};
DWORD hookAddr;
/**
* hook的一个exe中的方法
* void showAge(int age){
* std::cout << age << endl;
* }
*/
void hookPrint(int age){
std::cout << "hook age is : " << (int)age << std::endl;
}
void _declspec(naked) print() {
__asm {
push ebp
mov ebp,esp
mov eax,dword ptr ss:[ebp+8]
push eax
call hookPrint
add esp,0x4
mov esp,ebp
pop ebp
jmp retAddr
}
}
void hook(DWORD offset) {
DWORD baseAddr;
DWORD pid = GetCurrentProcessId();
getProcessAddr(pid, baseAddr);
hookAddr = baseAddr + offset;
/**
* 不需要权限
*/
memcpy((LPVOID) oldCode, (LPVOID) hookAddr, 5);
retAddr = hookAddr + 5;
char jmpCode[5] = {0};
jmpCode[0] = 0xE9;//或者0xE8
*(DWORD *) &jmpCode[1] = (DWORD) print - hookAddr - 5;
/**
* 不能替换成memcpy使用
*/
if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) hookAddr, (LPVOID) jmpCode, 5, nullptr) == 0) {
std::cout << "hook fail" << std::endl;
} else {
std::cout << "hook success" << std::endl;
}
}
void unhook() {
std::cout << "unhook" << std::endl;
if (WriteProcessMemory(GetCurrentProcess(), (LPVOID) hookAddr, (LPVOID) oldCode, 5, nullptr) == 0) {
std::cout << "unhook fail" << std::endl;
} else {
std::cout << "unhook success" << std::endl;
}
}
BOOL getProcessAddr(DWORD dwPID, DWORD &baseAddr) {
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
me32.dwSize = sizeof(MODULEENTRY32);
if (!Module32First(hModuleSnap, &me32)) {
CloseHandle(hModuleSnap);
return FALSE;
}
baseAddr = (DWORD) me32.modBaseAddr;
CloseHandle(hModuleSnap);
return TRUE;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
hook(0x1717);//0x1717是使用x32dbg查到call的位置偏移
break;
case DLL_PROCESS_DETACH:
unhook();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
注入Dll的程序
#include <iostream>
#include <Windows.h>
#include "tchar.h"
#include "WindowUtil.h"
DWORD findProcessPid(LPCTSTR name) {
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (!hProcess) {
return FALSE;
}
PROCESSENTRY32 info;
info.dwSize = sizeof(info);
if (!Process32First(hProcess, &info)) {
return FALSE;
}
while (true) {
const LPTSTR fName = info.szExeFile;
if (_tcscmp(fName, name) == 0) {
CloseHandle(hProcess);
return info.th32ProcessID;
}
if (!Process32Next(hProcess, &info)) {
CloseHandle(hProcess);
return FALSE;
}
}
}
BOOL getProcessAddr(DWORD pid, LPCTSTR moduleName, DWORD &baseAddr) {
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
me32.dwSize = sizeof(MODULEENTRY32);
if (!Module32First(hModuleSnap, &me32)) {
CloseHandle(hModuleSnap);
return FALSE;
}
do {
if (_tcscmp(me32.szModule, moduleName) == 0 || _tcscmp(me32.szExePath, moduleName) == 0) {
break;
}
} while (Module32Next(hModuleSnap, &me32));
baseAddr = (DWORD) me32.modBaseAddr;
CloseHandle(hModuleSnap);
return TRUE;
}
void inject(LPCTSTR name, LPCTSTR dllPath) {
DWORD pid = findProcessPid(name);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
unsigned int size = strlen(dllPath);
LPVOID dllPathAddr = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(handle, dllPathAddr, dllPath, size, nullptr);
HANDLE remoteHandle = CreateRemoteThread(handle, nullptr, NULL, (PTHREAD_START_ROUTINE) LoadLibraryA, dllPathAddr,
NULL, nullptr);
WaitForSingleObject(remoteHandle, INFINITE);
VirtualFreeEx(handle, dllPathAddr, size, MEM_DECOMMIT);
CloseHandle(remoteHandle);
CloseHandle(handle);
}
void unject(LPCTSTR name, LPCTSTR dllPath) {
DWORD pid = findProcessPid(name);
DWORD dllPathAddr;
getProcessAddr(pid, dllPath, dllPathAddr);
std::cout << std::hex << dllPathAddr << std::endl;
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
HANDLE remoteHandle = CreateRemoteThread(handle, nullptr, NULL, (PTHREAD_START_ROUTINE) FreeLibrary,
(LPVOID) dllPathAddr,
NULL, nullptr);
WaitForSingleObject(remoteHandle, INFINITE);
CloseHandle(remoteHandle);
CloseHandle(handle);
}
int main() {
LPCTSTR name = _T("Demo.exe");
LPCTSTR dllPath = _T("C:\\Users\\Administrator\\CLionProjects\\Dll2\\cmake-build-release\\Dll2.dll");
inject(name, dllPath);
std::cin.get();//输入任意字符回车即可卸载Dll
unject(name, dllPath);
return 0;
}