安全的交互通道 及 栈回塑检查与伪造

第四章:安全的交互通道
消息钩子,Hook游戏消息处理过程,GetKeyState(),GetAsyncKeyState()和GetKeyBoardState()函数,进程间通信。
消息钩子:SetWindowsHookEx(),UnhookWindowsHookEx()
Hook游戏消息处理过程:GetWindowLong(),SetWindowLong()
GetKeyState(),GetAsyncKeyState()和GetKeyBoardState()函数:容易Hook检测到。
 按键->键盘驱动捕捉这个中断转为Virtual Key Code -> I/O管理器装成IRP(中断请求包)->OS组装VK_XX为WM_CHAR.
 GetKeyState,GetKeyBoardState两个在消息过程(此时状态才会变)中使用前者取一个,后者取所有的。
 GetAsyncKeyState其返回值内容,最高位表示是否按下,最低位表示上次调用此函数后,这个按键是否按下。

 

栈回塑检查就是检查返回地址是否合法,伪造就是push一个伪造的栈帧进去。

game.exe  游戏映像
normal.dll  游戏功能模块

invader.dll 非法模块

//game.exe
#include "normaldll\normaldll.h"
#include "invader\invader.h"
#include <vector>
#include <Windows.h>
using namespace std;

vector<int> vecAddr;

int ebpret[6][2] = { 0 };

void fun1()
{
	__asm{
		push eax
		push ebx
		push ecx
		lea eax, [ebpret]
		mov [eax], ebp
		mov ecx, ebp
		add ecx, 4
		mov ebx, [ecx]
		add eax, 4
		mov [eax], ebx
		pop ecx
		pop ebx
		pop eax
	}

	for(int i = 0; i < 6; ++i)
	{
		printf("ebp:%08x   retaddr:%08x \n",ebpret[i][0],ebpret[i][1]);
	}
	fnnormaldll();
}
void fun2()
{
	__asm{
		push eax
		push ebx
		push ecx
		lea eax, [ebpret]
		add eax, 8
		mov [eax], ebp
		mov ecx, ebp
		add ecx, 4
		mov ebx, [ecx]
		add eax, 4
		mov [eax], ebx
		pop ecx
		pop ebx
		pop eax
	}
	fun1();
}
void fun3()
{
	__asm{
		push eax
		push ebx
		push ecx
		lea eax, [ebpret]
		add eax, 0x10
		mov [eax], ebp
		mov ecx, ebp
		add ecx, 4
		mov ebx, [ecx]
		add eax, 4
		mov [eax], ebx
		pop ecx
		pop ebx
		pop eax
	}
	fun2();
}

void fun4()
{
	__asm{
		push eax
		push ebx
		push ecx
		lea eax, [ebpret]
		add eax, 0x18
		mov [eax], ebp
		mov ecx, ebp
		add ecx, 4
		mov ebx, [ecx]
		add eax, 4
		mov [eax], ebx
		pop ecx
		pop ebx
		pop eax
	}
	fun3();
}

void main()
{
	HMODULE baseAddr = GetModuleHandle(L"testFakeStackFrames.exe");
	nnormaldll = (int)baseAddr;
	ninvader = (int)baseAddr;

	ninvader = (int)baseAddr;
	fninvader();
	__asm{
		push eax
		push ebx
		push ecx
		lea eax, [ebpret]
		add eax, 0x20
		mov [eax], ebp
		mov ecx, ebp
		add ecx, 4
		mov ebx, [ecx]
		add eax, 4
		mov [eax], ebx
		pop ecx
		pop ebx
		pop eax
	}
	fun4();

	while(true)
	{
		Sleep(1000);
	}
}


 

//normal.dll
// normaldll.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "normaldll.h"
#include <string>

// This is an example of an exported variable
NORMALDLL_API int nnormaldll=0;

int ebpretdll[6][2] = { 0 };

bool CheckStackFrame()
{
	int bRet = 0;
	__asm
	{
		push eax
		push ebx
		push ecx
		push edx
		push edi
		push ebp

		lea edx, [ebpretdll]
		mov ebx, nnormaldll
		mov ecx, 5
label:
		mov [edx], ebp
		add edx, 4
		mov ebx, ebp
		add ebx, 4
		mov edi, [ebx]
		mov [edx],edi
		add edx, 4

		mov edi, [ebp]
		mov ebp, edi

		dec ecx
		jge label

		pop ebp
		pop edi
		pop edx
		pop ecx
		pop ebx
		pop eax
	}
	printf("EXE Baseaddr:%08x\n follow is check statck info:\n",nnormaldll);
	for(int i = 0; i < 6; ++i)
	{
		printf("ebp:%08x   retaddr:%08x \n",ebpretdll[i][0],ebpretdll[i][1]);
	}
	return bRet;
}
// This is an example of an exported function.
NORMALDLL_API int fnnormaldll(void)
{
	CheckStackFrame();
	wchar_t buf[100] = { 0 };
	wsprintfW(buf,L"EXE address:%08x, current dll address:%08x",nnormaldll,GetModuleHandle(L"normaldll.dll"));
	MessageBoxW(NULL,buf, L"normal dll caption", MB_OK);
	return 42;
}

// This is the constructor of a class that has been exported.
// see normaldll.h for the class definition
Cnormaldll::Cnormaldll()
{
	return;
}


 

//invader.dll
// invader.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "invader.h"
#include <windows.h>
#include <stdio.h>
#include <process.h>

#include "..\normaldll\normaldll.h"

// This is an example of an exported variable
INVADER_API int ninvader=0;

HANDLE g_event = NULL;
typedef int (*PFUN)(void);
DWORD fakestack[20] = { 0 };
DWORD addr = 0;

_declspec (naked) void fakeframe(DWORD funaddr,DWORD fakestack)
{
	__asm{
		mov edi, edi
		push ebp
		mov ebp, esp

		push eax
		push ebx
		//push ebp
		mov eax, addr
		add eax,18*4
		mov ebx, [ebp]
		mov [eax], ebx
		add eax,4
		mov [eax], esp
		
		jmp PUSH_REAL_RET_ADDR
FUN:
		push 0x771f000a		;//ret

		mov eax, ebp
		mov ebx, addr
		mov [eax],ebx

		mov eax, funaddr
		jmp eax
PUSH_REAL_RET_ADDR:
		call FUN
		mov eax, addr
		add eax,19*4
		mov esp, [eax]
		sub eax, 4
		mov ebx, [eax]
		mov [ebp], ebx

		pop ebx
		pop eax

		mov esp, ebp
		pop ebp
		ret 8
	}
}

void hah1()
{
	for(int i = 0; i< 20; )
	{
		fakestack[i] = (DWORD)&fakestack[i+2];
		fakestack[i+1] = 0x00000021;
		i += 2;
	}
	HMODULE hnormaldll = GetModuleHandleW(L"C:\\test\\testFakeStackFrames\\Debug\\normaldll.dll");
	PFUN p = (PFUN)GetProcAddress(hnormaldll,"?fnnormaldll@@YAHXZ");
	//nnormaldll = (int)GetModuleHandle(L"invader.dll");
	addr = (DWORD)&fakestack;
	fakeframe((DWORD)p,addr);
}
void hah2()
{
	hah1();
}
void hah3()
{
	hah2();
}
void hah4()
{
	hah3();
}

unsigned __stdcall start_address( void * pa )
{
	g_event = CreateEventW(NULL,FALSE,FALSE,L"SNOWMAN");
	printf("11111\n");
	WaitForSingleObject( g_event, INFINITE );

	hah4();
	while(true)
	{
		printf("dddddddddddddd\n");
		Sleep(1000);
	}
	_endthreadex( 0 );
	return 0;
}


// This is an example of an exported function.
INVADER_API int fninvader(void)
{
	HANDLE hthread = (HANDLE)_beginthreadex(NULL,0,&start_address,NULL,0,NULL);
	//Sleep(3000);
	//hah4();
	return 42;
}

// This is the constructor of a class that has been exported.
// see invader.h for the class definition
Cinvader::Cinvader()
{
	return;
}


 

//trigeror
#include <windows.h>
#include <stdio.h>
#include <process.h>

void main()
{
	HANDLE g_event = CreateEventW(NULL,FALSE,FALSE,L"SNOWMAN");
	if(GetLastError() == ERROR_ALREADY_EXISTS)
	{
		printf(" OK is exist, only triger\n");
		SetEvent(g_event);
	}
}


测试结果:

normal.dll调用时栈如下:

非法调用时的栈:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值