#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;
}
简单之检测函数返回地址是否合法(控制流防护的缺陷)
最新推荐文章于 2021-03-27 09:03:28 发布