注入DLL是个古老的技术,但是应用很广泛,特别在ring3下
注入的方法通常是3种
一.通过注册表键去写,这种方法的缺点是要等到系统重启后才能加载,
优点就是能方便注入多个,某些恶意软件通过这个方式,注入大量的DLL
有时候导致Explorer.exe的线程等待很长时间才能进入桌面
二.通过消息钩子,消息钩子的原理是这样的,我从看雪上得知的,
如果你设置一个消息钩子,每当某个进程处理消息的时候会检查是否存在
钩子,如果存在,将试图把DLL加载进来处理钩子,这样,DLL就轻松进入的进程
例子就是 ~WINDOW核心编程~;中的一个HOOK MESSAGEBOX的源码
三.通过创建远程线程,CreateRemoteThread,有几点需要注意的,
线程必须是目标内存里面的,所以必须要把线程CALL BACK函数写到
目标,WriteProcessMemory,不过整个回调函数写到目标,工作量似乎有点大,可以把LoadLibrary,做为远程线程函数,
要WriteProcessMemory就必须要找到一个内存区域来写,VirtualAllocEx可以用来申请
到内存,注意申请的内存要是PAGE_EXECUTE_READWRITE,
DWORD WINAPI ThreadProc( LPVOID lpParameter // thread data);
HMODULE LoadLibrary( LPCTSTR lpFileName // file name of module);
两段函数比较参数都是一个,所以做起来比较方便,
首先要获取LoadLibrary的地址,然后再把要注入的DLL文件名注入
到远程目标,因为要远程调用,所以注入的东西不能仅仅存在本来的进程
连个字符串都要写到目标上,下面给出一个例子,注入DLL到扫雷里面
HANDLE hProcess,hRemoteProcess; DWORD dwProcessId; HWND hwnd = ::FindWindow("扫雷","扫雷"); if(hwnd==NULL) { MessageBox("查找不到窗口"); return; }
GetWindowThreadProcessId(hwnd,&dwProcessId) ;
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,FALSE,dwProcessId); if(hProcess==NULL) { MessageBox("打开进程失败"); return; }
LPVOID dwInfoAddr = OpenMemory(hProcess,4096);
char dll_path[50] = "InjectDLL/0";
LPTHREAD_START_ROUTINE addr_loadlib = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"); injectInfo.LoadLibFunc =addr_loadlib;
if(!WriteProcessMemory(hProcess,dwInfoAddr,dll_path,sizeof(dll_path),NULL)) MessageBox("写内存失败");
hRemoteProcess = CreateRemoteThread( hProcess, // handle to process NULL, // SD 0, // initial stack size (LPTHREAD_START_ROUTINE)addr_loadlib, // thread function dwInfoAddr, // thread argument 0, // creation option NULL); // thread identifier if(hRemoteProcess == NULL) MessageBox("创建远程线程失败");
}
LPVOID OpenMemory(HANDLE hProcess,DWORD dwSize){ LPVOID lpAddr; lpAddr = VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if(lpAddr == NULL) { MessageBox(NULL,"开内存失败","title",MB_OK); } return lpAddr;}
这样就完成注入的过程,
最后~~~注意清理申请回来的内存
