zoukankan      html  css  js  c++  java
  • CreateRemoteThread 远程注入

    在release中可以成功,在debug中被注入的程序停止工作

    #pragma once
    #include "stdafx.h"
    #include <windows.h>
    #include <TlHelp32.h>
    #include <iostream>

    //线程参数结构体定义
    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)
    {
         RemoteParam* pRP = (RemoteParam*)lParam;

         PFN_MESSAGEBOX pfnMessageBox;
         pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
         pfnMessageBox(NULL, pRP->szMsg, pRP->szMsg, 0);

         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();

         //等待输入进程名称,注意大小写匹配
         std::cout << "Please input the name of target process !" << std::endl;
         char szExeName[MAX_PATH] = { 0 };
         std::cin >> szExeName;

         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 hUser32 = LoadLibrary("User32.dll");
         remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
         strcat(remoteData.szMsg, "Hello");

         //为线程参数在宿主进程中开辟存储区域
         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);

         return 0;
    }

  • 相关阅读:
    WPF 跨应用程序域的 UI(Cross AppDomain UI)
    Visual->UIElement->FrameworkElement,带来更多功能的同时也带来了更多的限制
    使用不安全代码将 Bitmap 位图转为 WPF 的 ImageSource 以获得高性能和持续小的内存占用
    从 “x is null 和 x == null” 的区别看 C# 7 模式匹配中常量和 null 的匹配
    WPF 和 UWP 中,不用设置 From 或 To,Storyboard 即拥有更灵活的动画控制
    WPF 同一窗口内的多线程 UI(VisualTarget)
    如何实现一个可以用 await 异步等待的 Awaiter
    使用 Task.Wait()?立刻死锁(deadlock)
    使用 ExceptionDispatchInfo 捕捉并重新抛出异常
    CaptureMouse/CaptureStylus 可能会失败
  • 原文地址:https://www.cnblogs.com/duyy/p/3711743.html
Copyright © 2011-2022 走看看