能力值:
( LV3,RANK:20 )
|
-
-
26 楼
支持,方便开源一下代码吗,或者透露下“ptrace init进程的patch技术”
|
能力值:
( LV5,RANK:60 )
|
-
-
27 楼
heartbeast
支持,方便开源一下代码吗,或者透露下“ptrace init进程的patch技术”
我有一个不需要写代码的方法,直接 把init pull出来,用16进制编译器,或者ida找到ro.\0的位置,再通过dd 命令去写/proc/1/mem,把内存里的ro.\0改成xx.\0,就成了。
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
不错,支持一下
|
能力值:
( LV6,RANK:80 )
|
-
-
29 楼
神器,支持
|
能力值:
( LV2,RANK:10 )
|
-
-
30 楼
为啥我的修改不了ro.product.model 呢?
------------------------ 可以修改成功了,因为之前SELinux没有设置为Permissive权限所以没有注入成功 再次感谢楼主!
最后于 2018-6-7 17:53
被Jack飞编辑
,原因:
|
能力值:
( LV3,RANK:20 )
|
-
-
31 楼
看到有兄台贴了mprop的逆向分析,好吧,其实没必要判断prop_info这个结构,楼上也有人写出了原理,其实就是改个字符串绕过验证流程,贴出源码以飨读者:
BTW:无论引用代码还是自己修改,请务必注明出处。
/**
* Copyright (C) 2018 netsniffer
* mprop v1.0, 2017/01/19
* https://bbs.pediy.com/thread-215311.htm
*/
#include <unistd.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <memory.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/system_properties.h>
#define PROP_NAME_MAX 32
#define PROP_VALUE_MAX 92
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);
}
}
#define ORI_INST 0x2e6f72
#define HACK_INST 0x2e6f73
int main(int argc, char **argv)
{
FILE *fp;
int m, rc;
int patch_count;
unsigned long maps, mape, addr, mlen;
unsigned long real_val, real_vaddr;
char perms[5];
char line[512];
char *buffer, *ro;
char* name = NULL, *value = NULL;
uint32_t tmp;
uint32_t dest_inst = ORI_INST;
uint32_t mod_inst = HACK_INST;
int restore = 0, verbose = 0;
for (m = 1; m < argc; m++) {
if (argv[m] == NULL)
continue;
if (argv[m][0] != '-') {
break;
}
if (argv[m][1] == 'r') {
restore = 1;
dest_inst = HACK_INST;
mod_inst = ORI_INST;
} else if (argv[m][1] == 'v') {
verbose = 1;
}
}
if (restore) {
fprintf(stderr, "restore ...\n");
}
else {
if (argc - m >= 2) {
// fprintf(stderr, "Usage: %s [-r] [-v] [prop_name] [prop_value]\n"
// "e.g.: %s ro.debuggable 1\n", argv[0], argv[0]);
name = argv[m];
value = argv[m+1];
}
fprintf(stderr, "start hacking ...\n");
}
fp = fopen("/proc/1/maps", "r");
if (!fp) {
perror("!! fopen ");
return 1;
}
// 00008000-000cb000 r-xp 00000000 00:01 6999 /init
memset(line, 0, sizeof(line));
while (fgets(line, sizeof(line), fp)) {
int main_exe = (strstr(line, "/init") != NULL) ? 1 : 0;
if (main_exe) {
rc = sscanf(line, "%lx-%lx %4s ", &maps, &mape, perms);
if (rc < 3) {
perror("!! sscanf ");
return 1;
}
if (perms[0] == 'r' && perms[1] == '-' && perms[2] == 'x' && perms[3] == 'p') {
break;
}
}
}
fclose(fp);
fprintf(stderr, "target mapped area: 0x%lx-0x%lx\n", maps, mape);
mlen = mape - maps;
buffer = (char *) calloc(1, mlen + 16);
if (!buffer) {
perror("!! malloc ");
return 1;
}
rc = ptrace(PTRACE_ATTACH, 1, 0, 0);
if (rc < 0) {
perror("!! ptrace ");
return rc;
}
for (addr = maps; addr < mape; addr += 4) {
tmp = ptrace(PTRACE_PEEKTEXT, 1, (void *) addr, 0);
*((uint32_t*)(buffer + addr - maps)) = tmp;
}
if (verbose) {
dump_hex(buffer, mlen);
}
for (m = 0; m < mlen; ++m) {
if (dest_inst == *(uint32_t*)(buffer+m)) { // 72 6F 2E 00 == ro.\0
break;
}
}
if (m >= mlen) {
fprintf(stderr, ">> inject position not found, may be already patched!\n");
}
else {
real_vaddr = maps + m;
real_val = *(uint32_t*)(buffer+m);
fprintf(stderr, ">> patching at: 0x%lx [0x%lx -> 0x%08x]\n", real_vaddr, real_val, mod_inst);
tmp = mod_inst;
rc = ptrace(PTRACE_POKETEXT, 1, (void *)real_vaddr, (void*)tmp);
if (rc < 0) {
perror("!! patching failed ");
}
tmp = ptrace(PTRACE_PEEKTEXT, 1, (void *)real_vaddr, 0);
fprintf(stderr, ">> %s reread: [0x%lx] => 0x%08x\n", restore ? "restored!" : "patched!", real_vaddr, tmp);
}
free(buffer);
rc = ptrace(PTRACE_DETACH, 1, 0, 0);
if (!restore && (name && value && name[0] != 0)) {
char propbuf[PROP_VALUE_MAX];
fprintf(stderr, "-- setprop: [%s] = [%s]\n", name, value);
__system_property_set(name, value);
usleep(400000);
__system_property_get(name, propbuf);
fprintf(stderr, "++ getprop: [%s] = [%s]\n", name, propbuf);
}
return rc;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
32 楼
神器,支持
|
能力值:
( LV2,RANK:10 )
|
-
-
33 楼
netsniffer
全局生效
感谢楼主的神器!这个只在native层的system_property_get函数里生效了,如何在java层生效,尤其是os.Build里,除了xposed还有什么方案么?
|
能力值:
( LV2,RANK:10 )
|
-
-
34 楼
试了几个不行 看看这个怎样
|
能力值:
( LV1,RANK:0 )
|
-
-
35 楼
支持下
|
能力值:
( LV3,RANK:20 )
|
-
-
36 楼
大神6666666666666666666666666 感谢您这个方案!!
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
真是个好用的小工具,模拟器调试省了不少事~ 谢谢楼主分享。
|
能力值:
( LV1,RANK:0 )
|
-
-
38 楼
真手机安卓9版本可以开启debug吗?
|
能力值:
( LV3,RANK:20 )
|
-
-
39 楼
roysue
最好用的难道不是XDebuggable么?
肉丝姐,现在这个时间点最好的开启debuggable的方式是啥。。
|
能力值:
( LV1,RANK:0 )
|
-
-
40 楼
netsniffer
看到有兄台贴了mprop的逆向分析,好吧,其实没必要判断prop_info这个结构,楼上也有人写出了原理,其实就是改个字符串绕过验证流程,贴出源码以飨读者:
BTW:无论引用代码还是自己修改,请 ...
但是判断prop_info这个结构可以兼容更高的版本,我在10里它的可以用,但是这个我就报错>> inject position not found, may be already patched!了
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
大佬,帮忙看看 sailfish:/data/local/tmp # ./mprop -v start hacking ... target mapped area: 0x0-0x0 >> inject position not found, may be already patched!
|
能力值:
( LV3,RANK:20 )
|
-
-
42 楼
偶尔看到注册年份,07年,额... 感觉都老了,时不时得冒个泡,回来看看 21年小改了一行 ( perms[2] == '-' ),当时仅仅为了测试Android新版本,老机器都扔了,不考虑兼容。
|