« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 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核心编程的,代码是网上的,我没有任何版权。 |
|
|