转:Hide data inside pointers(在指针中隐藏数据)
该文介绍了如何使用指针中一些未使用的位来隐藏一些数据。
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(在指针中隐藏数据)的更多相关文章
- 在图像中隐藏数据:用 Python 来实现图像隐写术
什么是“隐写术”? 隐写术是将机密信息隐藏在更大的信息中,使别人无法知道隐藏信息的存在以及隐藏信息内容的过程.隐写术的目的是保证双方之间的机密交流.与隐藏机密信息内容的密码学不同,隐写术隐瞒了传达消息 ...
- NOPI读取模板导出(Excel中追加数据)
在Controller里,我们定义一个FileResult的Action,返回值是一个文件形式被浏览器下载下来. [HttpGet] public FileResult ExportProductLi ...
- Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲
Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台: 微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...
- 访问cv::Mat中的数据时遇到的指针类型问题
在用Opencv的时候由于下图原本的图像尺寸是1111*1111,要进行resize,代码如下: cv::Mat img = cv::imread("//Users//apple//td3/ ...
- 聚集表(clustered table)data page中的数据行可以无序
误区 一直以为只要一个表含有聚集索引,那么在data page中的数据行是排序的.比如原来data page中有1.2.4.5.6这样四条记录,那么我要插入3这条记录,应该是先将456三条记录往后移, ...
- [MySQL]load data local infile向MySQL数据库中导入数据时,无法导入和字段不分离问题。
利用load data将文件中的数据导入数据库表中的时候,遇到了两个问题. 首先是load data命令无法执行的问题: 命令行下输入load data local infile "path ...
- Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages
Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages Web网页中动态数据区域的识别 ...
- load data导txt文件进mysql中的数据
1.实验内容: 利用SQL语句“load data ”将“.txt”文本文件中的数据导入到mysql中 2.实验过程: 首先我创了一个txt(也可以是其他的),设置其编码为utf-8,在windows ...
- 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容
在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...
随机推荐
- expdp小记
一.10.2.0.5要求expdp导出a用户b表空间下的数据. expdp \'/ as sysdba\' directory=mydir dumpfile=1.dmp schemas=a exclu ...
- 解决TextView最后一行显示不全
public class MultilineTextView extends TextView { private boolean calculatedLines = false; public Mu ...
- iOS报错笔记
问题一: linker command failed with exit code 1 (use -vto see invocation) 原因:导入了.m的头文件,导致同时有两个一样的.m文件在编译 ...
- div中嵌套div水平垂直居中
div中嵌套一个居中的div有很多方法,如果不想调整边距,有一个简单的方法: <div align="center" style="width: 200px;hei ...
- 关于loadrunner录制不跳转到IE
我是一个新手,对于这个问题,我已经愁了两周左右,因为是自学,一直没人教,靠自己百度也一直解决不了. 今天,我总算解决了这个问题. 我之前是ie8,根据网上说的启动IE----工具---Internet ...
- 在CentOS6.7操作系统上编译安装httpd2.4
功能描述: 在CentOS6.7操作系统上,编译安装apache服务,实现定制功能等 一.安装前提 1)安装编译httpd需要的软件包 [root@bqe6tewv41kx ~]# yum -y i ...
- html5 文件上传 带进度条
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- 斯坦福第四课:多变量线性回归(Linear Regression with Multiple Variables)
4.1 多维特征 4.2 多变量梯度下降 4.3 梯度下降法实践 1-特征缩放 4.4 梯度下降法实践 2-学习率 4.5 特征和多项式回归 4.6 正规方程 4.7 正规方程及不可逆性 ...
- [转] 基于ArcGISServer实现活动地图标注
——王嘉彬(Esri中国上海分公司) 1.背景 1.1.主流互联网地图应用的现状 在目前主流的互联网地图应用中,如 Google Map(图 1).搜狗地图(图2),POI 兴趣点的文字标注越来越多的 ...
- “”?: H3C SSH 配置+
开启ssh 服务 ssh service enable 创建用户 使用ssh local-user ssh 用户级别 authorization-attribute user-role level-1 ...