进行DLL注入的三种方法
2008-04-09 04:12:19来源:互联网 阅读 ()
作者:陶冶(无邪) MAIL:taoy5178@hotmail.com OICQ:24149877 from:网络技术
在WINDOWS中,每个进程都有自己独立的地址空间,这样一个应用程序就无法进入另一个进程的地址空间而不会破坏另一个进程的运行,这样使得系统更加的稳定。但这样一来,相反的,如果我们要对我们感兴趣的进程进行操作也就变得复杂起来。比如,我们要为另一个进程创建的窗口建立子类或是要想从其中一个感兴趣的进程中取得一些有趣的信息(比如你想得到WIN2000用户登录的密码)。而DLL注入技术就是正好可以解决这些问题。DLL注入就是将DLL插入到其它你指定的进程的地址空间中,使得我们可以对感兴趣的进程进行操作。
在我们的DLL注入到指定的进程空间时,为了可以使我们更清楚地看到它已经成功对注入到了指定的进程空间,所以我们有需要使用一个简单的工具来查看指定的进程空间中所载入的所有模块,以便确定我们的DLL是否已经成功注入。如果你系统中装有WINDOWS优化大师,那么你可以利用它提供的进程工具来查看,没有也没关系,我用BCB写了一个小工具,虽然不怎么方便,但也可以清楚地看到指定进程空间中的所有载入模块。 该工具的主要代码如下:
//--------------------------------------------------------------------------- void __fastcall TfrmMain::btLookClick(TObject *Sender) { DWORD dwProcessId; BOOL bRet; MODULEENTRY32 hMod = {sizeof(hMod)}; HANDLE hthSnapshot = NULL; BOOL bMoreMods = FALSE; ListView->Clear(); if (Edit->Text == "") return; else dwProcessId = StrToInt(Edit->Text);
// 为进程建立一个快照 hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId); if (hthSnapshot == NULL) { MessageBox(Handle,("CreateToolhelp32Snapshot failed with error " IntToStr(GetLastError())).c_str(),"Error!", MB_ICONINFORMATION MB_OK); return; } // 获取模块列表中的模块 bMoreMods = Module32First(hthSnapshot, &hMod); if (bMoreMods == FALSE) { MessageBox(Handle,("Module32First failed with error " IntToStr(GetLastError())).c_str(),"Error!", MB_ICONINFORMATION MB_OK); return; } for (; bMoreMods; bMoreMods = Module32Next(hthSnapshot, &hMod)) { TListItem *Item; Item = ListView->Items->Add(); Item->Caption = String(hMod.szExePath); Item->ImageIndex = 0; } // 关闭句柄 CloseHandle(hthSnapshot); }
接下来就开始我们的正题吧。 DLL注入主要有三种方法,即应用HOOK技术、创建远程线程和特洛伊DLL三种。
一、应用HOOK技术进行DLL注入 我原来写过有关HOOK的介绍,如果你看过了或者是以前写过HOOK程序,那么你已经会这种DLL注入了。它其它就是为系统或某个线程安装一个钩子。这里要说的是,如果是全局钩子,那么你的DLL将会在进程调用时载入到任意一个调用的进程的地址空间中,这样是相当浪费资源的。因此我在下载的演示中就只对某一个指定的线程安装线程钩子。 1、用BCB建立一个DLL工程(如果你用的是VC或其它,请自己对照),输入以下代码: //=========================================================================== // 文件: UnitLib.cpp // 说明: 演示利用钩子技术进行DLL注入. // 将本DLL中的代码注入到指定的进程空间. // 作者: 陶冶(无邪) //=========================================================================== // 函数声明 extern "C" __declspec(dllexport) __stdcall bool SetHook(DWORD dwThreadId); extern "C" __declspec(dllexport) __stdcall LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam);
static HHOOK hHook = NULL; // 钩子句柄 static HINSTANCE hInst; // 当前DLL句柄 int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { hInst = hinst; return 1; } //--------------------------------------------------------------------------- // 安装钩子函数 bool __declspec(dllexport) __stdcall SetHook(DWORD dwThreadId) { if (dwThreadId != 0) { MessageBox(NULL, ("DLL已经注入!nThreadId = " IntToStr(dwThreadId)).c_str(),"DLL", MB_ICONINFORMATION MB_OK); // 安装指定线程的钩子 hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MyProc, hInst,dwThreadId); if (hHook != NULL) return true; }else { MessageBox(NULL, "DLL即将从记事本进程空间中撤出!","DLL", MB_ICONINFORMATION MB_OK); return (UnhookWindowsHookEx(hHook)); } return true; }
// 钩子函数 LRESULT CALLBACK __declspec(dllexport) __stdcall MyProc(int nCode, WPARAM wParam, LPARAM lParam) { // 因为只是演示DLL注入,所以这里什么也不做,交给系统处理 return (CallNextHookEx(hHook, nCode, wParam, lParam)); } //---------------------------------------------------------------------------
该DLL中有两个函数,一个为安装钩子函数(SetHook),另一个为钩子函数(MyProc)。其中安装钩子函数提供了一个参数,由该参数指定安装到哪个线程,如果该参数为0,则卸载钩子。 编译该工程,即生成我们要用来注入到指定进程中的DLL文件了。 2、建立测试工程。用BCB建立一个应用程序工程,在窗体中添加两个按钮,一个用来安装线程钩子,一个用来卸载。代码如下: //--------------------------------------------------------------------------- // SetHook函数原型声明 typedef BOOL (WINAPI *LPSETHOOK)(unsigned long dwThreadId);
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:Guest权限突破
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash