Advertisement
Guest User

process dumping with ptrace

a guest
Aug 31st, 2016
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.22 KB | None | 0 0
  1. /*
  2.        
  3.                     Dump running process memory using ptrace!
  4.                 Thanks to Cturt for the idea and hitodama for the SDK!
  5.  
  6.         Build with https://github.com/ps4dev/ps4sdk just like with the other sdk examples
  7.     Use TCP-Dump or other desired tool to listen/capture binary dump on desired port/IP specified below..
  8.        
  9.         This does not contain priv escalation so you will need to run kernel_execute from the sdk.
  10.        
  11.     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!IMPORTANT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  12.  
  13.        kernel_execute from ps4sdk must have additional privilege escalation included and built into the sdk..
  14.  
  15.     Replace ps4KernelPrivilegeUnjail in https://github.com/ps4dev/ps4sdk/common/kernel/source/kernel/privilage.c
  16.                     with this || and run make clean/make on ps4sdk!
  17.                           ||   
  18.                           \/
  19.                            
  20.  
  21.             int ps4KernelPrivilegeUnjail()
  22.             {
  23.                 struct thread *td;
  24.                 struct filedesc *fd;
  25.                 struct ucred *cr;
  26.                 void *t;
  27.  
  28.                 ps4KernelThreadGetCurrent(&td);
  29.  
  30.                 ps4ExpressionReturnOnError(ps4KernelSymbolLookUp("prison0", &t));
  31.                 cr = td->td_proc->p_ucred;
  32.                 cr->cr_prison = (struct prison *)t;
  33.  
  34.                 void *td_ucred = *(void **)(((char *)td) + 304); // p_ucred == td_ucred
  35.    
  36.                 // sceSblACMgrIsSystemUcred
  37.                 uint64_t *sonyCred = (uint64_t *)(((char *)td_ucred) + 96);
  38.                 *sonyCred = 0xffffffffffffffff;
  39.    
  40.                 // sceSblACMgrGetDeviceAccessType
  41.                 uint64_t *sceProcType = (uint64_t *)(((char *)td_ucred) + 88);
  42.                 *sceProcType = 0x3801000000000013; // Max access
  43.    
  44.                 // sceSblACMgrHasSceProcessCapability
  45.                 uint64_t *sceProcCap = (uint64_t *)(((char *)td_ucred) + 104);
  46.                 *sceProcCap = 0xffffffffffffffff; // Sce Process
  47.    
  48.                 ((uint64_t *)0xFFFFFFFF832CC2E8)[0] = 0x123456; //priv_check_cred bypass with suser_enabled=true
  49.                 ((uint64_t *)0xFFFFFFFF8323DA18)[0] = 0; // bypass priv_check
  50.  
  51.                 ps4ExpressionReturnOnError(ps4KernelSymbolLookUp("rootvnode", &t));
  52.                 fd = td->td_proc->p_fd;
  53.                 //fd->fd_cdir =
  54.                 fd->fd_rdir = fd->fd_jdir = *(struct vnode **)t;
  55.  
  56.                 return PS4_OK;
  57.             }
  58.  
  59.  
  60.  
  61. */
  62.  
  63. #include <stdlib.h>
  64. #include <stdio.h>
  65. #include <string.h>
  66. #include <stdint.h>
  67.  
  68. #include <unistd.h>
  69.  
  70. #include <arpa/inet.h>
  71. #include <netinet/in.h>
  72.  
  73. #include <sys/mman.h>
  74. #include <sys/sysctl.h>
  75. #include <sys/ptrace.h>
  76. #include <sys/errno.h>
  77. #include <sys/proc.h>
  78. #include <sys/user.h>
  79. #include <sys/uio.h>
  80.  
  81. #include <ps4/kernel.h>
  82.  
  83. /* Defines */
  84.  
  85. #define MAP_ANON     0x1000 /* allocated from memory, swap space */
  86. #define MAP_ANONYMOUS    MAP_ANON
  87.  
  88. #define IP(a, b, c, d) (((a) << 0) + ((b) << 8) + ((c) << 16) + ((d) << 24))
  89. #define TCP_NODELAY 1
  90.  
  91.  
  92. static void *readbuf;
  93.  
  94.  
  95. /* Standard function for reading VM MAP structures*/
  96.  
  97. struct kinfo_vmentry *
  98. kinfo_getvmmap(pid_t pid, int *cntp)
  99. {
  100.     int mib[4];
  101.     int error;
  102.     int cnt;
  103.     size_t len;
  104.     char *buf, *bp, *eb;
  105.     struct kinfo_vmentry *kiv, *kp, *kv;
  106.  
  107.     *cntp = 0;
  108.     len = 0;
  109.     mib[0] = CTL_KERN;
  110.     mib[1] = KERN_PROC;
  111.     mib[2] = KERN_PROC_VMMAP;
  112.     mib[3] = pid;
  113.  
  114.     error = sysctl(mib, 4, NULL, &len, NULL, 0);
  115.     if (error)
  116.         return (NULL);
  117.     len = len * 4 / 3;
  118.     buf = malloc(len);
  119.     if (buf == NULL)
  120.         return (NULL);
  121.     error = sysctl(mib, 4, buf, &len, NULL, 0);
  122.     if (error) {
  123.         free(buf);
  124.         return (NULL);
  125.     }
  126.     /* Pass 1: count items */
  127.     cnt = 0;
  128.     bp = buf;
  129.     eb = buf + len;
  130.     while (bp < eb) {
  131.         kv = (struct kinfo_vmentry *)(uintptr_t)bp;
  132.         if (kv->kve_structsize == 0)
  133.             break;
  134.         bp += kv->kve_structsize;
  135.         cnt++;
  136.     }
  137.  
  138.     kiv = calloc(cnt, sizeof(*kiv));
  139.     if (kiv == NULL) {
  140.         free(buf);
  141.         return (NULL);
  142.     }
  143.     bp = buf;
  144.     eb = buf + len;
  145.     kp = kiv;
  146.     /* Pass 2: unpack */
  147.     while (bp < eb) {
  148.         kv = (struct kinfo_vmentry *)(uintptr_t)bp;
  149.         if (kv->kve_structsize == 0)
  150.             break;
  151.         /* Copy/expand into pre-zeroed buffer */
  152.         memcpy(kp, kv, kv->kve_structsize);
  153.         /* Advance to next packed record */
  154.         bp += kv->kve_structsize;
  155.         /* Set field size to fixed length, advance */
  156.         kp->kve_structsize = sizeof(*kp);
  157.         kp++;
  158.     }
  159.     free(buf);
  160.     *cntp = cnt;
  161.     return (kiv);   /* Caller must free() return value */
  162. }
  163.  
  164.  
  165.  
  166.  
  167. int main(int argc, char **argv)
  168. {
  169.    
  170. /* Method to retreive PIDs and Threads */
  171.  
  172.     int pid, mib[4];
  173.     int dumpPID;
  174.  
  175.     char *PIDname = "eboot.bin";
  176.  
  177.     for (pid = 0; pid < 100; pid++){
  178.    
  179.     mib[0] = CTL_KERN;
  180.     mib[1] = KERN_PROC;
  181.     mib[2] = KERN_PROC_PID;
  182.     mib[3] = pid;
  183.  
  184.     size_t len;
  185.     len = 0x45000;
  186.     char *dump;
  187.  
  188.     dump = malloc(len);
  189.    
  190.         if(sysctl(mib, 4, dump, &len, NULL, 0) == -1) {
  191.         printf("   [-] PID %2d ----------------------------------------------------->\t", pid);
  192.         perror("sysctl");
  193.         }
  194.         else if(len > 0) {
  195.         char *processName = dump + 0x1bf;
  196.         char *threadName = dump + 0x18a;
  197.  
  198.         printf("   [+] PID %2d  NAME: %25s  THREAD: %15s\n", pid, processName, threadName);
  199.    
  200.         if(strcmp(processName, PIDname) == 0) dumpPID = pid;
  201.  
  202.     free(dump);
  203.     }
  204. }
  205.  
  206.  
  207.  
  208. /* Method to setup mappings for ptrace to read*/
  209.  
  210.     struct kinfo_vmentry *kvm0, *kvm;
  211.     int d, cnt, w = 0;
  212.     uint64_t start[1024];
  213.     uint64_t stop[1024];
  214.     uint64_t offsets[1024];
  215.     uint64_t sizes[1024];
  216.     memset(sizes, 0, sizeof(sizes));
  217.     memset(start, 0, sizeof(start));
  218.     memset(stop, 0, sizeof(stop));
  219.     memset(offsets, 0, sizeof(offsets));
  220.  
  221.  
  222.     kvm0 = kinfo_getvmmap(dumpPID, &cnt);
  223.  
  224.     printf("    [+] vm entry list if for %s\n", PIDname);
  225.     for (d = 0, kvm = kvm0; d<cnt; d++, kvm++, w++){
  226.         printf("        [+] process start is: 0x%016llX and process end is: 0x%016llX\n", kvm->kve_start, kvm->kve_end);
  227.         printf("        [+] process location in memory is: 0x%016llX\n", kvm->kve_offset);
  228.  
  229.            
  230.         start[w] = kvm->kve_start;         
  231.         stop[w] = kvm->kve_end;
  232.         offsets[w] = kvm->kve_offset;
  233.     }
  234.  
  235. /* Print out process vm mapping info for debug */
  236.  
  237.     printf( "[-]type is:%d\n"
  238.         "[-]offset is:0x%016llX\n"
  239.         "[-]fileid is:0x%016llX\n"
  240.         "[-]fsid is:0x%016llX\n"
  241.         "[-]flags are:%d\n"
  242.         "[-]resident page number:%d\n"
  243.         "[-]# of priv pages:%d\n"
  244.         "[-]proc bitmask:%d\n"
  245.         "[-]vm obj ref count:%d\n"
  246.         "[-]vm shadow count:%d\n"
  247.         "[-]vnode type:%d\n"
  248.         "[-]file size:0x%016llX\n"
  249.         "[-]device id:0x%016llX\n"
  250.         "[-]file mode:0x%016llX\n"
  251.         "[-]kve status:0x%016llX\n"
  252.  
  253.         ,kvm->kve_type
  254.         ,kvm->kve_offset
  255.         ,kvm->kve_vn_fileid
  256.         ,kvm->kve_vn_fsid
  257.         ,kvm->kve_flags
  258.         ,kvm->kve_resident
  259.         ,kvm->kve_private_resident
  260.         ,kvm->kve_protection
  261.         ,kvm->kve_ref_count
  262.         ,kvm->kve_shadow_count
  263.         ,kvm->kve_vn_type
  264.         ,kvm->kve_vn_size
  265.         ,kvm->kve_vn_rdev
  266.         ,kvm->kve_vn_mode
  267.         ,kvm->kve_status);
  268.        
  269.     printf("   [+] value 0 of start is: 0x%016llX\n    and value 0 of stop is: 0x%016llX\n", start[0], stop[0]);
  270.        
  271.  
  272.  
  273. /* Create socket for TCP-Dump */
  274.  
  275.     struct sockaddr_in server;       
  276.  
  277.     server.sin_len = sizeof(server);
  278.     server.sin_family = AF_INET;
  279.     server.sin_addr.s_addr = IP(192, 168, 1, 64);
  280.     server.sin_port = htons(9023);
  281.     memset(server.sin_zero, 0, sizeof(server.sin_zero));
  282.     int sock = socket(AF_INET, SOCK_STREAM, 0);
  283.     connect(sock, (struct sockaddr *)&server, sizeof(server));
  284.  
  285.    
  286.     int flag = 1;
  287.     setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
  288.  
  289.  
  290. /* Method to trace process and dump its memory locations */
  291.  
  292.     int x;
  293.     int result = ptrace(PT_ATTACH, dumpPID, NULL, 0);
  294.     printf("   [+] Attaching to process with result: %d\n", result);
  295.     if(result == -1)perror("ptrace");
  296.    
  297.     for(x = 0; stop[x] != 0; x++){
  298.         uint64_t end         = stop[x];
  299.         uint64_t destination = start[x];
  300.         uint64_t mappingSize = end - destination;
  301.         uint64_t mappingAddress = destination;
  302.         uint64_t DUMP_SIZE = mappingSize;
  303.         uint64_t offset;
  304.  
  305.             struct ptrace_io_desc pt_desc;
  306.             readbuf = mmap(NULL, mappingSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
  307.  
  308.             for(offset = mappingAddress; offset < mappingAddress + mappingSize; offset += DUMP_SIZE) {
  309.                 pt_desc.piod_op = PIOD_READ_D;
  310.                 pt_desc.piod_addr = readbuf;
  311.                 pt_desc.piod_offs = offset;
  312.                 pt_desc.piod_len = DUMP_SIZE;
  313.    
  314.                 int ret = ptrace(PT_IO, dumpPID, &pt_desc, 0);
  315.                 if(!ret) send(sock, readbuf, pt_desc.piod_len, 0);
  316.  
  317.             }                  
  318.         }
  319.  
  320. /* Detatch from proccess after dump is complete */
  321.  
  322.     int endResult = ptrace(PT_DETACH, dumpPID, NULL, 0);
  323.     printf("   [+] Detaching from process: %d\n", endResult);
  324.        
  325.        
  326.  
  327. /* Close sockets and free the mapped memory */
  328. close(sock);
  329. free(kvm0);
  330.  
  331.  
  332. return EXIT_SUCCESS;
  333.  
  334. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement