躲猫猫,用inline hook来进行验证

Hook是一个非常强大的技巧,利用Hook,不仅可以起到监控进程,做自己想做的事,而且可以利用hook来进行一些check。

给出下面的main函数:

#include <stdio.h>
#include <Windows.h>
#pragma warning(disable:4996)

//key : ccaaa
int main()
{
	char s[256] = "\0";
	if (NULL == LoadLibrary(L"F:\\桌面\\c语言\\HOOK_DLLLL\\Debug\\HOOK_DLLLL.dll")) {
		printf("%d\n", GetLastError());
	}
	printf("input key : ");
	scanf("%s", s);

	MessageBoxW(0, L"win", L"yingyingying", MB_OK);

	return 0;
}

例如我们可以Hook MessageBoxW,并将验证藏在MessageBoxW中,让它跟MessageBox的第一个参数的值挂钩,相应的dll代码如下:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

typedef int(*TYPE_MessageBox)(HWND, LPCWSTR, LPCWSTR, UINT);
typedef void(*MyHookProc)();
WCHAR *lose = L"lose";
WCHAR *fail = L"fail";
BYTE temp[5];
TYPE_MessageBox  funcAddr;

void RestoreHook()
{
	int i;

	for (i = 0; i < 5; i++) {
		*((unsigned char *)funcAddr + i) = temp[i];
	}
}

_declspec(naked) void MyHook()
{
	_asm {//[ebp + 8]
		push ebp
		mov ebp, esp
		mov eax, [ebp + 8] //get HWND
		cmp eax, 1
		je success	//if success
		mov eax, lose //替换第二个参数
		mov [ebp + 12], eax //替换第三个参数
		mov eax, fail
		mov [ebp + 16], eax
	success :
		mov [ebp + 8], 0	//清零(NULL) 因为我们实际上并没有指定任何handle
		call RestoreHook	//恢复原本的MessageBoxW
		mov esp,ebp
		pop ebp
		mov eax,funcAddr
		jmp eax			//跳到原本的函数执行
	}
}

void MyHookMessageBox()
{
	HMODULE hProc = NULL;
	WCHAR *libName = L"user32.dll";
	BYTE code[5] = {0xE9 };
	DWORD oldProtect;

	hProc = GetModuleHandle((LPCWSTR)libName);
	if (!hProc) {
		printf("%d\n", GetLastError());
	}
	funcAddr = (TYPE_MessageBox)GetProcAddress(hProc, "MessageBoxW");//获得函数地址

	memcpy(temp, (void *)funcAddr, 5 * sizeof(BYTE));//保存原本
	*((int *)(code + 1)) = (int)MyHook - (int)funcAddr - 5;//这里的jmp是相对跳转 不好理解的可以动手算一下
	VirtualProtect(funcAddr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);//代码页赋予写权限 因为我们要memcpy
	memcpy(funcAddr, code, 5 * sizeof(BYTE));
	VirtualProtect(funcAddr, 5, oldProtect, NULL);//恢复之前的页属性
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		MyHookMessageBox();
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

当我们运行程序时,正常来说应该是显示yingyingying的,但是被hook之后显示出了这个。
在这里插入图片描述
所以需要将主函数的MessageBoxW的第一个参数改为1。
在这里插入图片描述

其实我们可以在dll里再放置一个计数器;并在主函数里任意隐蔽位置执行n个MessageBox进行混淆和一个最终的验证flag值以用于最终验证,每调用一次MessageBox就增加一次计数器,我们可以自定义到达哪个值,会进行一次hook验证,如果不符合,最终的flag值就为false,然后恢复原本的MessageBoxW,接着正常执行,直到最后验证。我这里就简单的提示一下,等鄙人有时间再完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值