[导入](纪念国殇).Net Hosting:托管远程线程插入及非托管dll线程插入实现
线程插入,在托管平台上面,是不能直接实现的。如果想通过托管平台在一个非托管的Process里面插入执行一段托管代码,就需要在非托管Process里面启动CLR。我们可以以此为突破口,通过直接调用CLR提供的功能接口来执行托管代码。
最终效果,是实现了非托管平台下托管代码执行的混合型线程插入。
在开发CLR的时候,MS将CLR作为一个COM服务器放到了一个DLL里面。MS为CLR定义了一个标准的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, //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.
文章来源:http://www.cnblogs.com/lbq1221119/archive/2008/05/19/1202533.html