Detours模拟

#include "stdafx.h"



#include<shlobj.h>



#define GET_VIRTUAL_FROM_EXPORT(fun,offset) /

(DWORD*)((DWORD)((ULONG)(fun) + (ULONG)( *(ULONG*)((BYTE*)(fun) + 1) ) + 5 + (offset)))



void StartDetour();



void StopDetour();







#pragma data_seg(".WXW")



HHOOK hhook = NULL;   // a handle of hook



#pragma data_seg()



#pragma comment(linker,"/section:.WXW,rws")







HANDLE g_hInstance = NULL;







BYTE JmpInstruction[5] = {0xe9};//CallTargetJmp2Detour



DWORD *posJmpOffset = NULL;//Back2TargetOffset



BYTE OldInstruction[5];







// 该函数共16个字节



extern "C" __declspec(dllexport) int __declspec(naked) Trampoline(){



	__asm{



		mov edi,edi



		push ebp



		mov ebp,esp



		;下5个字节被插入的跳转指令覆盖,然后就跳转了



		nop



		nop



		nop



		nop



		nop



		xor eax,eax



		pop esp



		ret 0x10



	}



}







extern "C" __declspec(dllexport) int WINAPI DetourSHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)



{



    int rets = 0;



	// 在调用目标函数之前做些操作



	MessageBox(NULL, "Start", "notice", MB_OK);







    // 跳到Trampoline



	_asm{



		push options



		push fmtID



		push drive



		push hwnd



		lea eax, Trampoline



		call eax



		mov dword ptr [rets], eax



    }







	// 目标函数返回后做一些操作



	MessageBox(NULL, "Finish", "notice", MB_OK);



	//StopDetour();



    return rets;



}







void StartDetour()



{



	DWORD dwOld;







	posJmpOffset = (DWORD *)(JmpInstruction + 1);



	// "DetourSHFormatDrive"是钩子函数的导出项跳转指令地址,"SHFormatDrive"是格式化函数首指令地址.



	*posJmpOffset = DWORD((ULONG)DetourSHFormatDrive - (ULONG)SHFormatDrive - 5);



	VirtualProtect(SHFormatDrive, 5, PAGE_EXECUTE_READWRITE, &dwOld);



	memcpy(OldInstruction,SHFormatDrive,5);



	WriteProcessMemory(GetCurrentProcess() , SHFormatDrive, JmpInstruction, 5, &dwOld);



	VirtualProtect(SHFormatDrive, 5, dwOld, NULL);







	VirtualProtect(Trampoline, 16, PAGE_EXECUTE_READWRITE, &dwOld);



	// "Trampoline"是跳板函数导出项跳转指令地址.



	// 对Trampoline偏移6字节处的双字修改为真正的跳板返回跳转偏移



	posJmpOffset = (DWORD *)(JmpInstruction + 1);



	// 将跳转偏移清零



	memset(posJmpOffset, 0, 4);



	WriteProcessMemory(GetCurrentProcess() ,GET_VIRTUAL_FROM_EXPORT(Trampoline,5), JmpInstruction, 5, &dwOld);







	*posJmpOffset = DWORD((DWORD)SHFormatDrive + 5 - (DWORD)GET_VIRTUAL_FROM_EXPORT(Trampoline,10));



	WriteProcessMemory(GetCurrentProcess() ,GET_VIRTUAL_FROM_EXPORT(Trampoline,5), JmpInstruction, 5, &dwOld);



	VirtualProtect(Trampoline, 16, dwOld, NULL);



}







void StopDetour()



{



	DWORD dwOld;



	VirtualProtect(SHFormatDrive, 5, PAGE_EXECUTE_READWRITE, &dwOld);



	WriteProcessMemory(GetCurrentProcess() , SHFormatDrive, OldInstruction, 5, &dwOld);



	VirtualProtect(SHFormatDrive, 5, dwOld, NULL);



}







LRESULT CALLBACK MyShellProc (int nCode, WPARAM wParam, LPARAM lParam){



	return CallNextHookEx(hhook, nCode, wParam, lParam);



}







extern"C" __declspec( dllexport ) BOOL InstallHook(){



	hhook = ::SetWindowsHookEx( WH_GETMESSAGE , MyShellProc ,(HINSTANCE)g_hInstance, 0);



	if(hhook != NULL){



		return TRUE;



	}



	return FALSE;



}







extern"C" __declspec( dllexport ) void UninstallHook(){



	if(hhook != NULL){



		UnhookWindowsHookEx(hhook);



		hhook = NULL;



	}



}







BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )



{



	//OutputDebugString("dllmain...");



	//__asm int 3



	g_hInstance = hModule;







	switch (ul_reason_for_call){



	case DLL_PROCESS_ATTACH:



		StartDetour();



		break;



	case DLL_THREAD_ATTACH:



		break;



	case DLL_THREAD_DETACH:



		break;



	case DLL_PROCESS_DETACH:



		break;



	}



	return TRUE;



}



建立远线程将该DLL导入目标线程,也可以调用InstallHook()用全局消息钩子载入,导入后会执行StartDetour()
将格式化操作拦截,这里只是简单的在格式化之前和之后加入一个对话框。

补充一点,在系统开了数据执行保护(DEP)的时候,若通过远程线程注入,必须将跳板函数和钩子函数导出,若系统有修改系统函数的IAT,则可以通过全局消息钩子注入。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值