用模式地址原理,隐藏数据


/// @file exam_1_2.c
/// @brief exam_1_2 * 用模式地址原理,隐藏数据的实验

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif

#ifndef INOUT
#define INOUT
#endif

void fnUseModeAddressHideInfo();
BOOL encryptBytesDataToModeAddr(
							 IN unsigned char cByteContent,
							 INOUT void** ppAddrBits76,
							 INOUT void** ppAddrBits54,
							 INOUT void** ppAddrBits32,
							 INOUT void** ppAddrBits10);

BOOL decryptBytesDataToModeAddr(
							 OUT unsigned char* pcByteContent,
							 INOUT void** ppAddrBits76,
							 INOUT void** ppAddrBits54,
							 INOUT void** ppAddrBits32,
							 INOUT void** ppAddrBits10);

void* GetModeAddrPointer(IN void* pAddrBits76);

int main(int argc, char** argv)
{
    fnUseModeAddressHideInfo();

    printf("END, press any key to quit\n");
    getchar();
    
    return 0;
}

/// 在每个变量模式地址上隐藏2bits数据
void fnUseModeAddressHideInfo()
{
	char cTmp = 0;
	int iTmp = 0;
	float fTmp = 0;
	double dblTmp = 0;
	unsigned char ucData = 0;

	void* pBit76 = NULL;
	void* pBit54 = NULL;
	void* pBit32 = NULL;
	void* pBit10 = NULL;

	srand(time(NULL));

	/// 不关心数据的值, 只要这些值在隐藏数据后,不被改变即可
	cTmp = rand() % 127; ///< char数据范围 0 ~ 128
	iTmp = rand();
	fTmp = 1.0f * rand() / 100;
	dblTmp = 1.0 * rand() / 100;
	// ucData = rand() % 0xff;
	ucData = 0x5A;
	// ucData = 0xA5;

	pBit76 = &cTmp;
	pBit54 = &iTmp;
	pBit32 = &fTmp;
	pBit10 = &dblTmp;

	/// 打印变量原值
	printf("original : cTmp is %p\n", cTmp);
	printf("original : iTmp is %p\n", iTmp);
	printf("original : fTmp is %p\n", fTmp);
	printf("original : dblTmp is %p\n", dblTmp);

	/// 打印要隐藏的数据
	printf("ucData = %p, encrypt...\n", ucData);

	/// 加密
	encryptBytesDataToModeAddr(
		ucData, 
		&pBit76, 
		&pBit54, 
		&pBit32, 
		&pBit10);

	/// 保证变量值不变
	printf("after enc : cTmp is %p\n", cTmp);
	printf("after enc : iTmp is %p\n", iTmp);
	printf("after enc : fTmp is %p\n", fTmp);
	printf("after enc : dblTmp is %p\n", dblTmp);

	/// 解密
	ucData = ucData + 13; ///< 先打乱ucData, 可以验证解密后的值是否为ucData原值
	decryptBytesDataToModeAddr(
		&ucData, 
		&pBit76, 
		&pBit54, 
		&pBit32, 
		&pBit10);

	printf("ucData = %p, decrypt over\n", ucData);

	/// 保证变量值不变
	printf("cTmp is %p\n", cTmp);
	printf("iTmp is %p\n", iTmp);
	printf("fTmp is %p\n", fTmp);
	printf("dblTmp is %p\n", dblTmp);

	/// 用指针取变量值
	printf("use pt get cTmp is %p\n", *((char*)GetModeAddrPointer(pBit76)));
	printf("use pt get iTmp is %p\n", *((int*)GetModeAddrPointer(pBit54)));
	printf("use pt get fTmp is %p\n", *((float*)GetModeAddrPointer(pBit32)));
	printf("use pt get dblTmp is %p\n", *((double*)GetModeAddrPointer(pBit10)));

	/** run result
	original : cTmp is 00000057
	original : iTmp is 00002CDD
	original : fTmp is C0000000
	original : dblTmp is 147AE148
	ucData = 000000A5, encrypt...
	after enc : cTmp is 00000057
	after enc : iTmp is 00002CDD
	after enc : fTmp is C0000000
	after enc : dblTmp is 147AE148
	ucData = 000000A5, decrypt over
	cTmp is 00000057
	iTmp is 00002CDD
	fTmp is C0000000
	dblTmp is 147AE148
	use pt get cTmp is 00000057
	use pt get iTmp is 00002CDD
	use pt get fTmp is C0000000
	use pt get dblTmp is 147AE148
	*/
}

BOOL encryptBytesDataToModeAddr(
								IN unsigned char cByteContent,
								INOUT void** ppAddrBits76,
								INOUT void** ppAddrBits54,
								INOUT void** ppAddrBits32,
								INOUT void** ppAddrBits10)
{
	BOOL bRc = FALSE;
	unsigned int iAddr = 0;
	unsigned int iDataTmp = 0;

	do 
	{
		if (((NULL == ppAddrBits76) || (NULL == *ppAddrBits76))
			|| ((NULL == ppAddrBits54) || (NULL == *ppAddrBits54))
			|| ((NULL == ppAddrBits32) || (NULL == *ppAddrBits32))
			|| ((NULL == ppAddrBits10) || (NULL == *ppAddrBits10)))
		{
			break;
		}

		/// save bit76 to addr
		iDataTmp = ((cByteContent >> 6) & 0x3);
		iAddr = (unsigned int)(*(unsigned int**)ppAddrBits76);
		iAddr = iAddr & 0xFFFFFFFC;
		iAddr |= iDataTmp;
		*(unsigned int**)ppAddrBits76 = (unsigned int *)iAddr;

		/// save bit54 to addr
		iDataTmp = ((cByteContent >> 4) & 0x3);
		iAddr = (unsigned int)(*(unsigned int**)ppAddrBits54);
		iAddr = iAddr & 0xFFFFFFFC;
		iAddr |= iDataTmp;
		*(unsigned int**)ppAddrBits54 = (unsigned int *)iAddr;

		/// save bit32 to addr
		iDataTmp = ((cByteContent >> 2) & 0x3);
		iAddr = (unsigned int)(*(unsigned int**)ppAddrBits32);
		iAddr = iAddr & 0xFFFFFFFC;
		iAddr |= iDataTmp;
		*(unsigned int**)ppAddrBits32 = (unsigned int *)iAddr;

		/// save bit10 to addr
		iDataTmp = (cByteContent & 0x3);
		iAddr = (unsigned int)(*(unsigned int**)ppAddrBits10);
		iAddr = iAddr & 0xFFFFFFFC;
		iAddr |= iDataTmp;
		*(unsigned int**)ppAddrBits10 = (unsigned int *)iAddr;

		bRc = TRUE;
	} while (0);

	return bRc;
}

BOOL decryptBytesDataToModeAddr(
								OUT unsigned char* pcByteContent,
								INOUT void** ppAddrBits76,
								INOUT void** ppAddrBits54,
								INOUT void** ppAddrBits32,
								INOUT void** ppAddrBits10)
{
	BOOL bRc = FALSE;
	unsigned int iAddr = 0;
	unsigned int iDataTmp = 0;
	
	do 
	{
		if ((NULL == pcByteContent)
			|| ((NULL == ppAddrBits76) || (NULL == *ppAddrBits76))
			|| ((NULL == ppAddrBits54) || (NULL == *ppAddrBits54))
			|| ((NULL == ppAddrBits32) || (NULL == *ppAddrBits32))
			|| ((NULL == ppAddrBits10) || (NULL == *ppAddrBits10)))
		{
			break;
		}
		
		*pcByteContent = 0;

		/// get bit76 to addr
		iDataTmp = (unsigned int)(*ppAddrBits76) & 0x3;
		*pcByteContent |= (iDataTmp << 6);
		
		/// get bit54 to addr
		iDataTmp = (unsigned int)(*ppAddrBits54) & 0x3;
		*pcByteContent |= (iDataTmp << 4);
		
		/// get bit32 to addr
		iDataTmp = (unsigned int)(*ppAddrBits32) & 0x3;
		*pcByteContent |= (iDataTmp << 2);
		
		/// get bit10 to addr
		iDataTmp = (unsigned int)(*ppAddrBits10) & 0x3;
		*pcByteContent |= iDataTmp;

		bRc = TRUE;
	} while (0);

	return bRc;
}

void* GetModeAddrPointer(IN void* pAddrBits76)
{
	void* pRc = NULL;

	do 
	{
		if (NULL == pAddrBits76)
		{
			break;
		}

		pRc = (unsigned int*)((unsigned int)pAddrBits76 & (~3));
	} while (0);

	return pRc;
}


阅读更多
个人分类: C
上一篇函数指针的基本用法
下一篇用函数指针代替switch-case
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭