一.DLL注入
为什么要注入DLL呢?
因为我们想在一个进程中做我们想要做的操作。而在Windows中,系统为每个进程都虚拟出了私有的地址空间。例如指针,它指向的只是本进程的内存,这使得很难对另一个进程进行操作和控制。但是通过注入DLL,我们可以在目标进程中执行DLL中的代码,从而达到操控目标进程的效果。
这里只详细说一下远程线程注入的方法,注入的方法还有很多,不再详细介绍。
首先准备好需要注入的DLL,注意DLL的指令集与目标程序是否兼容。
我们要通过CreateRemoteThread在目标进程创建一个线程,在线程内执行LoadLibrary载入要注入的DLL,从而完成DLL注入。
HMODULE hModule = GetModuleHandle("kernel32");
LPTHREAD_START_ROUTINE funcAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "LoadLibraryA");
void* pDllPathRemote = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, pDllPathRemote, (void*)dllPath, sizeof(dllPath), NULL);
hThread = CreateRemoteThread(hProcess, NULL, 0, funcAddr, pDllPathRemote, 0, NULL);
LoadLibrary用于读取我们要注入的DLL,它被定义在Kernel32.dll中,每个应用程序都需要Kernel32.dll,并且根据经验系统在每个进程都会将Kernel32.dll映射到同一地址。注意LoadLibrary是一个宏定义,实际需要选择LoadLibraryA或LoadLibraryW。
CreateRemoteThread是一个Windows API函数,它能够创建一个在其它进程地址空间中运行的线程。
VirtualAllocEx 函数的作用是在指定进程的虚拟空间申请一块内存区域。
WriteProcessMemory此函数能将数据写入某一进程的内存区域。
由于创建的线程在目标进程的内存空间执行,所以需要将DLL的路径传入目标进程。
二.DLL入口点
进程第一次映射一个DLL到其地址空间时,会调用DLL的入口点函数DllMain并传入DLL_PROCESS_ATTACH参数,我们可以在此进行API拦截操作。
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Intercept();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
三.系统API拦截
什么是API拦截?
API拦截就是在程序调用系统API之前让其先进入我们预设的函数,执行我们的操作。
API拦截主要有通过覆盖代码拦截,修改模块导入段拦截两种方式。
这里详细说一下