这种方法同前一种方法相比,要显得复杂一些,并且这种方法只能在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; /?漌2n?
} 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
桂湖山 阅读(1530)
评论(0) 编辑 收藏 引用 所属分类:
windows OS