您的位置:首页 > 其它

(纪念国殇).Net Hosting:托管远程线程插入及非托管dll线程插入实现

2008-05-19 14:24 387 查看
线程插入,在托管平台上面,是不能直接实现的。如果想通过托管平台在一个非托管的Process里面插入执行一段托管代码,就需要在非托管Process里面启动CLR。我们可以以此为突破口,通过直接调用CLR提供的功能接口来执行托管代码。
       最终效果,是实现了非托管平台下托管代码执行的混合型线程插入。
       在开发CLR的时候,MS将CLR作为一个COM服务器放到了一个DLL里面。MS为CLR定义了一个标准的COM接口,同时分配了全局的GUID。在安装Framework的时候,就被安装到了注册表里面去。
       基于上一篇文章里面讲的DotNet CLR Hosting的原理,就可以很容易实现在非托管进程里面启动CLR并且执行托管代码:
      
       首先,在非托管宿主里面加载CLR并且启动:
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 

ICLRRuntimeHost *pCLRHost = NULL;
HRESULT hr = CorBindToRuntimeEx(
L"v2.0.40103",                     //需要加载的CLR版本,Null表示最新的
L"wks",                 //GC的风格,Null表示默认的工作站模式
STARTUP_CONCURRENT_GC,
CLSID_CLRRuntimeHost,                   //CLR的CLSID
IID_ICLRRuntimeHost,               //ICLRRuntimeHost的IID
(PVOID*) &pCLRHost);                     //返回的COM接口
 

初始化并且启动CLR:
pCLRHost->Start();

 

然后执行一段托管代码:
hr = pCLRHost ->ExecuteInDefaultAppDomain(L"test.exe",
                                        L" test.Program",
                                        L"Start",
                                        NULL,
                                        &retVal);
      
       可以把需要执行的托管函数放到一个编译好的本地代码集或者是dll里面。然后把上面的代码做成一个shellcode,这样就可以实现托管代码的线程插入了。
       这种技术,对于可以被插入的进程也是有限制的,仅限所有有权限进程WriteProcessMemory操作的本机进程。
 

这里仅讨论其实现的可能性和方法,个人感觉这种技术是鸡肋..
 

下面介绍下非托管下的dll线程插入技术的实现,首先介绍几个dll线程插入的时候的主要的函数:
OpenProcess - 用于打开要寄生的目标进程。
VirtualAllocEx/VirtualFreeEx - 用于在目标进程中分配/释放内存空间。
WriteProcessMemory - 用于在目标进程中写入要加载的DLL名称。
CreateRemoteThread - 远程加载DLL的核心内容,用于控制目标进程调用API函数。
LoadLibrary - 目标进程通过调用此函数来加载病毒DLL。
   

       单纯的加载一个dll到一个具有WriteProcessMemory操作权限的Process并不是很困难,只要利用上面的几个函数,就可以让目标进程执行相应的注入代码:
 

       //加载一个目标Library到指定的Process ID里面,并且创建一个线程同时执行注入的dll里面的代码。

BOOL RemoteLoadLibrary( DWORD dwProcessID, LPCSTR lpszDll )
{
       // 打开目标进程

       HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessID );
       // 向目标进程地址空间写入DLL名称
       DWORD dwSize, dwWritten;
       dwSize = lstrlenA( lpszDll ) + 1;
       //在目标进程里面分配空间

       LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT,
PAGE_READWRITE );
       if ( NULL == lpBuf )
       {
              CloseHandle( hProcess );
              return FALSE;
       }
       //把需要插入的dll的内容写到分配好了的Process的内存空间里面去。

       if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) )
       {
              // 要写入字节数与实际写入字节数不相等,仍属失败
              if ( dwWritten != dwSize )
              {    
                     //释放分配的空间。

                     VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
                     CloseHandle( hProcess );
                     return FALSE;
              }
       }
       else
       {
              CloseHandle( hProcess );
              return FALSE;
       }
 

       // 使目标进程调用LoadLibrary,加载DLL

       DWORD dwID;
       LPVOID pFunc = LoadLibraryA;
       //创建一个远程需要执行插入dll的thread,并且执行代码

       HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID );
       // 等待LoadLibrary加载完毕

       WaitForSingleObject( hThread, INFINITE );
       // 释放目标进程中申请的空间

       VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
       CloseHandle( hThread );
       CloseHandle( hProcess );
       return TRUE;
}
 

       上面把两种技术都列举出来了,基于托管平台和非托管平台实现dll插入的实现和对比。
 

       纪念国殇。2008-5-19 2:02:58 PM 首发sscli.cnblogs.com.

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息