添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

DLL注入

DLL注入是指向运行中的其他进程强制插入特点的DLL文件。DLL注入命令其他进程自行调用LoadLibrary()API,加载用户指定的DLL文件,此时该DLL的DllMain()函数就会被调用执行。

DLL注入的实现方法

  1. 创建远程线程(CreateRemoteThread() API)
  2. 使用注册表(AppInit_DLLs值)
  3. 消息钩取(SetWindowsHookEx()API)
  4. CreateRemoteThread()

    首先看一下myhack.dll源代码

    myhack.dll

    #include "pch.h"
    #include<Windows.h>
    #include<tchar.h>
    #pragma comment(lib,"urlmon.lib")
    #include <Urlmon.h>
    #define DEF_URL (L"http://www.naver.com/index.html")
    #define DEF_FILE_NAME (L"index.html")
    HMODULE g_hMod = NULL;
    DWORD WINAPI ThreadProc(LPVOID lParam) {
    	//第三个参数填需要下载文件的地址
        URLDownloadToFile(NULL, DEF_URL, L"C:\\Users\\rkvir\\Desktop\\hook\\index.html", 0, NULL);
        return 0;
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
        HANDLE hThread = NULL;
        g_hMod = hModule;
        switch (ul_reason_for_call)
        case DLL_PROCESS_ATTACH:
            OutputDebugString(L"myhack.dll Injection!");
            hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
            CloseHandle(hThread);
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        return TRUE;
    

    我们可以看到该DLL被加载时,先输出一个字符串myhack.dll Injection!,然后创建线程调用函数,通过URLDownloadToFile()API下载指定网站的文件。

    InjectDll.exe

    当我们有了实现功能的DLL文件,现在还需要一个能够将DLL注入到进程中的工具

    #include<Windows.h>
    #include<tchar.h>
    BOOL InjectDll(DWORD dwPid, LPCTSTR szDllPath) {
    	HANDLE hProcess = NULL, hThread = NULL;
    	HMODULE hMod = NULL;
    	LPVOID pRemoteBuf = NULL;
    	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
    	LPTHREAD_START_ROUTINE pThreadProc;
    	//1.使用dwPid获取 目标进程(notepad.exe)句柄
    	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    	if (!hProcess)
    		_tprintf(L"OpenProcess(%d)v failed!!! [%d]\n", dwPid, GetLastError());
    		return FALSE;
    	//2.在目标进程(notepad.exe)中分配szDllName大小的内存,dll文件的路径
    	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
    	//3.将myhack.dll路径写入分配的内存
    	WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
    	//4.获取LoadLibraryW()API的地址
    	hMod = GetModuleHandle(L"kernel32.dll");
    	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
    	//5.在notepad.exe进程中运行线程
    	//pThreadProc为notepa.exe进程内存中的LoadLibraryW地址
    	//pRemoteBuf为写入到notepa.exe进程内存中的myhack.dll字符串地址
    	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
    	WaitForSingleObject(hThread, INFINITE);
    	CloseHandle(hThread);
    	CloseHandle(hProcess);
    	return TRUE;
    int _tmain(int argc, TCHAR* argv[]) {
    	if (argc!=3)
    		//检查输入程序的参数是否为3个
    		_tprintf(L"USAGE: %s Pid Dll_Path \n", argv[0]);
    	if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
    		_tprintf(L"InjectDll(\"%s\") Success!!!\n", argv[2]);
    		_tprintf(L"InjectDll(\"%s\") Failed!!!\n", argv[2]);
    	return 0;
    

    其实这里面最主要的就是CreateRemoteThread,通过这个API,我们可以在notepad.exe进程中创建一个实现DLL加载的LoadLibrary线程.CreateRemoteThread的第四个参数原本是指向线程函数地址,我们指向LoadLibrary,同时第五个参数就是LoadLibrary的参数,我们传入需要加载的DLL的路径。

    AppInit_DLLS

    将要注入的DLL的路径字符串写入AppInit_DLLs项目,然后将LoadAppInit_DLLs的项目置为1,就可以实现注入

    原理

    User32.dll被加载到进程中时,会读取AppInit_DLLs注册表项,若有值,则调用LoadLibrary()API加载用户DLL。严格意义上说,dll只会加载到加载User32.dll的进程。

    实验

    我们实现注入myhack2.dll

    1.首先修改AppInit_DLLs的值

    2.将LoadAppInit_DLLs的值修改为1

    3.重启系统,使修改生效

    已经注入进去了,只要加载user32.dll的进程都会被注入,但是只有进程为notepad.exe才会进行操作

    SetWindowsHookEx()

    这个API安装好消息钩子后,由OS将指定的DLL强制注入到相应的进程

    DLL卸载

    利用了FreeLibrary()API,仅适用于卸载自己强制注入的DLL文件,和通过CreateRemoteThread原理一样,这里只是把第四个参数改为FreeLibrary的地址,第五个参数为DLL加载地址。


    转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]