我是靠谱客的博主 忧虑鱼,最近开发中收集的这篇文章主要介绍CreateRemoteThread简单应用之二,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

宿主进程 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简单应用之二所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部