Вы узнали плохую привычку от gcc (компилятор, наиболее часто используемый с Dev C ++). Несмотря на то, что он во многих отношениях хорошо соответствует стандарту C ++, в одном он не дает результатов. Согласно стандарту, вам не разрешается делать какие-либо арифметические действия с пустыми указателями.
Пустой указатель в основном предназначен для "держателя". Вы можете поместить указатель на любой тип объекта в указатель void, а позже вы можете получить его обратно - но вы не можете фактически делать какие-либо подобные указателю вещи (разыменование или арифметику указателя) с самим указателем void.
GCC терпит неудачу в этом отношении. Хотя он не позволит вам разыменовать пустой указатель, он позволит вам выполнить арифметику с пустым указателем. Когда вы это делаете, он обрабатывает его так, как если бы он был указателем на символ, поэтому, если вы увеличиваете или уменьшаете его, это происходит в единицах единицы.
Чтобы поддерживать арифметику, вы, вероятно, захотите создать указатель на (возможно, без знака) символ и выполнить арифметику для этого:
void print_function_instructions(void* fptr, size_t func_len) {
unsigned char* func_ptr = reinterpret_cast<unsigned char*>(fptr);
for (unsigned char i = 0; i < func_len; i++)
printf("%p (%2u): %x\n", func_ptr + i, i, func_ptr[i]);
}
int change_page_permissions_of_address(void* address) {
// Move the pointer to the page boundary
unsigned char* addr = reinterpret_cast<unsigned char *>(address);
int page_size = getpagesize();
DWORD dwOldProtect;
addr -= (uintptr_t)addr % page_size;
if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
return -1;
}
return 0;
}