minecraft-pi-reborn/core/src/core.c

74 lines
2.0 KiB
C
Raw Normal View History

2020-09-25 16:43:53 +00:00
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdint.h>
#include <libcore/libcore.h>
2020-10-01 15:08:46 +00:00
#define PATCH_PRINTF(print, start, str) if (print) fprintf(stderr, "Patching (0x%04x) - "str": 0x%02x 0x%02x 0x%02x 0x%02x\n", (uint32_t) start, data[0], data[1], data[2], data[3]);
#define PREPARE_PATCH(print, count) \
2020-09-25 16:43:53 +00:00
size_t page_size = sysconf(_SC_PAGESIZE); \
2020-10-01 15:08:46 +00:00
uintptr_t end = ((uintptr_t) start) + (4 * count); \
2020-09-25 16:43:53 +00:00
uintptr_t page_start = ((uintptr_t) start) & -page_size; \
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_WRITE); \
\
unsigned char *data = (unsigned char *) start; \
int thumb = ((size_t) start) & 1; \
if (thumb) { \
data--; \
} \
2020-10-01 15:08:46 +00:00
PATCH_PRINTF(print, start, "original");
2020-09-25 16:43:53 +00:00
2020-10-01 15:08:46 +00:00
#define END_PATCH(print) \
PATCH_PRINTF(print, start, "result"); \
2020-09-25 16:43:53 +00:00
\
2020-10-01 15:08:46 +00:00
mprotect((void *) page_start, end - page_start, PROT_READ | PROT_EXEC); \
__clear_cache(start, (void *) end);
#define ORIGINAL_SIZE 4 + sizeof (int)
void *overwrite(void *start, void *target) {
PREPARE_PATCH(1, 2);
void *original = malloc(ORIGINAL_SIZE);
memcpy(original, start, ORIGINAL_SIZE);
2020-09-25 16:43:53 +00:00
if (thumb) {
unsigned char patch[4] = {0xdf, 0xf8, 0x00, 0xf0};
memcpy(data, patch, 4);
} else {
unsigned char patch[4] = {0x04, 0xf0, 0x1f, 0xe5};
memcpy(data, patch, 4);
}
memcpy(&data[4], &target, sizeof (int));
2020-10-01 15:08:46 +00:00
END_PATCH(1);
return original;
}
void revert_overwrite(void *start, void *original) {
PREPARE_PATCH(0, 2);
void *temp = malloc(ORIGINAL_SIZE);
memcpy(temp, data, ORIGINAL_SIZE);
memcpy(data, original, ORIGINAL_SIZE);
memcpy(original, temp, ORIGINAL_SIZE);
free(temp);
END_PATCH(0);
2020-09-25 16:43:53 +00:00
}
void patch(void *start, unsigned char patch[]) {
2020-10-01 15:08:46 +00:00
PREPARE_PATCH(1, 1);
2020-09-25 16:43:53 +00:00
memcpy(data, patch, 4);
2020-10-01 15:08:46 +00:00
END_PATCH(1);
2020-09-25 16:43:53 +00:00
}
2020-10-02 23:28:31 +00:00
void patch_address(void *start, void *target) {
unsigned char patch_data[4] = {target & 0xff, (target >> 8) & 0xff, (target >> 16) & 0xff, (target >> 24) & 0xff};
patch(start, patch_data);
}