简单之检测函数返回地址是否合法(控制流防护的缺陷)

#include "stdafx.h"

#pragma pack(1)

typedef struct _FUNCTION_RETURN_INFO {
	ULONG_PTR lEspAddress;
	ULONG_PTR lReturnAddress;
} FUNCTION_RETURN_INFO, *PFUNCTION_RETURN_INFO;

#pragma pack()


static PFUNCTION_RETURN_INFO g_lpFunctionReturnInfo = NULL;

static bool _cdecl InintCheckReturnCount(size_t uFunctionCount)
{
	const size_t uMallocSize = uFunctionCount * sizeof(FUNCTION_RETURN_INFO);

	g_lpFunctionReturnInfo = (PFUNCTION_RETURN_INFO)malloc(uMallocSize);

	if (NULL == g_lpFunctionReturnInfo)
		return false;
	memset(g_lpFunctionReturnInfo, 0, uMallocSize);
	return true;
}

static void _cdecl PushReturnInfo(DWORD dwFunctionIndex, ULONG_PTR lEspAddress)
{
	if (0U == g_lpFunctionReturnInfo[dwFunctionIndex].lReturnAddress)
	{
		CONST UCHAR * lpFunctionPtr = (CONST UCHAR *)
			*PULONG_PTR(lEspAddress - (sizeof(ULONG_PTR) * 2U + sizeof(DWORD)));

		g_lpFunctionReturnInfo[dwFunctionIndex].lEspAddress = lEspAddress;

		lpFunctionPtr = lpFunctionPtr + 3U; do {
			if (0x0E8 == *lpFunctionPtr)
			{
				g_lpFunctionReturnInfo[dwFunctionIndex].lReturnAddress = (ULONG_PTR)&lpFunctionPtr[5];
				return;
			}
			else if (0x15FF == *PUSHORT(lpFunctionPtr))
			{
				g_lpFunctionReturnInfo[dwFunctionIndex].lReturnAddress = (ULONG_PTR)&lpFunctionPtr[6];
				return;
			}
		} while (++lpFunctionPtr);
	}
}

static void _cdecl CheckReturnAddress(DWORD dwFunctionIndex, DWORD dwParamSize)
{
	register ULONG_PTR lCurReturnAddress = 0U;

	lCurReturnAddress = *PULONG_PTR(
		g_lpFunctionReturnInfo[dwFunctionIndex].lEspAddress - (sizeof(ULONG_PTR) + dwParamSize)
		);

	if (g_lpFunctionReturnInfo[dwFunctionIndex].lReturnAddress != lCurReturnAddress)
	{
		_asm INT 0x03;
	}
}

#define  _ININTCR(c) InintCheckReturnCount((c))

#define _CRBEGIN(i) \
		_asm push esp \
		_asm push (i) \
		_asm call PushReturnInfo \
		_asm add esp, 0x08

#define _CREND(i) \
		_asm push dwParamSize \
		_asm push (i) \
		_asm call CheckReturnAddress \
		_asm add esp, 0x08

#define _CRPARAM register DWORD dwParamSize = 

#define _FCRS(p) sizeof((p))
#define _NCRS(p) + sizeof((p))

enum _function_name_index {
	add_number_index,
	sub_number_index
};

int _cdecl add_number(int x, int y);

int _cdecl add_number(int x, int y)
{
	/*
	函数内容部分;
	......
	*/
	//只需定义在函数结尾处的return之上即可
	_CRPARAM(_FCRS(x)_NCRS(y));  //该函数所有参数大小和
	_CREND(add_number_index);
	return (x + y);
}

int main()
{
	_ININTCR(2U);
	_CRBEGIN(add_number_index); //必须放在检测函数之前
	add_number(1, 1);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL提供了几个控制函数,可以用于在查询中实现控制。其中包括IF函数、CASE函数和NULLIF函数。下面我将为你详细介绍这些函数的用法。 1. IF函数: IF函数是一种简单控制函数,可以根据条件的真假返回不同的值。它的语法如下: IF(condition, value_if_true, value_if_false) 其中,condition是一个条件表达式,如果该条件为真,则返回value_if_true;如果条件为假,则返回value_if_false。 2. CASE函数: CASE函数是一种更灵活的控制函数,可以根据多个条件的不同结果返回不同的值。它分为两种形式:简单CASE函数和搜索CASE函数简单CASE函数的语法如下: CASE expression WHEN value1 THEN result1 WHEN value2 THEN result2 ... ELSE result END 其中,expression是要比较的表达式,value1、value2等是待比较的值,result1、result2等是对应值的返回结果,ELSE子句是当没有匹配的值时返回的默认结果。 搜索CASE函数的语法如下: CASE WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... ELSE result END 其中,condition1、condition2等是待判断的条件,result1、result2等是对应条件为真时的返回结果,ELSE子句是当没有条件为真时返回的默认结果。 3. NULLIF函数: NULLIF函数可以比较两个表达式的值,如果两个值相等,则返回NULL;如果不相等,则返回第一个表达式的值。它的语法如下: NULLIF(expression1, expression2) 其中,expression1和expression2是要比较的两个表达式。 综上所述,IF函数可以根据条件的真假返回不同的值,CASE函数可以根据多个条件的不同结果返回不同的值,NULLIF函数可以比较两个表达式的值并返回不同的结果。这些控制函数可以帮助你在MySQL编程中实现控制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值