Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux mprotect()作为ASM系统调用的第三个参数的用法是什么?_Linux_Memory_Memory Management_Assembly - Fatal编程技术网

Linux mprotect()作为ASM系统调用的第三个参数的用法是什么?

Linux mprotect()作为ASM系统调用的第三个参数的用法是什么?,linux,memory,memory-management,assembly,Linux,Memory,Memory Management,Assembly,在i386体系结构Linux中,我知道可以通过将系统调用的标识加载到EAX中,并将参数加载到EBX、ECX等中来构建系统调用 在这种情况下,我对第三个主张保护的论点感到困惑;假设我想在二进制分配的内存可执行文件中创建一个内存段,那么PROT_EXEC参数(arg3)的编码是如何工作的?我知道前两个参数是(1)指向分配块开始的指针,(2)分配块的长度,这在ASM中相对容易概念化(因为它们是内存中的十六进制地址) 如何将mprotect()的第三个参数格式化为Linux上i386程序集中发出的中断系

在i386体系结构Linux中,我知道可以通过将系统调用的标识加载到EAX中,并将参数加载到EBX、ECX等中来构建系统调用

在这种情况下,我对第三个主张保护的论点感到困惑;假设我想在二进制分配的内存可执行文件中创建一个内存段,那么PROT_EXEC参数(arg3)的编码是如何工作的?我知道前两个参数是(1)指向分配块开始的指针,(2)分配块的长度,这在ASM中相对容易概念化(因为它们是内存中的十六进制地址)

如何将mprotect()的第三个参数格式化为Linux上i386程序集中发出的中断系统调用?


谢谢。

TL;DR:一个整数作为第三个参数传递

现在让我们回答评论中的问题。 如果打开mman common.h,它应该位于/usr/include/asm generic中,您将发现这些值

#define PROT_READ       0x1             /* page can be read */
#define PROT_WRITE      0x2             /* page can be written */
#define PROT_EXEC       0x4             /* page can be executed */
#define PROT_SEM        0x8             /* page may be used for atomic ops */
在编译之前,预处理器将用上面的数字替换您的参数。 所以如果你有这个电话:

mprotect(myaddress, 256, PROT_READ | PROT_WRITE);
该代码将替换为以下代码:

mprotect(myaddress, 256, 0x1 | 0x2);
现在看看不同参数可以取的值:它们不是随机选择的,它们是二的幂,因此在二进制表示法中,它们只由一个1位数和零表示

PROT_READ  = 0x1 =   00000001
PROT_WRITE = 0x2 =   00000010
PROT_EXEC  = 0x4 =   00000100
选择二的幂是很方便的,因为当你使用二进制或时,你得到的数字结合了前面的两个值,所以这两个信息都包含在或的数字中

PROT_WRITE | PROT_EXEC = 
    00000010
  | 00000100
=   00000110
现在回到我们的电话:

如果您调用了
mprotect(myaddress,256,PROT|u READ | PROT|u WRITE)
,那么会发生的情况是
PROT|u READ | PROT|u WRITE
会被合并到
0x1 | 0x2
,即
0x3

现在在内核方面,假设
PROT_READ | PROT_WRITE
是由用户编写的。内核接收参数
0x3
,并希望检查PROT_READ是否最初写入。这样做的一种方法是写下:

if (PROT_READ & userValue) { }
它之所以有效,是因为userValue包含二进制的PROT_READ和PROT_WRITE的组合版本:

PROT_READ & userValue = 
    00000001
&&  00000011
 =  00000001
如果设置了该标志,则该数字为非零,因此内核知道已传递该标志


希望这有帮助。

我看到了,但我看到它在C中以“PROT_EXEC”的形式发布。另外,我不确定按位or如何表示四个唯一值,因为按位or操作只能产生两个值。我基本上不了解如何为不同的标志设置此参数的格式,手册也没有多少帮助。