XDebuggable是一个xposed的插件用来 使android:debuggable="true"保证可调试状态
mprop修改default.prop中ro.debuggable=1保证可调试状态
hook修改android/os/Process.java的start方法,并保证其第五个参数debugflags的值为1.
关键在于hook修改start函数的第五个参数,我们来看第五个参数是啥?
debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER值为1则开启调试模式 然后启动新的进程
查看SELinux状态:
1、/usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态
SELinux status: enabled
2、getenforce ##也可以用这个命令检查
关闭SELinux:
1、临时关闭(不用重启机器):
setenforce 0 ##设置SELinux 成为permissive模式
setenforce 1 设置SELinux 成为enforcing模式
2、修改配置文件需要重启机器:
修改/etc/selinux/config 文件
将SELINUX=enforcing改为SELINUX=disabled
重启机器即可
adb shell su
chmod 755 /data/local/tmp/mprop
data/local/tmp/mprop ro.debuggable 1
/data/local/tmp/mprop -r
手机默认的prop属性如下:
root@cancro:/ # cat default.prop
cat default.prop
#
# ADDITIONAL_DEFAULT_PROPERTIES
#
ro.adb.secure=0
ro.secure=1
security.perf_harden=1
ro.allow.mock.location=0
ro.debuggable=1
ro.zygote=zygote32
dalvik.vm.image-dex2oat-Xms=64m
dalvik.vm.image-dex2oat-Xmx=64m
dalvik.vm.dex2oat-Xms=64m
dalvik.vm.dex2oat-Xmx=512m
ro.dalvik.vm.native.bridge=0
debug.atrace.tags.enableflags=0
persist.sys.strict_op_enable=false
persist.sys.whitelist=/system/etc/whitelist_appops.xml
camera2.portability.force_api=1
persist.sys.timezone=Asia/Shanghai
#
# BOOTIMAGE_BUILD_PROPERTIES
#
ro.bootimage.build.date=Wed Jun 14 02:20:41 CST 2017
ro.bootimage.build.date.utc=1497378041
ro.bootimage.build.fingerprint=Xiaomi/cancro/cancro:6.0.1/MMB29M/7.6.14:user/release-keys
persist.sys.usb.config=adb
原理:直接ptrace init进程,对标红的ro.属性的判断逻辑进行修改,跳过,这样任意属性就都可以设置了。
/**
* Copyright (C) 2018 netsniffer
* mprop v1.0, 2017/01/19
* https://bbs.pediy.com/thread-215311.htm
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;
}
//输出每个参数
printf("%s",argv[m]);
}
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) {
printf("%s","dump dex");
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;
}
#include
#include
#include
#include
#include
#include
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include
#include
struct prop_info;
struct prop_area;
extern int __system_property_area_init();
extern int __system_property_get(const char *name, char *value);
extern int __system_property_add(const char *name, unsigned int namelen,
const char *value, unsigned int valuelen);
extern const prop_info *__system_property_find(const char *name);
extern prop_area *__system_property_area__;
extern int __system_property_update(prop_info *pi, const char *value, unsigned int len);
void usage() {
printf("usage: mprop property_name property_value\n");
}
int main(int argc,char **argv){
sleep(30);
printf("start....\n");
const int fd = open("/dev/__properties__",
O_RDWR | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
if (argc!=3) {
usage();
return -1;
}
if (strlen(argv[1])+1>PROP_NAME_MAX) {
printf("property name is to long\n");
return -1;
}
if (sizeof(argv[2])+1>PROP_VALUE_MAX) {
printf("property value is to long\n");
return -1;
}
if (fd<0) {
perror("open");
return -1;
}
struct stat fd_stat;
if (fstat(fd, &fd_stat) <0) {
perror("fstat");
return -1;
}
if (!S_ISREG(fd_stat.st_mode)) {
printf("internal error\n");
return -1;
}
void *memory_area = mmap(NULL, fd_stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
__system_property_area__ = (prop_area *)memory_area;
printf("mapd...\n");
char value[PROP_VALUE_MAX];
bool update = true;
if(__system_property_get(argv[1],value)<=0) {
update = false;
printf("update falsei\n");
}
if (update) {
printf("old value : %s\n",value);
prop_info *pinfo = const_cast(__system_property_find(argv[1]));
if (!pinfo){
printf("internal error\n");
return -1;
}
if(__system_property_update(pinfo,argv[2],strlen(argv[2]))) {
printf("update error\n");
return -1;
}
} else {
printf("add value: name:%s value:%s\n",argv[1],argv[2]);
if(__system_property_add(argv[1],strlen(argv[1]),argv[2],strlen(argv[2]))) {
printf("update error\n");
return -1;
}
}
printf("new value %s\n",argv[2]);
return 0;
}
android ro.debuggable属性调试修改(mprop逆向) https://bbs.pediy.com/thread-246081.htm
http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/os/Process.java#start