在 C 课程中听到它之后,我一直在尝试使用自修改代码。我有一个使用 mprotect 为一段内存设置内存保护的函数:
int SetMemoryProtections(void* addr, size_t length, int protection_flag)
{
size_t addr_as_int = (size_t)(byte*)addr;
size_t page_size = getpagesize();
//Address must be multiple of system page size
size_t aligned_addr_as_int = (addr_as_int / page_size) * page_size;
size_t additional_length = addr_as_int - aligned_addr_as_int;
void* aligned_addr = (byte*)addr - additional_length;
if(mprotect(aligned_addr, length + additional_length, protection_flag))
{
return -1;
}
else
{
return 0;
}
}
但是,当我尝试在动态分配的内存块上调用它时,我收到错误代码 EACCES 的错误。为什么会发生这种情况,有什么办法可以绕过它?当f_data_buffer
在堆栈上分配时,没有错误消息(这是注释掉的行)。
代码调用SetMemoryProtections
:
//byte f_data_buffer[16384];//Converts function pointer to byte pointer
byte* f_data_buffer = malloc(sizeof(byte) * getpagesize() * 3);
byte* f_data = f_data_buffer + getpagesize();
if(SetMemoryProtections(f_data, 20, PROT_READ | PROT_WRITE | PROT_EXEC))
{
printf("SetMemoryProtections encountered error. Error code: ");
switch(errno)
{
case EACCES: printf("EACCES"); break;
case EINVAL: printf("EINVAL"); break;
case ENOMEM: printf("ENOMEM"); break;
}
printf("\n");
return -1;
}
更新:我将代码重写为它在调用 printf 之前读取 errno。(它创建了一个名为 err 的局部变量,将 err 设置为 errno,然后使用 err 调用开关)我得到了相同的 EACCES 错误代码。