|
发表于 2023-4-2 13:43:55
|
显示全部楼层
似乎能构造反例
我在我的系统上查看了页面大小为4096字节
现在编写一个很简单的 C 语言程序- #include <unistd.h>
- #include <stdio.h>
- int main(){
- printf("pid=%d\n", getpid());
- int a = 0;
- a = a + 1;
- // 这里省略了410行 a = a + 1;
- sleep(-1);
- return 0;
- }
复制代码
然后用 clang 将其编译得到可执行文件,再用 objdump 反汇编得到指令序列,可以看到在代码段接近结尾的地方有这样三行:- 1ffb: 89 45 f8 mov %eax,-0x8(%rbp)
- 1ffe: bf ff ff ff ff mov $0xffffffff,%edi
- 2003: e8 48 f0 ff ff call 1050 <sleep@plt>
复制代码
4096字节用16进制表示是0x1000,显然这里的这条 mov 指令跨越了边界
接下来实际运行验证。运行这个程序会输出其进程号帮助验证,且会长时间睡眠来保持不退出。用输出的内存号查看内存映射(部分信息已经被隐藏):- $ cat /proc/44021/maps
- 561b4067f000-561b40680000 r--p 00000000 --:-- - a.out
- 561b40680000-561b40682000 r-xp 00001000 --:-- - a.out
- 561b40682000-561b40683000 r--p 00003000 --:-- - a.out
- 561b40683000-561b40684000 r--p 00003000 --:-- - a.out
- 561b40684000-561b40685000 rw-p 00004000 --:-- - a.out
- 561b41f85000-561b41fa6000 rw-p 00000000 --:-- 0 [heap]
复制代码
其中代码段是有执行权限的561b40680000-561b40682000,可见恰好占用两页
接下来将这两页的信息读取出来:- $ sudo dd if=/proc/44021/mem of=memdump1 bs=4096 count=1 skip=23114024576
- $ sudo dd if=/proc/44021/mem of=memdump2 bs=4096 count=1 skip=23114024577
复制代码
最后检查读取出的内容:- $ hexdump -s 4090 -C memdump1
- 01 89 45 f8 bf ff
- $ hexdump -n 8 -C memdump2
- ff ff ff e8 48 f0 ff ff
复制代码
和之前的反汇编信息对比就可以发现那条 mov 指令恰好出现在第一页的末尾和第二页的开始,跨越了两页 |
评分
-
参与人数 1 | 荣誉 +5 |
鱼币 +5 |
贡献 +3 |
收起
理由
|
人造人
| + 5 |
+ 5 |
+ 3 |
鱼C有你更精彩^_^ |
查看全部评分
|