VCpp代码注入,在其它程序中运行自定义代码

⌚Time: 2023-03-18 19:01:39

👨‍💻Author: Jack Ge

通过CreateRemoteThread注入代码的步骤

1.通过FindWindow、GetWindowThreadProcessId、OpenProcess打开目标进程

2.通过VirtualAllocEx函数在目标进程中分配内存

3.使用WriteProcessMemory将代码和变量写入到目标进程

4.使用CreateRemoteThread启动远程线程,运行注入的代码

定义自定义函数


//自定义函数

static DWORD myFuncStart(void *arg){

    int aa = 0;

    aa = *(int*)arg * 2;

    //MessageBox(NULL,NULL,L"",MB_OK);

    //printf("a");

    return aa;

}

//定义个静态变量,便于计算代码大小

static int ga;

计算代码大小


DWORD dwCodeSize = (DWORD)&ga - (DWORD)myFuncStart;

分配代码内存空间


void *pCodeRemote = VirtualAllocEx( hProcess, 0, dwCodeSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE );

注入代码


WriteProcessMemory( hProcess, pCodeRemote, (LPCVOID)myFuncStart, dwCodeSize, NULL);

分配变量内存


void *pDataRemote = VirtualAllocEx( hProcess, 0, sizeof(iArg), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);

写入参数值到目标程序内存


WriteProcessMemory( hProcess, pDataRemote, (void*)&iArg, sizeof(iArg),NULL);

建立远程线程执行代码


HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pCodeRemote, pDataRemote, 0 , NULL);

完整代码


#include <iostream>

#include <windows.h>

using namespace std;

static DWORD myFuncStart(void *arg){

    int aa = 0;

    aa = *(int*)arg * 2;

    //MessageBox(NULL,NULL,L"",MB_OK);

    //printf("a");

    return aa;

}

static int ga;

int main()

{

    //获取目标程序窗体句柄 查找”随机数生成器“程序

    HWND hwnd = FindWindow(NULL,L"随机数生成器");

    //获取目标程序线程pid

    DWORD pId;

    GetWindowThreadProcessId(hwnd,&pId);

    //打开目标进程

    HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pId);

    //函数参数

    int iArg = 999;

    //在目标程序中分配变量内存

    void *pDataRemote = VirtualAllocEx( hProcess, 0, sizeof(iArg), MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);

    if(GetLastError()){

        cout<<"1error!!"<<GetLastError()<<endl;

    }

    //写入参数值到目标程序的内存

    WriteProcessMemory( hProcess, pDataRemote, (void*)&iArg, sizeof(iArg),NULL);

    if(GetLastError()){

        cout<<"2error!!"<<GetLastError()<<endl;

    }

    //计算注入的代码大小

    DWORD dwCodeSize = (DWORD)&ga - (DWORD)myFuncStart;

    cout<<"inject code size:"<<dwCodeSize<<endl;

    //分配代码地址空间

    void *pCodeRemote = VirtualAllocEx( hProcess, 0, dwCodeSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE );

    if(GetLastError()){

        cout<<"3error!!"<<GetLastError()<<endl;

    }

    //注入代码

    WriteProcessMemory( hProcess, pCodeRemote, (LPCVOID)myFuncStart, dwCodeSize, NULL);

    if(GetLastError()){

        cout<<"4error!!"<<GetLastError()<<endl;

    }

    //建立远程线程,执行目标程序注入的代码

    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pCodeRemote, pDataRemote, 0 , NULL);

    if(GetLastError()){

        cout<<"5error!!"<<GetLastError()<<endl;

    }

    if (hThread)

    {

        //等待线程执行结束

        WaitForSingleObject( hThread, INFINITE );

        //获取线程函数返回值

        DWORD remoteRet;

        GetExitCodeThread( hThread, &remoteRet );

        cout<<"函数返回值:"<<remoteRet<<endl;

        //关闭线程

        CloseHandle( hThread );

        //释放目标程序中分配的内存

        VirtualFreeEx(hProcess, pDataRemote, 0, MEM_RELEASE);

        VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);

    }

    system("pause");

    return 0;

}


在自定义函数代码中如果调用printf、MessageBox等函数,会导致宿主程序崩溃,猜测是调用的函数也是代表程序地址,如果是在本地程序编译将这些函数编译进程序并且确定了函数地址,而宿主程序中明显是没有这类函数地址的,因此执行会导致程序崩溃

另外,32位程序不可将代码注入64位程序,会导致CreateRemoteThread函数返回错误5,拒绝访问