本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9690925
建立时间:2004年12月20日




[rootkit]在别人程序中运行自己的代码 
原创空间,  软件技术,  电脑与网络

邢红瑞 发表于 2005/10/18 18:40:33

Windows的大多数函数允许进程只对自己进行操作。这是很好的一个特性,因为它能够防止一个进程破坏另一个进程的运行。但是,有些函数却允许一个进程对另一个进程进行操作。这些函数大部分最初是为调试程序和其他工具设计的。不过任何函数都可以调用这些函数。这个DLL插入方法基本上要求目标进程中的线程调用LoadLibrary函数来加载必要的DLL。由于除了自己进程中的线程外,我们无法方便地控制其他进程中的线程,因此这种解决方案要求我们在目标进程中创建一个新线程。由于是自己创建这个线程,因此我们能够控制它执行什么代码。Windows提供了一个称为CreateRemoteThread的函数,使我们能够非常容易地在另一个进程中创建线程:CreateRemoteThread与CreateThread很相似,差别在于它增加了一个参数hProcess。该参数指明拥有新创建线程的进程。参数pfnStartAddr指明线程函数的内存地址。当然,该内存地址与远程进程是相关的。线程函数的代码不能位于你自己进程的地址空间中。注意在Windows2000中,更常用的函数CreateThread是在内部以下面的形式来实现的:Windows98在Windows98中,CreateRemoteThread函数不存在有用的实现代码,它只是返回NULL。Windows提供了一个函数,即VirtualAllocEx,使得一个进程能够分配另一个进程的地址空间中的内存:另一个函数则使我们能够释放该内存:远程进程由hProcess参数来标识。参数pvAddressRemote用于指明远程进程中的地址,参数pvBufferLocal是本地进程中的内存地址,参数dwSize是需要传送的字节数,pdwNumBytesRead和pdwNumBytesWritten用于指明实际传送的字节数。当函数返回时,可以查看这两个参数的值。既然已经知道了要进行操作,下面让我们将必须执行的操作步骤做一个归纳:1)使用VirtualAllocEx函数,分配远程进程的地址空间中的内存。2)使用WriteProcessMemory函数,将DLL的路径名拷贝到第一个步骤中已经分配的内存中。3)使用GetProcAddress函数,获取LoadLibraryA或LoadLibratyW函数的实地址(在user32.dll中)。4)使用CreateRemoteThread函数,在远程进程中创建一个线程,它调用正确的LoadLibrary函数,为它传递第一个步骤中分配的内存的地址。这就是它的基本操作步骤。这种插入DLL的方法存在的唯一一个不足是,Windows98并不支持这样的函数。只能在Windows2000上使用这种方法。以下是代码 #include "stdafx.h" #include <windows.h>typedef struct _RemotePara{//参数结构  char pMessageBox[120];  DWORD dwMessageBox; }RemotePara; //这是要注入的线程执行的代码DWORD __stdcall ThreadProc (RemotePara *lpPara){  typedef int (__stdcall *MMessageBoxA)(HWND,LPCTSTR,LPCTSTR,DWORD);//定义MessageBox函数  MMessageBoxA myMessageBoxA;  myMessageBoxA =(MMessageBoxA) lpPara->dwMessageBox ;//得到函数入口地址  myMessageBoxA(NULL,lpPara->pMessageBox ,lpPara->pMessageBox,0);//call return 0;     return 0;} //内存操作需要提升权限void EnableDebugPriv( void ) {  HANDLE hToken;  LUID sedebugnameValue;  TOKEN_PRIVILEGES tkp;  if ( ! OpenProcessToken( GetCurrentProcess(),   TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )   return;  if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) ){   CloseHandle( hToken );   return;  }  tkp.PrivilegeCount = 1;  tkp.Privileges[0].Luid = sedebugnameValue;  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL )   )   CloseHandle( hToken ); }运行的主程序#include "stdafx.h"#include "RemoteThread.h"int main(int argc, char* argv[]){ const DWORD THREADSIZE=1024*40;  DWORD byte_write;  EnableDebugPriv();//提升权限  HANDLE hWnd = OpenProcess (PROCESS_ALL_ACCESS,FALSE,3280);  if(!hWnd)return 0;  void *pRemoteThread =::VirtualAllocEx(hWnd,0,THREADSIZE,MEM_COMMIT| MEM_RESERVE,PAGE_EXECUTE_READWRITE);  if(!pRemoteThread)return 0;  if(!::WriteProcessMemory(hWnd,pRemoteThread,&ThreadProc,THREADSIZE,0))   return 0;   RemotePara myRemotePara;  ::ZeroMemory(&myRemotePara,sizeof(RemotePara));  HINSTANCE hUser32 = ::LoadLibrary ("user32.dll");  myRemotePara.dwMessageBox =(DWORD) ::GetProcAddress (hUser32 , "MessageBoxA");  strcat(myRemotePara.pMessageBox,"h\0");  //写进目标进程  RemotePara *pRemotePara =(RemotePara *) ::VirtualAllocEx (hWnd ,0,sizeof(RemotePara),MEM_COMMIT,PAGE_READWRITE);//注意申请空间时的页面属性  if(!pRemotePara)return 0;  if(!::WriteProcessMemory (hWnd ,pRemotePara,&myRemotePara,sizeof(myRemotePara),0))return 0;  //启动线程  HANDLE hThread = ::CreateRemoteThread (hWnd ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,pRemotePara,0,&byte_write);  if(!hThread){   return 0;  }  return 0; } 其实这就是一些病毒的机理,运行在别人的进程中,使自己不被发现。文字部分是参考windows核心编程的,代码是网上的,我没有任何版权。


阅读全文(4169) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144763525 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号