在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\0");

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

CreateRemoteThread 远程注入的更多相关文章

  1. CreateRemoteThread远程线程注入Dll与Hook

    CreateRemoteThread虽然很容易被检测到,但是在有些场合还是挺有用的.每次想用的时候总想着去找以前的代码,现在在这里记录一下. CreateRemoteThread远程注入 DWORD ...

  2. HOOK -- DLL的远程注入技术详解(1)

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  3. 将DLL挂接到远程进程之中(远程注入)

    线程的远程注入 要实现线程的远程注入必须使用Windows提供的CreateRemoteThread函数来创建一个远程线程该函数的原型如下:HANDLE CreateRemoteThread(    ...

  4. [转]远程注入DLL : 取得句柄的令牌 OpenProcessToken()

    http://hi.baidu.com/43755979/blog/item/3ac19711ea01bdc4a6ef3f6a.html 要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关 ...

  5. DLL的远程注入技术

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  6. DLL远程注入实例

    一般情况下,每个进程都有自己的私有空间,理论上,别的进程是不允许对这个私人空间进行操作的,但是,我们可以利用一些方法进入这个空间并进行操作,将自己的代码写入正在运行的进程中,于是就有了远程注入了. 对 ...

  7. DLL远程注入及卸载实现

    实现win7 64位系统下dll的远程注入及卸载,尚未再其他系统测试 源码地址:https://github.com/ndhisrfzs/InjectDll

  8. CreateRemoteThread 远程dll注入

    1.dll中的内容 // dllmain.cpp : 定义 DLL 应用程序的入口点.#include "stdafx.h" BOOL APIENTRY DllMain( HMOD ...

  9. 使用CreateRemoteThread把代码远程注入指定exe执行

    由于本人也是新手,如果有朋友不懂windows api相关知识,我相信查阅书籍或者百度会比我说有帮助的多,下面就我所做简单复述一下过程,欢迎指正缺点. 效果图示如下: 做的这个例子首先是创建了一个MF ...

随机推荐

  1. C语言下文件目录查看

    C语言下文件目录遍历通常会用到下面这些函数 _access()        /* 判断文件或文件夹路径是否合法 */ _chdir() /* 切换当前工作目录 */ _findfirst()   / ...

  2. HDU 5183 Negative and Positive (NP) (hashmap+YY)

    学到了以邻接表方式建立的hashmap 题意:给你一串数a和一个数k,都有正有负,问知否能找到一对数(i,j)(i<=j)保证a [i] - a [i+1] + a [i+2] - a [i+3 ...

  3. 【转】一次完整的HTTP请求所经历的7个步骤

    HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该 ...

  4. 二叉查找树--java

    package com.test.tree; public class BinarySearchTree<T extends Comparable<? super T>> { ...

  5. socket和多线程编程资料汇集-基础篇

    0 基础 CS结构的分析,server端和client的选取. 1 查看端口是否链接 netstat -an|grep portid 2 root用户抓包 tcpdump port -w fn.cap ...

  6. 02-THREE.JS 辅助线使用

    <!DOCTYPE html> <html> <head> <title></title> <script src="htt ...

  7. 《Effective C++》——条款20:宁以pass-by-reference-to-const替换pass-by-value

    切割(slicing)问题 请看下面代码: class Window { public: ... std::string name()const; //返回窗口名称 virtual void disp ...

  8. 三目运算符与if else的运行效率

    两者的效率比较: 当比较次数较少时,效率一样: 当比较次数较多时,发现ifelse的速度更快,应该是其汇编指令更少的原因.   if else的汇编代码如下:     三目运算符代码如下:

  9. (转)libcurl库使用方法,好长,好详细。

    一.ibcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP ...

  10. uva11489 - Integer Game(考思维,找规律)

    从S开始时只能是两种情况: 1.现在总和已经是3的倍数了,那么因为每人每次只能拿走一个数,要保持拿走之后依然是3的倍数,那么就只能拿3,6,9这类数,用num统计一下,看看num奇偶性就知道谁最后拿了 ...