《Windows API巡礼》--CreateRemoteThread和WriteProcessMemory

CreateRemoteThread函数用于为指定进程创建线程,该线程将会在其他进程的地址空间中执行,访问其他进程的资源:

HANDLE WINAPI CreateRemoteThread(

  __in   HANDLE hProcess, //需要为其创建线程的目标进程句柄,该目标进程需要具有如下权限:

                              //PROCESS_CREATE_THREADPROCESS_QUERY_INFORMATION

                              //PROCESS_VM_OPERATIONPROCESS_VM_WRITEPROCESS_VM_READ

  __in   LPSECURITY_ATTRIBUTES lpThreadAttributes, //指向安全描述符的指针,NULL为默认

  __in   SIZE_T dwStackSize, //线程堆栈大小,0表示使用默认值

  __in   LPTHREAD_START_ROUTINE lpStartAddress, //函数指针,指向存在与目标进程中的线程函数

  __in   LPVOID lpParameter, //传给线程函数的参数

  __in   DWORD dwCreationFlags, //0---线程创建后立即运行;

//CREATE_SUSPENDED---线程创建后挂起,知道ResumeThread函数调用才开始运行;

//STACK_SIZE_PARAM_IS_A_RESERVATION---dwStackSize参数指定初始保留的堆栈大小

//不指定该标志时,dwStackSize表示提交的大小(commit size

  __out  LPDWORD lpThreadId //指向存放线程ID的缓冲区的指针,为NULL表示不保存线程ID

);

返回值:

成功时,返回新线程的句柄;

失败时,返回NULL

 

WriteProcessMemory函数用于将数据写入到目标进程的虚拟地址空间中:

BOOL WINAPI WriteProcessMemory(

  __in   HANDLE hProcess, //目标进程句柄,操作进程需要有目标进程的PROCESS_VM_WRITE

                            //PROCESS_VM_OPERATION权限

  __in   LPVOID lpBaseAddress, //写入数据的地址,目标进程虚拟地址空间中的地址

  __in   LPCVOID lpBuffer, //指向需要写入的数据

  __in   SIZE_T nSize, //写入数据的字节大小

  __out  SIZE_T *lpNumberOfBytesWritten //用于保存实际写入的数据的大小

);

返回值:

成功时,返回非零值;

失败时,返回零值。

 

实例代码:直接将远程进程地址空间中的API函数LoadLibraryW作为线程函数调用:

#include <windows.h>

 

/***********************************************************

* 功能:通过创建远程线程给其他进程加载DLL

* 参数:dwProcessId--目标进程PID

*       lpszLibName--DLL的路径

* 返回值:是否成功

***********************************************************/

BOOL LoadRemoteDll(DWORD dwProcessId, LPTSTR lpszLibName)

{

    BOOL bResult = FALSE;

    HANDLE hProcess = NULL;

    HANDLE hThread = NULL;

    PTSTR pszLibFileRemote = NULL;

    DWORD cch;

    PTHREAD_START_ROUTINE pfnThreadRtn;

   

    __try

    {

        //获得想要注入代码的进程的句柄

        hProcess = OpenProcess(PROCESS_ALL_ACCESS,

                              FALSE, dwProcessId);

        if(hProcess == NULL)

        {

            __leave;           

        }    

        //计算DLL路径名需要的字节数

        cch = lstrlen(lpszLibName) + 1;

        //在远程线程中为路径名分配空间

        pszLibFileRemote = (PTSTR)VirtualAllocEx(

                           hProcess, NULL, cch,

                           MEM_COMMIT, PAGE_READWRITE);

        if(pszLibFileRemote == NULL)

        {

            __leave;                   

        }

       

        //DLL的路径名复制到远程进程的内存空间

        if(!WriteProcessMemory(hProcess,

                  (PVOID)pszLibFileRemote,

                  (PVOID)lpszLibName,

                  cch,

                  NULL))

        {

            __leave;         

        }

       

        //获得LoadLibraryKernel32.dll中的真实地址

        pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(

                     GetModuleHandle(TEXT("Kernel32")), TEXT("LoadLibraryW"));

        if(pfnThreadRtn == NULL)

        {

            __leave;               

        }

       

        //创建远程线程,并通过远程线程调用用户的DLL文件

        hThread = CreateRemoteThread(hProcess, NULL,

                0, pfnThreadRtn, (PVOID)pszLibFileRemote,

                0, NULL);

        if(hThread == NULL)

        {

            __leave;           

        }

       

        //等待远程线程终止

        WaitForSingleObject(hThread, INFINITE);

        bResult = TRUE;

    }    

    __finally

    {

        //关闭句柄

        if(pszLibFileRemote != NULL)

        {

            VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);

            pszLibFileRemote = NULL;                   

        }        

        if(hThread != NULL)

        {

            CloseHandle(hThread);

            hThread = NULL;

        }

        if(hProcess != NULL)

        {

            CloseHandle(hProcess);

            hProcess = NULL;           

        }

    }

    return bResult;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值