DLL注入原理
DLL注入原理
1 什么是DLL注入
DLL注入指的是向运行中的其他进程强制插入特定的DLL文件;DLL注入与一般DLL加载的区别在于, 加载的目标进程是其自身或其他进程。DLL被加载到进程后会自动运函数DllMain( )。
DLLMain函数模板:参考自MSDoc
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//add your code here
break;
case DLL_THREAD_ATTACH:
//add your code here
break;
case DLL_THREAD_DETACH:
//add your code here
break;
case DLL_PROCESS_DETACH:
//add your code here
break;
}
return TRUE;
}
2 DLL注入方法
- 创建远程线程:
CreateRemoteThreadO API
- 使用注册表:
Applnit_DLLs 值
- 消息钩取:
SetWindowsHookEx()API
2.1 远程线程法注入原理
利用CreateRemoteThrea()
函数在目标进程创建LoadLibrary()
线程来加载需要注入的DLL。
BOOL InjectDll(DWORD pid, LPCTSTR DllPath)
{
DWORD dwBufSize = (DWORD)(_tcslen(DllPath) + 1) * sizeof(TCHAR);
HANDLE hProcess = NULL;
HMODULE hMod = NULL;
HANDLE hThread = NULL;
LPTHREAD_START_ROUTINE pThreadProc;
LPVOID pRemoteBuf = NULL;
//获取目标进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess)
{
printf("open process failed! pid %d\n", pid);
return FALSE;
}
//在目标进程内存空间分配虚拟内存,存储DLL地址
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
//将DLL路径写入目标进程内存
int ret = WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)DllPath, dwBufSize, NULL);
//获取LoadLibrary函数地址
hMod = LoadLibrary("kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");
//在目标进程中创建LoadLibrary远程线程
hThread = CreateRemoteThread(
hProcess, //notepad进程句柄
NULL,
0,
pThreadProc, //LoadLibraryA句柄
pRemoteBuf, //需要注入的DLL文件路径
0,
NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
2.2 远程线程注入常用 API
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
//获取指定进程的快照,以及这些进程使用的堆,模块和线程。
//th32ProcessID = 0 则获取所有快照
HANDLE OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
//打开本地进程对象
LPVOID VirtualAllocEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
//在指定进程在内存中分配内存空间
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
);
//将数据写入指定进程的内存区域
HMODULE LoadLibraryA(
LPCSTR lpLibFileName
);
//将指定的模块加载到调用进程的地址空间中
HANDLE CreateRemoteThread(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
//创建在另一个进程的虚拟地址空间中运行的线程。
HMODULE GetModuleHandle(
LPCSTR lpModuleName
);
//检索指定模块的模块句柄。该模块必须已由调用进程加载。
FARPROC GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);
//从指定的动态链接库(DLL)中检索导出的函数或变量的地址