• DLL注入——使用注册表


    1.简介

    整个系统的配置都保存在注册表中,我们可以通过调整其中的设置来改变系统的行为。

    该方式依赖User32.dll,也就是说,需要可执行程序调用到这个系统动态库,我们注入的dll才会被执行到。基本上所有基于GUI的应用程序都使用了User32.dll。

    注册表位置:

    1. // AppInit_Dlls(64位程序读取)
    2. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows [AppInit_DLLs]
    3. //AppInit_Dlls(32位程序读取)
    4. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows [AppInit_DLLs]
    5. //32位系统
    6. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows [AppInit_DLLs]

    查看注册表:windows+R键,输入regedit

    AppInit_DLLs:需要包含一个DLL的文件名或一组DLL的文件名(通过空格或逗号分隔),例如:D:\testDll.dll。

    LoadAppInit_Dlls:将它的值设为1。

    原理:当User32.dll被映射到一个新的进程时,会收到DLL_PROCESS_ATTACH通知,会取得上述注册表AppInit_DLLs键的值,并调用LoadLibrary来载入这个字符串中指定的每个DLL。当系统载入每个DLL的时候,会调用它们的DLLMain函数并将参数fdwReason的值设为DLL_PROCESS_ATTACH,这样每个DLL就能够对自己进行初始化。

    2.示例

    2.1首先编译一个自定义的DLL,我使用的vs2019,创建一个动态链接库,如下图所示。

    2.2在dllmain.cpp中编写如下代码,主要是创建了一个新的进程,然后使用google浏览器打开百度页面。当系统载入每个DLL的时候,会调用它们的DLLMain函数并将参数fdwReason(这里命名为ul_reason_for_call)的值设为DLL_PROCESS_ATTACH,这样每个DLL就能够对自己进行初始化。

    1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
    2. #include "pch.h"
    3. #define CMD L"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
    4. #define URL L"http://www.baidu.com"
    5. BOOL APIENTRY DllMain( HMODULE hModule,
    6. DWORD ul_reason_for_call,
    7. LPVOID lpReserved
    8. )
    9. {
    10. TCHAR cmd[MAX_PATH] = { 0 };
    11. STARTUPINFO si = { 0 };
    12. PROCESS_INFORMATION pi = { 0 };
    13. si.cb = sizeof(STARTUPINFO);
    14. si.dwFlags = STARTF_USESHOWWINDOW;
    15. si.wShowWindow = SW_SHOWNORMAL;
    16. switch (ul_reason_for_call)
    17. {
    18. case DLL_PROCESS_ATTACH:
    19. wsprintf(cmd, L"%s %s", CMD, URL);
    20. // 创建一个新进程及其主线程;
    21. if (!CreateProcess(NULL, (LPTSTR)(LPCSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
    22. break;
    23. case DLL_THREAD_ATTACH:
    24. case DLL_THREAD_DETACH:
    25. case DLL_PROCESS_DETACH:
    26. if (pi.hProcess != NULL)
    27. CloseHandle(pi.hProcess);
    28. break;
    29. }
    30. return TRUE;
    31. }

    2.3编译然后生成库。

    将生成好的库放到一个简洁的路径下,这里放到D:/testDll.dll。

    2.4使用代码将键值写入到注册表。

    新建一个控制台应用程序,代码如下:

    1. #define DSTKEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\"
    2. BOOL RegInject(WCHAR* DllFullPath)
    3. {
    4. BOOL bOk = FALSE;
    5. HKEY hKey = NULL;
    6. BYTE DllPath[MAX_PATH] = { 0 };
    7. //打开注册表
    8. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, DSTKEY, 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
    9. {
    10. printf("RegOpenKeyEx Error!");
    11. return FALSE;
    12. }
    13. memcpy((void*)DllPath, DllFullPath, _tcslen(DllFullPath) * 2 + 1);
    14. //设置键值
    15. if (RegSetValueEx(hKey, L"AppInit_DLLs", 0, REG_SZ, DllPath, (_tcslen(DllFullPath) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS)
    16. {
    17. printf("RegSetKeyValue Error!");
    18. return FALSE;
    19. }
    20. DWORD dwValue = 1;
    21. //设置键值
    22. if (RegSetValueEx(hKey, L"LoadAppInit_DLLs", 0, REG_DWORD, (BYTE*)&dwValue, sizeof(dwValue)) != ERROR_SUCCESS)
    23. {
    24. printf("RegSetKeyValue Error! ");
    25. return FALSE;
    26. }
    27. //RegDeleteValue(hKey, L"AppInit_DLLs");
    28. //RegDeleteValue(hKey, L"LoadAppInit_DLLs");
    29. bOk = TRUE;
    30. if (hKey)
    31. RegCloseKey(hKey);
    32. return bOk;
    33. }
    34. // TODO: 在此处放置代码
    35. WCHAR DllFullPath[MAX_PATH] = L"D:\\testDll.dll";
    36. BOOL bOk = RegInject(DllFullPath);
    37. if (bOk)
    38. {
    39. printf("Registry inject success! ");
    40. }
    41. else
    42. {
    43. printf("Registry inject fail! ");
    44. }

    注意:程序要使用管理员权限执行,修改如下图所示。

     设置好注册表之后,任意GUI程序运行,都会打开浏览器,会弹出无数个网页。慎用!!!

    2.5删除注册表键值

    需要调用以下方法,删除对应的键值,这样才能将网页无限弹窗停止。

    1. RegDeleteValue(hKey, L"AppInit_DLLs");
    2. RegDeleteValue(hKey, L"LoadAppInit_DLLs");

  • 相关阅读:
    socket简介
    Nginx rewrite规则实现http跳转到https及301永久重定向
    Vue3组合式API
    使用PE U盘在VM Workstation中安装系统
    利用综合微生物指数评估富营养化危险沿海湿地生态状况
    Axios
    docker 登录本地仓库harbor问题
    【QT深入理解】QT中的几种常用的排序函数
    运行proto文件踩坑历程
    基于SSM+Vue+SpringCloud+MySQL的程序在线评测系统的设计与实现
  • 原文地址:https://blog.csdn.net/wzz953200463/article/details/126511895