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

线程插入,在托管平台上面,是不能直接实现的。如果想通过托管平台在一个非托管的Process里面插入执行一段托管代码,就需要在非托管Process里面启动CLR。我们可以以此为突破口,通过直接调用CLR提供的功能接口来执行托管代码。

       最终效果,是实现了非托管平台下托管代码执行的混合型线程插入。

       在开发CLR的时候,MSCLR作为一个COM服务器放到了一个DLL里面。MSCLR定义了一个标准的COM接口,同时分配了全局的GUID。在安装Framework的时候,就被安装到了注册表里面去。

       基于上一篇文章里面讲的DotNet CLR Hosting的原理,就可以很容易实现在非托管进程里面启动CLR并且执行托管代码:

      

       首先,在非托管宿主里面加载CLR并且启动:

 

ICLRRuntimeHost *pCLRHost = NULL;
HRESULT hr = CorBindToRuntimeEx(

L"v2.0.40103",                     //需要加载的CLR版本,Null表示最新的

L"wks",                 //GC的风格,Null表示默认的工作站模式

STARTUP_CONCURRENT_GC,

CLSID_CLRRuntimeHost,                   //CLRCLSID

IID_ICLRRuntimeHost,               //ICLRRuntimeHostIID

(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;

       //创建一个远程需要执行插入dllthread,并且执行代码

       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.

 

 



lbq1221119 2008-05-19 14:10 发表评论

文章来源:http://www.cnblogs.com/lbq1221119/archive/2008/05/19/1202533.html
posted @ 2008-05-20 09:18  潜水员  阅读(135)  评论(0编辑  收藏  举报