Dll注入:注冊表注入


在系統中每一個進程加載User32.dll時,會受到DLL_PROCESS_ATTACH通知,當User32.dll對其進行處理時,會取得注冊表鍵值HKEY_LOCAL_MACHINE\Software\Microsoft\windowsNT\CurrentVresion\Windows\AppInit_Dlls,並調用LoadLibrary來載入這個字符串中指定的每個DLL。被調用的DLL會在系統調用它們的DllMain函數,並將參數fdwReason的值設為DLL_PROCESS_ATTACH時,對自己進行初始化。所以我們在這個鍵值中添加我們的Dll路徑,即可實現注入。

注入流程:

打開注冊表鍵值如下:
HKEY_LOCAL_MACHINE\SoftWare\MicroSoft\Windows NT\CurrentVersion\Windows\

1.在上面的注冊表項中操作 AppInit_DLLs 鍵值,在該鍵值中添加自己的DLL的全路徑加dll名,多個DLL以逗號或者空格分開(因此在文件名中應該盡量不要存在空格),該鍵值只有第一個dll文件名可以包含路徑,后面的都不能包含,因此我們最好將dll放在系統路徑    下,這樣就可以不用包含路徑也能被加載了。

2.在該注冊表項中添加鍵值 LoadAppInit_DLLs ,類型為 DWORD,並將其值置為 1 .

注意:

1.AppInit_DLLs是一個REG_SZ類型,在這里寫入一個DLL的文件名或是一組DLL的文件名。如果寫入的是一組DLL文件名,那么中間要用逗號或者是空格分隔。由於在這里使用空格分隔文件名,因此一定要避免在DLL文件名中包含空格。第一個DLL的文件名可以包含路徑,但其他DLL包含的路徑則將被忽略。因此應該將多個DLL放到Windows系統目錄為妙,這樣就不必指定路徑了。

2.由於被注入的DLL是在進程生命期的早期被載入(User32.dll),因此在dll實現中所調用的函數應該被慎重考慮,當然,調用Kernel32.dll是可以的,但其他dll函數可能會導致問題,甚至會藍屏。

 

方法比較簡單,調用了USER32.dll 的進程都會被注入。可控性不強。

#include "stdafx.h"
#include <Windows.h>

#define DSTKEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows"

BOOL RegInject(WCHAR* DllFullPath);
int main()
{
    WCHAR DllFullPath[MAX_PATH] = L"C:\\Dll.dll";
    BOOL bOk = RegInject(DllFullPath);
    if (bOk)
    {
        printf("Registry inject success!\n");
    }
    else
    {
        printf("Registry inject fail!\n");
    }
    getchar();
    getchar();
    return 0;
    return 0;
}


//
//利用AppInit_Dlls鍵值會被user32.dll調用LoadLibrary所加載
//
BOOL RegInject(WCHAR* DllFullPath)
{

    BOOL bOk = FALSE;
    HKEY hKey = NULL;
    BYTE DllPath[MAX_PATH] = { 0 };


    printf("RegInject Enter...\r\n");


    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,DSTKEY,0,KEY_ALL_ACCESS,&hKey) != ERROR_SUCCESS)
    {
        printf("RegOpenKeyEx Error!\n");
        goto Exit;
    }

    memcpy((void*)DllPath, DllFullPath, _tcslen(DllFullPath)*2 + 1);


    if (RegSetValueEx(hKey,L"AppInit_DLLs",0,REG_SZ,DllPath, (_tcslen(DllFullPath) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS)
    {
        printf("RegSetKeyValue Error!\n");
        goto Exit;
    }

    DWORD dwValue = 1;


    if (RegSetValueEx(hKey,L"LoadAppInit_DLLs",0,REG_DWORD,(BYTE*)&dwValue,sizeof(dwValue)) != ERROR_SUCCESS)
    {
        printf("RegSetKeyValue Error!\n");
        goto Exit;
    }

    printf("RegInject Exit...\r\n");
    bOk = TRUE;

Exit:
    if (hKey)
        RegCloseKey(hKey);
    return bOk;

}

這個代碼沒有完善,沒有處理好,如果該鍵值里面已經有值得情況,也沒有寫清理函數。

參考:這個帖子比我寫的好。

http://blog.csdn.net/programmingring/article/details/18954193

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM