您的位置:首页 > 其它

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

2008-05-20 09:18 447 查看
线程插入,在托管平台上面,是不能直接实现的。如果想通过托管平台在一个非托管的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.

lbq1221119 2008-05-19 14:10 发表评论
文章来源:http://www.cnblogs.com/lbq1221119/archive/2008/05/19/1202533.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: