CFG 地址检测位图构建

CFG设计原理及分析

目标地址 :
0x00b613a0 =00000000 10110110 00010011 10100000(b)
首先取高位的3个字节:00000000 10110110 00010011 = 0x00b613
那么CFGbitmap的基地址加上 0x00b613 就是指向一个字节单元的指针。
这个指针最终取到的假设是:
CFGBitmap :0x10100444 = 0001 0000 0001 0000 0000 0100 0100 0100(b)
接着判断目标地址是否以0x10对齐:地址 & 0xf 是否等于 0 ;

如果等于0,那偏移是:最低字节二进制位的前5位,这里就是 10100;
若不等于0,则偏移是: 10100|0x1。
这里的例子,0x00b613a0 & 0xf = 0 ,所以偏移: 1010 0 = 20 (d)
这个偏移就是该函数在CFGbitmap中第20位的位置上,若这个位置是1,说明该函数调用是合法有效的,反之则不是。
那么:
CFGBitmap :0x10100444 = 0001 0000 000**1** 0000 0000 0100 0100 0100(b)20位加粗的 1 ,说明这个调用合法有效。

理论上32位地址有3G的取值范围。但目测一般用不了这么多。因为如果我们利用 32位前3字节将会有

2^24 --- 2^23
167772168388608之间的数组byte,也就是16M将可以表示所有的地址。

那么也就表示16M将可以实现所有地址的记录。

我们 详细分析,每个动态库二进制文件在加载的过程中,都会对齐内存并加上偏移。所以静态分析的文件一般都不会范围很大。

进一步分析64位的系统。这个时候地址范围将会变的比较大。将能表示18,446,744,073,709,551,616范围的地址。目测两个亿级相乘的级别。但是一般情况我们不会用到这么多的地址。而且静态库分析偏移的话也会在低位地址上。这时候其实我们完全可以利用低位地址进行对比,大部分情况将能实现偏移准确校验。

所以,我们默认可以利用低地址32位来直接校验rva。

这个时候,也就转化为和32位相同的情况。

为了贴近真实环境,我这里展示64位下关于sshd进程的相关内存情况

lier@lier-virtual-machine:~$ sudo cat /proc/1158/maps
[sudo] password for lier:
557e5163e000-557e51649000 r--p 00000000 08:05 6292593                    /usr/sbin/sshd
557e51649000-557e516c8000 r-xp 0000b000 08:05 6292593                    /usr/sbin/sshd
557e516c8000-557e51710000 r--p 0008a000 08:05 6292593                    /usr/sbin/sshd
557e51710000-557e51714000 r--p 000d1000 08:05 6292593                    /usr/sbin/sshd
557e51714000-557e51715000 rw-p 000d5000 08:05 6292593                    /usr/sbin/sshd
557e51715000-557e5171a000 rw-p 00000000 00:00 0
557e51e7b000-557e51ebd000 rw-p 00000000 00:00 0                          [heap]
.......
7f73baea6000-7f73baeb0000 rw-p 00000000 00:00 0
7f73baeb0000-7f73baeb4000 r--p 00000000 08:05 6298375                    /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7f73baeb4000-7f73baec7000 r-xp 00004000 08:05 6298375                    /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7f73baec7000-7f73baed1000 r--p 00017000 08:05 6298375                    /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7f73baed1000-7f73baed2000 r--p 00020000 08:05 6298375                    /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7f73baed2000-7f73baed3000 rw-p 00021000 08:05 6298375                    /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.28.0
7f73baed3000-7f73baed7000 r--p 00000000 08:05 6293661                    /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
7f73baed7000-7f73baee7000 r-xp 00004000 08:05 6293661                    /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
7f73baee7000-7f73baeea000 r--p 00014000 08:05 6293661                    /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
7f73baeea000-7f73baeeb000 ---p 00017000 08:05 6293661                    /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
7f73baeeb000-7f73baeec000 r--p 00017000 08:05 6293661                    /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
7f73baeec000-7f73baeed000 rw-p 00018000 08:05 6293661                    /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
7f73baeed000-7f73baeef000 rw-p 00000000 00:00 0
......
7f73baef6000-7f73baef8000 rw-p 00000000 00:00 0
7f73baef8000-7f73baefb000 r--p 00000000 08:05 6295312                    /usr/lib/x86_64-linux-gnu/libkrb5support.so.0.1
7f73baefb000-7f73baf02000 r-xp 00003000 08:05 6295312                    /usr/lib/x86_64-linux-gnu/libkrb5support.so.0.1
7f73baf02000-7f73baf05000 r--p 0000a000 08:05 6295312                    /usr/lib/x86_64-linux-gnu/libkrb5support.so.0.1
7f73baf05000-7f73baf06000 r--p 0000c000 08:05 6295312                    /usr/lib/x86_64-linux-gnu/libkrb5support.so.0.1
7f73baf06000-7f73baf07000 rw-p 0000d000 08:05 6295312                    /usr/lib/x86_64-linux-gnu/libkrb5support.so.0.1
7f73baf07000-7f73baf0b000 r--p 00000000 08:05 6292427                    /usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1
7f73baf0b000-7f73baf27000 r-xp 00004000 08:05 6292427                    /usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1
7f73baf27000-7f73baf34000 r--p 00020000 08:05 6292427                    /usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1
7f73baf34000-7f73baf35000 ---p 0002d000 08:05 6292427                    /usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1
7f73baf35000-7f73baf36000 r--p 0002d000 08:05 6292427                    /usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1
7f73baf36000-7f73baf37000 rw-p 0002e000 08:05 6292427                    /usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1
7f73baf37000-7f73baf38000 rw-p 00000000 00:00 0
......
7f73baf57000-7f73baf5b000 rw-p 00000000 00:00 0
7f73baf5b000-7f73baf67000 r--p 00000000 08:05 6291561                    /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7f73baf67000-7f73bb035000 r-xp 0000c000 08:05 6291561                    /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7f73bb035000-7f73bb072000 r--p 000da000 08:05 6291561                    /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7f73bb072000-7f73bb074000 r--p 00116000 08:05 6291561                    /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7f73bb074000-7f73bb079000 rw-p 00118000 08:05 6291561                    /usr/lib/x86_64-linux-gnu/libgcrypt.so.20.2.5
7f73bb079000-7f73bb07b000 r--p 00000000 08:05 6292160                    /usr/lib/x86_64-linux-gnu/liblz4.so.1.9.2
7f73bb07b000-7f73bb095000 r-xp 00002000 08:05 6292160                    /usr/lib/x86_64-linux-gnu/liblz4.so.1.9.2
7f73bb095000-7f73bb098000 r--p 0001c000 08:05 6292160                    /usr/lib/x86_64-linux-gnu/liblz4.so.1.9.2
7f73bb098000-7f73bb099000 r--p 0001e000 08:05 6292160                    /usr/lib/x86_64-linux-gnu/liblz4.so.1.9.2
7f73bb099000-7f73bb09a000 rw-p 0001f000 08:05 6292160                    /usr/lib/x86_64-linux-gnu/liblz4.so.1.9.2
7f73bb09a000-7f73bb09d000 r--p 00000000 08:05 6298636                    /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4
7f73bb09d000-7f73bb0b4000 r-xp 00003000 08:05 6298636                    /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4
7f73bb0b4000-7f73bb0bf000 r--p 0001a000 08:05 6298636                    /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4
7f73bb0bf000-7f73bb0c0000 r--p 00024000 08:05 6298636                    /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4
7f73bb0c0000-7f73bb0c1000 rw-p 00025000 08:05 6298636                    /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.4
7f73bb0c1000-7f73bb0c3000 rw-p 00000000 00:00 0
....
7f73bb164000-7f73bb166000 r--p 00000000 08:05 6298020                    /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
7f73bb166000-7f73bb169000 r-xp 00002000 08:05 6298020                    /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
7f73bb169000-7f73bb16a000 r--p 00005000 08:05 6298020                    /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
7f73bb16a000-7f73bb16b000 r--p 00005000 08:05 6298020                    /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
7f73bb16b000-7f73bb16c000 rw-p 00006000 08:05 6298020                    /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
.....
7ffc9c42e000-7ffc9c44f000 rw-p 00000000 00:00 0                          [stack]
7ffc9c55e000-7ffc9c561000 r--p 00000000 00:00 0                          [vvar]
7ffc9c561000-7ffc9c562000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]
lier@lier-virtual-machine:~$

可以看到大部分库的范围在三个字节以内。我们大可以猜测主流应用程序的关键序列位于rva在三个字节以内可以确认。这个时候我们对每个动态库的计算三个字节。前两个字节作为数组索引,后一字节作为位图信息。两字节将由256x256个字节数组,也就是65536。大小为64KB。

如果按照window cfg的设计逻辑, 前三字节作为索引,将会有更大的寻址空间,也就是256x256x256,16MB的字节数组。

当然我们可以设计两种模式,一种精简模式,重视效率和内存空间的使用。另一种重视精确度,但内存相对消耗较大。

当然这是理论计算最大值,实际应该比这个小一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值