用户层注入:(3)DLL劫持注入

基本概念

  Windows的应用程序在加载进程所需的动态库时,会根据导入表一一加载。但是,我们的导入表中只保存有动态库的名称,系统如何知道这个动态库的完整路径并将其加载呢?
  其实,在加载动态库时,系统会按照一定的顺序搜索各个目录来寻找指定的Dll文件。一般搜索顺序为:

应用程序所在目录-->系统目录-->16位系统目录-->Windows目录-->运行程序的当前目录-->PATH环境变量。

  这还与注册表项HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode有关,如果键值为1,则执行上述的搜索顺序。如果键值为0,则执行如下的搜索顺序:

应用程序所在目录-->运行程序的当前目录-->系统目录-->16位系统目录->Windows目录-->PATH环境变量。

注入原理

  上面说到,系统在加载所需的动态库时,第一个搜索的目录总是我们应用程序所在的目录,而应用程序常用的动态库Kernel32.dll、User32.dll等动态库是保存在Windows系统目录下的,搜索顺序都是比较靠后的,那么我们是否可以在当前目录下伪造一个User32.dll,提供同样的导出表,将每个导出函数转发到真正的User32.dll动态库里,同时可以实现我们自定义的操作,让系统误以为自己实际上已经加载了真正的User32.dll呢?
  这确实是行得通的。因为我们在系统加载真正的动态库之前阻止了他,就好像我们将Dll劫持了一样,所以这种注入方式又被称为Dll劫持注入。

函数转发

  在劫持了真正的Dll文件后,系统就会使用我们自定义Dll文件的导出表,这是如果不做调整,我们的Dll就会"露馅"。所以,在劫持了真正的Dll文件后,我们同时要保证Dll文件内的功能也要"劫持"到,这里我们使用的是函数转发机制。

#pragma comment(linker,"/EXPORT:MyMessageBox=User32.MessageBoxA")

  这段代码告诉编译器,系统在调用我们的Dll中的MyMessageBox时,会自动转发到User32.Dll中的MessageBoxA函数去执行。这就好比我们绑架了User32,然后我们假装告诉操作系统我们就是User32,这时候系统告诉我实现一下MessageBoxA函数,我们就可以把这个活甩给真正的User32,让它来完成,然后我们把完成的结果再返回给系统。以上就是函数转发机制的实现原理。

函数调用

  除了函数转发外,还有一种比较常用的方法,那就是函数调用。

VOID _declspec(naked) MyMessageBox()
{
	LPVOID MessageBoxAddress = NULL;
	HMODULE ModuleHandle = NULL;
	//加载真正的动态库
	ModuleHandle = LoadLibrary(_T("User32.dll"));
	if (ModuleHandle != NULL)
	{
		//获得导出函数的地址
		MessageBoxAddress = GetProcAddress(ModuleHandle, "MessageBoxA");
		if (MessageBoxAddress)
		{
			__asm
			{
				//跳转到真正的函数地址处
				jmp MessageBoxAddress
			}
		}
		//释放动态库
		FreeLibrary(ModuleHandle);
	}
}

  函数调用主要是在我们的函数内部,又手动加载了真正的动态库,获得了动态库的导出函数,一旦我们的函数被系统调用,我们再在函数内调用真正的函数,在实现了我们自定义操作的同时,同时保证了功能的完整性。
  如果说函数转发是"胁迫"真正的Dll帮我们实现功能,那么函数调用就是让Dll告诉我们实现的方法,我们自己自己来实现。

局限性

  (1)Windows7以上,系统没有了SafeDllSearchMode 这一选项,而是采用新的注册表项\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs,凡是此项下的DLL文件就会被禁止从应用程序自身所在的目录下调用,而只能从系统目录即SYSTEM32目录下调用。
在这里插入图片描述
  (2)有些Dll文件在加载时需要检查签名等选项,如果是我们伪造的Dll,检查时就会出错,这也就导致了Dll劫持的失败。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值