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中创建的线程执行成功!



原创粉丝点击