#include <stdio.h>
#include <sys/ptrace.h>
#include <string.h>
#include <ctype.h>
#include <sys/system_properties.h>
#define nullptr NULL
#define ORI_INST 0x2e6f72
#define HACK_INST 0x2e6f73
static void dump_hex(const char* buf, int len)
{
const uint8_t *data = (const uint8_t*)buf;
int i;
char ascii_buf[17];
ascii_buf[16] = '\0';
for (i = 0; i < len; i++) {
int val = data[i];
int off = i % 16;
if (off == 0)
printf("%08x ", i);
printf("%02x ", val);
ascii_buf[off] = isprint(val) ? val : '.';
if (off == 15)
printf(" %-16s\n", ascii_buf);
}
i %= 16;
if (i) {
ascii_buf[i] = '\0';
while (i++ < 16)
printf(" ");
printf(" %-16s\n", ascii_buf);
}
}
int main(int argc, char **argv) {
FILE *fp = fopen("/proc/1/maps", "r");
if (fp == nullptr) {
printf("Unable open /proc/1/maps/.\n");
return 1;
}
int rc;
char line[512];
unsigned long maps, mape, addr, mlen;
char perms[5];
unsigned long real_val, real_vaddr;
memset(line, 0, sizeof(line));
while (fgets(line, sizeof(line), fp)) {
int init_exe = (strstr(line, "/init") != nullptr) ? 1:0;
if (init_exe) {
rc = sscanf(line, "%lx-%lx %4s ", &maps, &mape, perms);
if (rc < 3) {
printf("skip sscanf.\n");
}
if (perms[0] == 'r' && perms[1] == '-' && perms[2] == 'x' && perms[3] == 'p') {
break;
}
}
}
printf("init text: %lx-%lx %4s\n", maps, mape, perms);
fclose(fp);
mlen = mape - maps;
char *buffer = new char[mlen + 16];
if (buffer == nullptr) {
printf("Alloc mem error.\n");
return 1;
}
rc = ptrace(PTRACE_ATTACH, 1, 0, 0);
if (rc < 0) {
printf("ptrace error.\n");
return 1;
}
int tmp;
for (addr = maps; addr < mape; addr += 4) {
tmp = ptrace(PTRACE_PEEKTEXT, 1, (void *) addr, 0);
*((uint32_t *)(buffer + addr - maps)) = tmp;
}
//dump_hex(buffer, mlen);
//printf("\n\n~~~~~~\n\n");
int m;
for (m = 0; m < mlen; m++) {
if (ORI_INST == *(uint32_t *)(buffer+m)) {//ro.
break;
}
}
if (m >= mlen) {
printf("warnning not found ro. in mem.\n");
//return 1;
} else {
real_vaddr = maps + m;
real_val = *(uint32_t *)(buffer+m);
tmp = HACK_INST;
rc = ptrace(PTRACE_POKETEXT, 1, (void *)real_vaddr, (void*)tmp);
if (rc < 0) {
printf("!! patching failed.\n");
}
}
delete[] buffer;
rc = ptrace(PTRACE_DETACH, 1, 0, 0);
__system_property_set(argv[1], argv[2]);
printf("end!\n");
return rc;
}
网友评论