概述
宿主进程 exe.exe
#include <stdio.h>
#include <time.h>
#include <windows.h>
int foo (void)
{
printf("foon");
// MessageBox(NULL, "foo", "Notice", MB_OK);
#if 0
HINSTANCE hUser32 = LoadLibrary("User32.dll");
typedef int (*DllFun)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
DllFun dwMessageBox = (DllFun)GetProcAddress(hUser32, "MessageBoxA");
#endif
// printf("dwMessageBox GetProcAddress:%0pn", dwMessageBox);
// dwMessageBox(NULL, "foo", "Notice", MB_OK);
HINSTANCE hdll = LoadLibrary("C:\Downloads\hookexe\hookdll\Debug\hookdll.dll");
// fnHookfoo对应的函数类型 HOOKDLL_API int fnHookdll(void)
typedef int (*DllFun)(void);
DllFun foo = (DllFun)GetProcAddress(hdll, "fnHookdll");
///printf("%pn", foo);
foo();
return 0;
}
int main(int argc, char* argv[])
{
while (1)
{
Sleep(1000);
foo ();
}
return 0;
}
远程注入进程hookexe2.exe
// hookexe2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#pragma once
#include <windows.h>
#include <TlHelp32.h>
#include <stdio.h>
//线程参数结构体定义
typedef struct _RemoteParam {
char szMsg[12]; //MessageBox函数中显示的字符提示
DWORD dwMessageBox;//MessageBox函数的入口地址
} RemoteParam, * PRemoteParam;
//定义MessageBox类型的函数指针
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
//线程函数定义
DWORD __stdcall threadProc(LPVOID lParam)
{
//只要使用api必须拦截 !!!!!!!!
RemoteParam* pRP = (RemoteParam*)lParam;
typedef int (*DllFun)(void); // 函数指针,注意要和原函数的原型一制
DllFun MyFun = (DllFun)pRP->dwMessageBox;
//就是这句有错!!!!!!!!!
// printf("threadProc GetProcAddress:%0pn", MyFun);
// printf("szMsg:%sn", pRP->szMsg);
(DllFun)MyFun();
return 0;
}
//提升进程访问权限
bool enableDebugPriv()
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
return false;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
CloseHandle(hToken);
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
CloseHandle(hToken);
return false;
}
return true;
}
//根据进程名称得到进程ID,如果有多个运行实例的话,返回第一个枚举到的进程的ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe)) {
MessageBox(NULL,
"The frist entry of the process list has not been copyied to the buffer",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
while (Process32Next(hSnapshot, &pe)) {
if (!strcmp(lpszProcessName, pe.szExeFile)) {
return pe.th32ProcessID;
}
}
return 0;
}
int main(int argc, char* argv[])
{
//定义线程体的大小
const DWORD dwThreadSize = 4096;
DWORD dwWriteBytes;
//提升进程访问权限
enableDebugPriv();
//等待输入进程名称,注意大小写匹配
char szExeName[MAX_PATH] = { 0 };
//cout<< "Please input the name of target process !" <<endl;
//
// cin >> szExeName;
// cout<<szExeName<<endl;
//strcpy(szExeName,"notepad.exe");
scanf("%s",szExeName);
//cout<<szExeName<<endl;
DWORD dwProcessId = processNameToId(szExeName);
if (dwProcessId == 0) {
MessageBox(NULL, "The target process have not been found !",
"Notice", MB_ICONINFORMATION | MB_OK);
return -1;
}
//根据进程ID得到进程句柄
HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (!hTargetProcess) {
MessageBox(NULL, "Open target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//在宿主进程中为线程体开辟一块存储区域
//在这里需要注意MEM_COMMIT | MEM_RESERVE内存非配类型以及PAGE_EXECUTE_READWRITE内存保护类型
//其具体含义请参考MSDN中关于VirtualAllocEx函数的说明。
void* pRemoteThread = VirtualAllocEx(hTargetProcess, 0,
dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!pRemoteThread) {
MessageBox(NULL, "Alloc memory in target process failed !",
"notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//将线程体拷贝到宿主进程中
if (!WriteProcessMemory(hTargetProcess,
pRemoteThread, &threadProc, dwThreadSize, 0)) {
MessageBox(NULL, "Write data to target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//定义线程参数结构体变量
RemoteParam remoteData;
ZeroMemory(&remoteData, sizeof(RemoteParam));
//填充结构体变量中的成员
HINSTANCE hdll = LoadLibrary("C:\Downloads\hookexe\hookdll\Debug\hookdll.dll");
// fnHookfoo对应的函数类型 HOOKDLL_API int fnHookdll(void)
remoteData.dwMessageBox = (DWORD)GetProcAddress(hdll, "fnHookdll");
strcat(remoteData.szMsg, "Hellon");
printf("remoteData.dwMessageBox %pn", remoteData.dwMessageBox);
//为线程参数在宿主进程中开辟存储区域
RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(
hTargetProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
if (!pRemoteParam) {
MessageBox(NULL, "Alloc memory failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//将线程参数拷贝到宿主进程地址空间中
if (!WriteProcessMemory(hTargetProcess ,
pRemoteParam, &remoteData, sizeof(remoteData), 0)) {
MessageBox(NULL, "Write data to target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//在宿主进程中创建线程
HANDLE hRemoteThread = CreateRemoteThread(
hTargetProcess, NULL, 0, (DWORD (__stdcall *)(void *))pRemoteThread,
pRemoteParam, 0, &dwWriteBytes);
if (!hRemoteThread) {
MessageBox(NULL, "Create remote thread failed !", "Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
CloseHandle(hRemoteThread);
FreeLibrary(hdll);
return 0;
}
对应的DLL文件源码C:\Downloads\hookexe\hookdll\Debug\hookdll.dll
// This is an example of an exported function.
HOOKDLL_API int fnHookdll(void)
{
char msg[] = "fnHookdll"; // 常量字符串不可复制到其它进程,因此使用局部变量数组
puts (msg);
return 42;
}
这里一定不能直接使用 puts (“fnHookdll”); 否则不同进程中常量字符串对应的地址指针值不一致,导致hook进程复制到宿主进程后指针失效
试验步骤
1) 运行宿主进程exe.exe
2) 运行hook进程hookexe2.exe
效果:
hook进程hookexe2.exe 中显示连续的fnHookdll, 意味着hookexe2.exe在宿主进程exe.exe中创建的线程执行成功!
最后
以上就是忧虑鱼为你收集整理的CreateRemoteThread简单应用之二的全部内容,希望文章能够帮你解决CreateRemoteThread简单应用之二所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复