DLL注入–注册表注入

转载至http://www.crackme.cn/programming/523.html

在Windows NT/2000/XP/2003中,有一个注册表项:
HKEY_LOCAL_MACHINE/Software/Microsoft/WindowsNT/CurrentVersion/Windows/
利用当中的一个键值对AppInit_DLLs,进行DLL注入

AppInit_DLLs是一个REG_SZ类型,在这里写入一个DLL的文件名或是一组DLL的文件名。如果写入的是一组DLL文件名,那么中间要用逗号或者是空格分隔。由于在这里使用空格分隔文件名,因此一定要避免在DLL文件名中包含空格。第一个DLL的文件名可以包含路径,但其他DLL包含的路径则将被忽略。因此应该将多个DLL放到Windows系统目录为妙,这样就不必指定路径了。为了能够让系统使用这个注册表项,还需要一个名为LoadAppInit_Dlls的REG_DWORD类型的注册表项,并将其值设置为1.(经测试,LoadAppInit_Dlls键值对可以不用写)

注入原理:
User32.dll被映射到一个新的进程时,会收到DLL_PROCESS_ATTACH通知。当User32.dll对它进行处理的时候,会取得上述注册表键值,并调用LoadLibrary来载入这个字符串中指定的每个DLL。当系统载入每个DLL的时候,会调用它们的DllMain函数并将参数fdwReason的值设为DLL_PROCESS_ATTACH,这样每个DLL就能够对自己进行初始化。由于被注入的DLL是在进程的生命期的早期被载入的,因此我们在调用函数的时候应该慎重。调用Kernel32.dll中的函数应该没有问题,但是调用其他DLL中的函数可能会导致问题,甚至可能会导致蓝屏。User32.dll不会检查每个DLL载入或是初始化是否成功

所注入的dll注意事项:
1. 只有程序加载user32.dll才会触发上述注册表键值
2. 注册表注入dll后,所注入的dll会自动卸载.所以实现函数必须用线程来实现 或 用注入的dll加载共它dll

简单例程:(exe)

#include <iostream>

#include "windows.h"

using namespace std;


#define _EXIT system("pause");return 0

#define SUBKEY_PATH"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows"

#define KEY_NAME_A"AppInit_DLLs"

#define KEY_NAME_B"LoadAppInit_DLLs"// 此键貌似添不添加都无所谓


bool IsModule(const char *mod);// 判断模块是否存在


int main()

{

HMODULE hmod = 0;

if(!IsModule("user32.dll"))

{

cout<<"user32.dll没有加载"<<endl;

LoadLibrary("user32.dll");

//LoadLibrary("C:\\test_dll\\Release\\test_dll.dll");

}

char szInjectDLLs[256] = {0};

cout<<"需注入的dll,多个dll用;分隔:"<<endl;

cin.getline(szInjectDLLs, 256);


HKEY hSubKey = 0;

DWORD num = 1;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY_PATH, 0, KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS)

{

if((RegSetValueEx(hSubKey, KEY_NAME_A, 0, REG_SZ, (PBYTE)szInjectDLLs, strlen(szInjectDLLs) + 1) == ERROR_SUCCESS) &&

   (RegSetValueEx(hSubKey, KEY_NAME_B, 0, REG_DWORD, (PBYTE)(&num), 4) == ERROR_SUCCESS))

{

cout<<"DLL注入-注册表注入成功!"<<endl;

_EXIT;

}

}

else

{

// 子键不存在

cout<<"子键: "<<SUBKEY_PATH<<" 不存在"<<endl;

}

cout<<"DLL注入-注册表注入失败!"<<endl;

_EXIT;

}


bool IsModule(const char *mod)

{

HMODULE hMod_user = GetModuleHandle(mod);

if(!hMod_user)

{

return false;

}

return true;

}


简单例程:(dll)

// test_dll.cpp : Defines the entry point for the DLL application.

//


#include "stdafx.h"


VOID CALLBACK ShowMsg()

{

MessageBox(NULL, "我是信息框", "注入成功!", MB_OK);

}


BOOL APIENTRY DllMain( HANDLE hModule, 

                       DWORD  ul_reason_for_call, 

                       LPVOID lpReserved

 )

{

if(ul_reason_for_call == DLL_PROCESS_ATTACH)

{

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ShowMsg, NULL, 0, NULL);

}

    return TRUE;

}



评论
©Mrack | Powered by LOFTER