【文章标题】: dll劫持
【文章作者】: 125096
【软件名称】: dll.dll
【加壳方式】: 无
【编写语言】: VS2010
【使用工具】: VS2010,OllyDbg,LordPE.EXE,MSND
【操作平台】: 盗版WIN732位操作系统
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
大家好,我是125096。今天研究了下dll劫持,以前听说过,也看到过论坛里大牛们放出的成品。一直认为这是一个神奇的东东,打我PG我不乖。
以前中过lpk.dll病毒的朋友心里最清楚了。应用程序会从当前路径加载lpk.dll这个例子最好不过了。我的系统的盗版的win7系统发现不会中这个病毒了。把lpk.dll和USP10.dll拷贝到exe的目录下不会从当前目录加载。尝试找了许多系统的dll都不会? 群里的扫地大叔说系统核心dll不会加载的。貌似这个是win7的新改进,以前用盗版的XP系统。经常中这玩意。在win7中注册表的位置是[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs],我尝试着改下dll,发现无权限。里面包括的dll有很多,大家可以打开注册表自己定位看下。好了,说了这么多了。咱们开始吧。less go
下面的例子是exe调用系统函数部分。GetFileVersionInfoSize位于version.dll(要劫持dll时请去注册表确认是否存在名单中,当然我这个不在)
#include <iostream>
#include <Windows.h>
#include <Winver.h>
#pragma comment (lib,"Version.lib")
using namespace std;
int main (void)
{
DWORD nSize=GetFileVersionInfoSize(TEXT("D:\\IPHLPAPI.DLL"),NULL);
cout<<nSize<<endl;
return 0;
}
下面我们用LordPE.EXE打开version.dll,这个dll很小,只有15个导出函数,下面会减少不少工作量。由于不同版本的win7可能这里和我的不一样(我的是盗版win7没更新补丁的)
我的思路的这样的,exe加载我的dll,我的dll在加载系统目录下的dll然后获取系统的函数给exe调用。代码采用vs2010编写,由于编译器会产生很多垃圾代码(其实就是堆栈平衡之类的,这个堆栈平衡会影响咱们的工作。所以先定义我们写的函数是asm的,让编译器不用产生垃圾代码,不过我们就得自己来处理堆栈了)
//宏定义
#define EXTERNC extern "C"
#define NAKED __declspec(naked)
#define EXPORT __declspec(dllexport)
#define ALCPP EXPORT NAKED
#define ALSTD EXTERNC EXPORT NAKED void __stdcall
#define ALCFAST EXTERNC EXPORT NAKED void __fastcall
#define ALCDECL EXTERNC NAKED void __cdecl
// 导出函数
#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=_My_GetFileVersionInfoA,@1")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoByHandle=_My_GetFileVersionInfoByHandle,@2")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoExW=_My_GetFileVersionInfoExW,@3")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeA=_My_GetFileVersionInfoSizeA,@4")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExW=_My_GetFileVersionInfoSizeExW,@5")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeW=_My_GetFileVersionInfoSizeW,@6")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoW=_My_GetFileVersionInfoW,@7")
#pragma comment(linker, "/EXPORT:VerFindFileA=_My_VerFindFileA,@8")
#pragma comment(linker, "/EXPORT:VerFindFileW=_My_VerFindFileW,@9")
#pragma comment(linker, "/EXPORT:VerInstallFileA=_My_VerInstallFileA,@10")
#pragma comment(linker, "/EXPORT:VerInstallFileW=_My_VerInstallFileW,@11")
#pragma comment(linker, "/EXPORT:VerLanguageNameA=_My_VerLanguageNameA,@12")
#pragma comment(linker, "/EXPORT:VerLanguageNameW=_My_VerLanguageNameW,@13")
#pragma comment(linker, "/EXPORT:VerQueryValueA=_My_VerQueryValueA,@14")
#pragma comment(linker, "/EXPORT:VerQueryValueW=_My_VerQueryValueW,@15")
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include "MyExport.h"
//全局变量
HMODULE g_hModule = NULL;
DWORD g_dwReturn[15] = {0};
#pragma intrinsic(strcat,memcmp,memcpy)
#pragma comment(linker, "/entry:DllMain")
#pragma comment(lib,"User32.lib")
FARPROC WINAPI GetAddress(PCSTR pszProcName);
BOOL WINAPI Load();
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hModule);
if (!Load())return FALSE;
}
break;
case DLL_PROCESS_DETACH:
{
if (g_hModule)
{
FreeLibrary(g_hModule);
g_hModule=NULL;
}
}
break;
case DLL_THREAD_ATTACH:{}break;
case DLL_THREAD_DETACH:{}break;
}
return TRUE;
}
FARPROC WINAPI GetAddress(PCSTR pszProcName)
{
FARPROC fpAddress=NULL;
if( (fpAddress = GetProcAddress(g_hModule, pszProcName) ) != NULL)
return fpAddress;
ExitProcess(1);
}
//加载原始模块
__inline BOOL WINAPI Load()
{
TCHAR tzPath[MAX_PATH] = {0};
GetSystemDirectory(tzPath, MAX_PATH); //未测试64位系统, 64位系统下32位dll实际在wow64目录下
_tcscat_s(tzPath, TEXT("\\version.dll"));
if ( ( g_hModule = LoadLibrary(tzPath) ) == NULL )
return FALSE;
return TRUE;
}
// 导出函数
ALCDECL My_GetFileVersionInfoA(void)
{
// 保存返回地址
__asm POP g_dwReturn[0 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoA")();
// 转跳到返回地址
__asm JMP g_dwReturn[0 * TYPE long]; //返回函数
}
// 导出函数
ALCDECL My_GetFileVersionInfoByHandle(void)
{
// 保存返回地址
__asm POP g_dwReturn[1 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoByHandle")();
// 转跳到返回地址
__asm JMP g_dwReturn[1 * TYPE long];
}
// 导出函数
ALCDECL My_GetFileVersionInfoExW(void)
{
// 保存返回地址
__asm POP g_dwReturn[2 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoExW")();
// 转跳到返回地址
__asm JMP g_dwReturn[2 * TYPE long];
}
// 导出函数
ALCDECL My_GetFileVersionInfoSizeA(void)
{
// 保存返回地址
__asm POP g_dwReturn[3 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoSizeA")();
劫持这个函数试试
//GetAddress("GetFileVersionInfoSizeA")();
//_asm
//{
// mov eax,0x1234
//}
// 转跳到返回地址
__asm JMP g_dwReturn[3 * TYPE long];
}
// 导出函数
ALCDECL My_GetFileVersionInfoSizeExW(void)
{
// 保存返回地址
__asm POP g_dwReturn[4 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoSizeExW")();
// 转跳到返回地址
__asm JMP g_dwReturn[4 * TYPE long];
}
// 导出函数
ALCDECL My_GetFileVersionInfoSizeW(void)
{
// 保存返回地址
__asm POP g_dwReturn[5 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoSizeW")();
// 转跳到返回地址
__asm JMP g_dwReturn[5 * TYPE long];
}
// 导出函数
ALCDECL My_GetFileVersionInfoW(void)
{
// 保存返回地址
__asm POP g_dwReturn[6 * TYPE long];
// 调用原始函数
GetAddress("GetFileVersionInfoW")();
// 转跳到返回地址
__asm JMP g_dwReturn[6 * TYPE long];
}
// 导出函数
ALCDECL My_VerFindFileA(void)
{
// 保存返回地址
__asm POP g_dwReturn[7 * TYPE long];
// 调用原始函数
GetAddress("VerFindFileA")();
// 转跳到返回地址
__asm JMP g_dwReturn[7 * TYPE long];
}
// 导出函数
ALCDECL My_VerFindFileW(void)
{
// 保存返回地址
__asm POP g_dwReturn[8 * TYPE long];
// 调用原始函数
GetAddress("VerFindFileW")();
// 转跳到返回地址
__asm JMP g_dwReturn[8 * TYPE long];
}
// 导出函数
ALCDECL My_VerInstallFileA(void)
{
// 保存返回地址
__asm POP g_dwReturn[9 * TYPE long];
// 调用原始函数
GetAddress("VerInstallFileA")();
// 转跳到返回地址
__asm JMP g_dwReturn[9 * TYPE long];
}
// 导出函数
ALCDECL My_VerInstallFileW(void)
{
// 保存返回地址
__asm POP g_dwReturn[10 * TYPE long];
// 调用原始函数
GetAddress("VerInstallFileW")();
// 转跳到返回地址
__asm JMP g_dwReturn[10 * TYPE long];
}
// 导出函数
ALCDECL My_VerLanguageNameA(void)
{
// 保存返回地址
__asm POP g_dwReturn[11 * TYPE long];
// 调用原始函数
GetAddress("VerLanguageNameA")();
// 转跳到返回地址
__asm JMP g_dwReturn[11 * TYPE long];
}
// 导出函数
ALCDECL My_VerLanguageNameW(void)
{
// 保存返回地址
__asm POP g_dwReturn[12 * TYPE long];
// 调用原始函数
GetAddress("VerLanguageNameW")();
// 转跳到返回地址
__asm JMP g_dwReturn[12 * TYPE long];
}
// 导出函数
ALCDECL My_VerQueryValueA(void)
{
// 保存返回地址
__asm POP g_dwReturn[13 * TYPE long];
// 调用原始函数
GetAddress("VerQueryValueA")();
// 转跳到返回地址
__asm JMP g_dwReturn[13 * TYPE long];
}
// 导出函数
ALCDECL My_VerQueryValueW(void)
{
// 保存返回地址
__asm POP g_dwReturn[14 * TYPE long];
// 调用原始函数
GetAddress("VerQueryValueW")();
// 转跳到返回地址
__asm JMP g_dwReturn[14 * TYPE long];
}