CreateRemoteThread简单应用之二
来源:互联网 发布:网络侦探 进化表 编辑:程序博客网 时间:2024/05/20 00:52
宿主进程 exe.exe
#include <stdio.h>#include <time.h> #include <windows.h>int foo (void){ printf("foo\n"); // 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:%0p\n", 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("%p\n", 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:%0p\n", MyFun); // printf("szMsg:%s\n", 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, "Hello\n"); printf("remoteData.dwMessageBox %p\n", 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简单应用
- CreateRemoteThread简单应用
- CreateRemoteThread简单应用
- CreateRemoteThread简单应用
- CreateRemoteThread简单应用
- 简单的CreateRemoteThread例子
- iText简单应用之二
- quartz之简单应用二
- vc++教程之CreateRemoteThread
- DLL注入之CreateRemoteThread
- listview简单应用之BaseAdapter(二)
- CreateRemoteThread
- CreateRemoteThread
- CreateRemoteThread
- CreateRemoteThread
- 进程注入方法之 CreateRemoteThread
- 简单的CreateRemoteThread例程-初学者必看
- Java Serializable(序列化)的理解和总结
- Cocos2dx 之 PhysicsHandler 简单实现
- Android ApiDemo 笔记(一)Content与Graphics
- Apache Pig的一些基础概念及用法总结(1)
- ThinkPHP学习之多语言支持
- CreateRemoteThread简单应用之二
- 多线程 - 基本知识
- 向pig脚本中传入参数
- 活跃性问题
- JAVAWeb_利用Session防止表单重复提交:10-客户端防表单重复提交和服务器端session防表单重复提交
- XAF笔记01
- a,b比较和交换问题
- Android ApiDemo 笔记(二)Graphics和View
- 嵌入式Linux+ARM开发环境搭建