Нужно прехватить вызовы некоторых функций в Linux, с помощью подмены кода, но возникла проблема с изменением атрибутов виртуальной памяти процесса. В винде это делается с помощьюю VirtualProtect. Существует ли аналог подобной функции в Linux?
Когда я указываю в параметрах mprotect адрес перехватываемой фунуции, она возвращает -1 вот примерчик: mprotect((void*)fopen, cmd_sz, PROT_WRITE | PROT_EXEC);
Не адрес функции нужно указывать, а "page-aligned start address of memory region", т.е. стартовый адрес страницы. 2й параметр: "page-aligned bytes' size of memory region".
как же тогда все-таки изменить атрибуты первых байтов функции, например open, используя mprotect, если вас не затруднит, не могли бы вы привести небольшой примерчик.
_dima_ Посмотрите тогда описание VirtualProtect в msdn - принцип тотже. Атрибуты задаются постранично, а не побайтово. Нужно вычислить адрес начала страницы, где хранится код функции, которую нужно пропатчить. Если размер страницы - 4Кб, то вычислить адрес начала можно простым and addr,0FFFFF000h.
Спасибо, mprotect заработала. Но к сожалению возникла новая проблемка: подмена первых байт функции fopen прошла удачно, на при попытке вызвать ее - segmentation fault, вот небольшой пример: #include<stdio.h> #include<string.h> #include<sys/mman.h> typedef unsigned char byte; int cmd_sz = 5; int addr_sz = 4; unsigned char JMP = 0xE9; int my(const char* fname, const char* mode){ printf("your file "); printf(fname); printf(" could not de open in mode "); printf(mode); printf("\n"); return 0; }; int main(){ unsigned char old_bytes[cmd_sz]; unsigned char new_bytes[cmd_sz]; new_bytes[0] = JMP; memmove(&new_bytes[1], (const void*)my, addr_sz); memmove(old_bytes, (const void*)fopen, cmd_sz); int addr = (int)(void*)fopen; printf("%d\n", addr); int page_addr = addr & 0x0FFFFF000; printf("%d\n", mprotect((void*)page_addr ,4096, PROT_READ | PROT_WRITE | PROT_EXEC)); //здесь ноль! memmove((void*)fopen, new_bytes , cmd_sz); //здесь тоже все ок! fopen("no.txt", "a+"); // здесь Segmentation fault return 0; }