随笔-64  评论-13  文章-2  trackbacks-0
这种方法同前一种方法相比,要显得复杂一些,并且这种方法只能在WIN2000中使用(XP,和最新的2003不知道)。具体步骤如下:

1)、取得远程进程的进程ID;

2)、在远程进程空间中分配一段内存用来存放要注入的DLL完整路径;

3)、将要注入的DLL的路径写到刚才分配的远程进程空间;

4)、从Kernel32.dll中取得LoadLibray的地址;

5)、调用CreateRemoteThread函数以从Kernel32.dll中取得的LoadLibrary函数的地址为线程函数的地址,以我们要注入的DLL文件名为参数,创建远程线程;

在第二三步中,为什么要把我们要注入的DLL的文件名写到远程进程的地址空间进行操作,《WINDOWS核心编程》中是这样描述的:

“(要注入的DLL文件名)字符串是在调用进程的地址空间中。该字符串的地址已经被赋予新创建的远程线程,该线程将它传递给L o a d L i b r a r y A。但是,当L o a d L i b r a r y A取消对内存地址的引用时, D L L路径名字符串将不再存在,远程进程的线程就可能引发访问违规”;



至于第四步中为什么不直接对LoadLibrary进行调用,《WINDOWS核心编程》中是这样描述的:

“如果在对C r e a t e R e m o t e T h r e a d的调用中使用一个对L o a d L i b r a r y A的直接引用,这将在你的模块的输入节中转换成L o a d L i b r a r y A的形实替换程序的地址。将形实替换程序的地址作为远程线程的起始地址来传递,会导致远程线程开始执行一些令人莫名其妙的东西。其结果很可能造成访问违 规。”

另:

DLL注入的步骤

1。在受害进程中为DLL代码分配要占据的空间。
用到的函数:VirtualAllocEx

2。在受害进程中为要注入的DLL所需的参数分配空间。
用到的函数:VirtualAllocEx

3。把DLL的名字和代码写入受害进程的存储空间。
用到的函数:WriteProcessMemory

4。在受害进程中创建线程,运行新注入的DLL。
用到的函数:CreateRemoteThread

5。释放受害进程中的资源。
用到的函数:VirtualFreeEx


//sample
#include <windows.h> Dzm?锷w? 
#include <winsvc.h> ?鵾 :.禔  
#include <tlhelp32.h> lY篼rc柲v? 
// DLL注入函数 ?W黲?銷  
bool LoadLib(DWORD dwProcessId, LPWSTR lpszLibName) =孔觧f镏J  
{ 焿t瞵醞  
     HANDLE hProcess = NULL;       ?7?箨W?  
     HANDLE hThread = NULL; /?G#q腱Y  
     LPWSTR lpszRemoteFile = NULL; i缘?碫9? 
      諥?堃櫛  
t~,?叮  
     // 打开远程进程 `2?q駉f<? 
     hProcess = OpenProcess(PROCESS_CREATE_THREAD             eO`;*?=? 
           | PROCESS_VM_OPERATION             綂?咧v?? 
           | PROCESS_VM_WRITE,             ?{瘐?高  
           FALSE,             陾?柺&荗w  
           dwProcessId); 浙?(v   
      w??S甗J? 
     if (hProcess == NULL)       鑉?>Y祽? 
     {             垺|}=Z肬_  
           MessageBox(NULL, "OpenProcess failed with error " , "Error",                   ?珚綛:  
                 MB_ICONINFORMATION + MB_OK);             )b禸齲;u  
           return FALSE;             ]嘢W?缣  
     } 户喯?椱m? 
      ?睟諗倝? 
            訬E)¥梥? 
     // 在远程进程中分配存贮DLL文件名的空间       庿}忸丁!  
     lpszRemoteFile = (LPWSTR)VirtualAllocEx(hProcess, NULL,                         1闎u;P?茒  
           sizeof(WCHAR) * lstrlenW(lpszLibName) + 1,             _tH硎娾]  
           MEM_COMMIT, PAGE_READWRITE);       <?J?痲v  
     if (lpszRemoteFile == NULL)             徇??笯l*  
     {       (SNX~[70  
           MessageBox(NULL, "VirtualAllocEx failed with error " , "Error", 囖沒何M?? 
                 MB_ICONINFORMATION + MB_OK); ?眖ir?  
           return FALSE; 龝H﹢湷?  
     } 巙碋κm7巇  
      幚w薦?H  
     // 复制DLL文件名到远程刚分配的进程空间 QH洐迦? 
     if (!WriteProcessMemory(hProcess, lpszRemoteFile, ?鈷坘侄煝  
           (PVOID)lpszLibName, sizeof(WCHAR) * lstrlenW(lpszLibName) + 1, ?钍禵绚?  
           NULL)) P+??滁  
     { E耦??C'? 
           MessageBox(NULL, "WriteProcessMemory failed with error " , "Error", p`j$潀1  
                 MB_ICONINFORMATION + MB_OK); ?鮑征? 
           return FALSE; ?etXF?%M  
     } 01?熜?鑴  
     // 取得LoadLibrary函数在Kennel32.dll中的地址 _雨B芰?  
     PTHREAD_START_ROUTINE pfnThreadRtn = 'k1汕  
           (PTHREAD_START_ROUTINE)GetProcAddress( j澇x竳俘? 
           GetModuleHandle("Kernel32.dll"),"LoadLibraryW"); E?涽gm埳? 
     if (pfnThreadRtn == NULL) 伓ZC騷远?  
     { >痥T ◣g? 
           MessageBox(NULL, "GetProcAddress failed with error " , "Error", y 广篋狤?  
                 MB_ICONINFORMATION + MB_OK); MqQ?? }  
           return FALSE; A?`|9欛  
     } e?&嘄 ^?  
     // 创建远程线程 c,0髛jgeJ  
     hThread = CreateRemoteThread(hProcess, `剎^D鯩?? 
           NULL, Ar鹼DH貂 ? 
           0, #W?枊R柑  
           pfnThreadRtn, // LoadLibrary地址 胭mG榍??  
           lpszRemoteFile, // 要加载的DLL名 楖8資啱  
           0,             ?I挷?腺? 
           NULL);       熿騒I<簀? 
     if (hThread == NULL)             撪?殥?v? 
     {             }教z >?  
           MessageBox(NULL, "CreateRemoteThread failed with error " , "Error",                   靁嘽g授G  
                 MB_ICONINFORMATION + MB_OK);             ? 4復?  
           return FALSE;             .k钄z5.S  
     } m袁鹯?Z? 
      躎?b|钍  
     // 等待线程返回       媣l\\厝I0  
     WaitForSingleObject(hThread, INFINITE); 屰騉-7@e? 
                  検蓮~R灔  
     // 释放进程空间中的内存       ?跑+e脌  
     VirtualFreeEx(hProcess, lpszRemoteFile, 0, MEM_RELEASE);       摶"汊驄&? 
     // 关闭句柄       钡領?荴  
     CloseHandle(hThread);       ?蚊ˉ?  
     CloseHandle(hProcess);                   ?G.矽庉N  
     return TRUE;       ZCu尢5賆  
} 90??嫫蟄  
螨^rn`+v膼  
void main() J癋赖澝?  
{ 嫟g賜jG?? 
     LPWSTR m_szDllFile = L"D:\\FileHook\\APIHook_Dll\\Debug\\APIHook_Dll.dll"; ?k2R脽忮  
     DWORD m_dwProcessId = 0; }Υofe介? 
     PROCESSENTRY32 pe; 蝷?掆  
     // 创建快照句柄 pT唓虌赦⊿  
     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 葺?M櫍M  
     // 先搜索系统中第一个进程的信息 cG嫕l詻翘? 
     Process32First(hSnapshot, &pe); q杴5?Y? 
     // 下面对系统中的所有进程进行枚举,并保存其信息 _m?]5椃t  
     do{             FMJ?  
           if(strcmp(pe.szExeFile,"explorer.exe") == 0      ) h? |VH? 
                  F塠昷籛^  
           { 彞€?T胉eF  
                 m_dwProcessId =pe.th32ProcessID; m災滑磁A? 
                 break; /?漌2n? 
           } O??拻懠? 
     } 5謣軇旽j  
     while (Process32Next(hSnapshot, &pe)); M_:娌_樆? 
     // 关闭快照句柄 w?E眳  
     CloseHandle(hSnapshot); 鐭ㄘ碲ш潰  
     LoadLib(m_dwProcessId, m_szDllFile); ?8Y旡X苽{  
} 唜#B鮘  
?i淪渧"f?

posted on 2008-01-16 22:54 桂湖山 阅读(1522) 评论(0)  编辑 收藏 引用 所属分类: windows OS
只有注册用户登录后才能发表评论。