该文介绍了如何使用指针中一些未使用的位来隐藏一些数据。

When we write C code, pointers are everywhere. We can make a little extra use of pointers and sneak in some extra information in them. To pull this trick off, we exploit the natural alignment of data in memory.

Data in memory is not stored at any arbitrary address. The processor always reads memory in chunks at the same size as its word size; and thus for efficiency reasons, the compiler assigns addresses to entities in memory as multiples of their size in bytes. Therefore on a 32 bit processor, a 4-byte int will definitely reside at a memory address that is evenly divisible by 4.

Here, I am going to assume a system where size of int and size of pointer are 4 bytes.

Now let us consider a pointer to an int. As said above, the int can be located at memory addresses 0x1000 or 0x1004 or 0x1008, but never at 0x1001 or 0x1002 or 0x1003 or any other address that is not divisible by 4.
Now, any binary number which is a multiple of 4 will end with 00.
This essentially means that for any pointer to an int, its 2 lower order bits are always zero.

Now we have 2 bits which communicate nothing. The trick here is put our data into these 2 bits, use them whenever we want and then remove them before we make any memory access by dereferencing the pointer.

Since bitwise operations on pointers don’t go well with the C standard, We will be storing the pointer as an unsigned int.

The following is a naive snippet of the code for brevity. See my github repo - hide-data-in-ptr for the full code.

void put_data(int *p, unsigned int data)
{
assert(data < );
*p |= data;
} unsigned int get_data(unsigned int p)
{
return (p & );
} void cleanse_pointer(int *p)
{
*p &= ~;
} int main(void)
{
unsigned int x = ;
unsigned int p = (unsigned int) &x; printf("Original ptr: %u\n", p); put_data(&p, ); printf("ptr with data: %u\n", p);
printf("data stored in ptr: %u\n", get_data(p)); cleanse_pointer(&p); printf("Cleansed ptr: %u\n", p);
printf("Dereferencing cleansed ptr: %u\n", *(int*)p); return ;
}

This will give the following output:

Original ptr:  3216722220
ptr with data: 3216722223
data stored in ptr: 3
Cleansed ptr: 3216722220
Dereferencing cleansed ptr: 701

We can store any number that can be represented by 2 bits in the pointer. Using put_data(), the last 2 bits of the pointer are set as the data to be stored. This data is accessed using get_data(). Here, all bits except the last 2 bits are overwritten as zeroes there by revealing our hidden data.

cleanse_pointer() zeroes out the last 2 bits, making the pointer safe for dereferencing. Note that while some CPUs like Intel will let us access unaligned memory locations, certain others like ARM CPU will fault. So, always remember to keep the pointer pointed to an aligned location before dereferencing.

Is this used anywhere in the real world?

Yes, it is. See the implementation of Red Black Trees in the Linux kernel (link).

The node of the tree is defined using:

struct rb_node {
unsigned long __rb_parent_color;
struct rb_node *rb_right;
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));

Here unsigned long __rb_parent_color stores:
1. the address of the parent node

2. the node’s color.

The color is represented as 0 for Red and 1 for Black.

Just like in the earlier example, this data is sneaked into the ‘useless’ bits of the parent pointer.

Now see, how the parent pointer and the color information is accessed:

/* in rbtree.h */
#define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))/* in rbtree_augmented.h */
#define __rb_color(pc) ((pc) & 1)
#define rb_color(rb) __rb_color((rb)->__rb_parent_color)

转:Hide data inside pointers(在指针中隐藏数据)的更多相关文章

  1. 在图像中隐藏数据:用 Python 来实现图像隐写术

    什么是“隐写术”? 隐写术是将机密信息隐藏在更大的信息中,使别人无法知道隐藏信息的存在以及隐藏信息内容的过程.隐写术的目的是保证双方之间的机密交流.与隐藏机密信息内容的密码学不同,隐写术隐瞒了传达消息 ...

  2. NOPI读取模板导出(Excel中追加数据)

    在Controller里,我们定义一个FileResult的Action,返回值是一个文件形式被浏览器下载下来. [HttpGet] public FileResult ExportProductLi ...

  3. Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲

    Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台:   微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...

  4. 访问cv::Mat中的数据时遇到的指针类型问题

    在用Opencv的时候由于下图原本的图像尺寸是1111*1111,要进行resize,代码如下: cv::Mat img = cv::imread("//Users//apple//td3/ ...

  5. 聚集表(clustered table)data page中的数据行可以无序

    误区 一直以为只要一个表含有聚集索引,那么在data page中的数据行是排序的.比如原来data page中有1.2.4.5.6这样四条记录,那么我要插入3这条记录,应该是先将456三条记录往后移, ...

  6. [MySQL]load data local infile向MySQL数据库中导入数据时,无法导入和字段不分离问题。

    利用load data将文件中的数据导入数据库表中的时候,遇到了两个问题. 首先是load data命令无法执行的问题: 命令行下输入load data local infile "path ...

  7. Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages

    Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages Web网页中动态数据区域的识别 ...

  8. load data导txt文件进mysql中的数据

    1.实验内容: 利用SQL语句“load data ”将“.txt”文本文件中的数据导入到mysql中 2.实验过程: 首先我创了一个txt(也可以是其他的),设置其编码为utf-8,在windows ...

  9. 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容

    在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...

随机推荐

  1. mORMot使用基础

    mORMot 名称来自Marmot,对,土拨鼠,俗称旱獭,是一种生活在高寒山区的动物.多数都在白天活动,喜群居,善掘土,所挖地道深达数米,内有铺草的居室,非常舒适.通常洞穴都会有两个以上的入口,以策安 ...

  2. aspectj pointcut 找不到类型pointcut cannot be resolved to a type

    引入了aspectJ后,文件提示找不到pointcut类型.修改如下: .project文件添加内容,红色字体为添加的引用 <?xml version="1.0" encod ...

  3. WebService 调用

    一.WebService调用 1.webservice支持四种调用方式:SOAP 1.1,SOAP 1.2,GET,POST.           2.如果要webservice支持GET,POST调 ...

  4. 不要轻易delete void*指针,这样会隐藏比较多的错误。

    #include<iostream> using namespace std; class Object{ void* data; const int size; const char i ...

  5. OpenSessionInViewFilter 的配置及作用

    spring为我们解决hibernate的Session的关闭与开启问题. Hibernate 允许对关联对象.属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Sessio ...

  6. h5图片上传预览与拖拽上传

    图片上传: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  7. [leetcode 17]Letter Combinations of a Phone Number

    1 题目: Given a digit string, return all possible letter combinations that the number could represent. ...

  8. Makecert.exe(证书创建工具)

    Makecert.exe(证书创建工具) .NET Framework 4.5   其他版本   2(共 3)对本文的评价是有帮助 - 评价此主题   证书创建工具生成仅用于测试目的的 X.509 证 ...

  9. SQL Server 内存数据库原理解析

    前言 关系型数据库发展至今,细节上以做足文章,在寻求自身突破发展的过程中,内存与分布式数据库是当下最流行的主题,这与性能及扩展性在大数据时代的需求交相辉映.SQL Server作为传统的数据库也在最新 ...

  10. [转]一个文件上传的jquery插件

    http://www.jb51.net/article/51547.htm 这篇文章主要介绍了使用ajaxfileupload.js实现ajax上传文件php版,需要的朋友可以参考下     无论是P ...