/// @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;
}