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
16777216 到 8388608之间的数组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的字节数组。
当然我们可以设计两种模式,一种精简模式,重视效率和内存空间的使用。另一种重视精确度,但内存相对消耗较大。
当然这是理论计算最大值,实际应该比这个小一点。
7516

被折叠的 条评论
为什么被折叠?



