Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Dump running process memory using ptrace!
- Thanks to Cturt for the idea and hitodama for the SDK!
- Build with https://github.com/ps4dev/ps4sdk just like with the other sdk examples
- Use TCP-Dump or other desired tool to listen/capture binary dump on desired port/IP specified below..
- This does not contain priv escalation so you will need to run kernel_execute from the sdk.
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!IMPORTANT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- kernel_execute from ps4sdk must have additional privilege escalation included and built into the sdk..
- Replace ps4KernelPrivilegeUnjail in https://github.com/ps4dev/ps4sdk/common/kernel/source/kernel/privilage.c
- with this || and run make clean/make on ps4sdk!
- ||
- \/
- int ps4KernelPrivilegeUnjail()
- {
- struct thread *td;
- struct filedesc *fd;
- struct ucred *cr;
- void *t;
- ps4KernelThreadGetCurrent(&td);
- ps4ExpressionReturnOnError(ps4KernelSymbolLookUp("prison0", &t));
- cr = td->td_proc->p_ucred;
- cr->cr_prison = (struct prison *)t;
- void *td_ucred = *(void **)(((char *)td) + 304); // p_ucred == td_ucred
- // sceSblACMgrIsSystemUcred
- uint64_t *sonyCred = (uint64_t *)(((char *)td_ucred) + 96);
- *sonyCred = 0xffffffffffffffff;
- // sceSblACMgrGetDeviceAccessType
- uint64_t *sceProcType = (uint64_t *)(((char *)td_ucred) + 88);
- *sceProcType = 0x3801000000000013; // Max access
- // sceSblACMgrHasSceProcessCapability
- uint64_t *sceProcCap = (uint64_t *)(((char *)td_ucred) + 104);
- *sceProcCap = 0xffffffffffffffff; // Sce Process
- ((uint64_t *)0xFFFFFFFF832CC2E8)[0] = 0x123456; //priv_check_cred bypass with suser_enabled=true
- ((uint64_t *)0xFFFFFFFF8323DA18)[0] = 0; // bypass priv_check
- ps4ExpressionReturnOnError(ps4KernelSymbolLookUp("rootvnode", &t));
- fd = td->td_proc->p_fd;
- //fd->fd_cdir =
- fd->fd_rdir = fd->fd_jdir = *(struct vnode **)t;
- return PS4_OK;
- }
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdint.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/mman.h>
- #include <sys/sysctl.h>
- #include <sys/ptrace.h>
- #include <sys/errno.h>
- #include <sys/proc.h>
- #include <sys/user.h>
- #include <sys/uio.h>
- #include <ps4/kernel.h>
- /* Defines */
- #define MAP_ANON 0x1000 /* allocated from memory, swap space */
- #define MAP_ANONYMOUS MAP_ANON
- #define IP(a, b, c, d) (((a) << 0) + ((b) << 8) + ((c) << 16) + ((d) << 24))
- #define TCP_NODELAY 1
- static void *readbuf;
- /* Standard function for reading VM MAP structures*/
- struct kinfo_vmentry *
- kinfo_getvmmap(pid_t pid, int *cntp)
- {
- int mib[4];
- int error;
- int cnt;
- size_t len;
- char *buf, *bp, *eb;
- struct kinfo_vmentry *kiv, *kp, *kv;
- *cntp = 0;
- len = 0;
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_VMMAP;
- mib[3] = pid;
- error = sysctl(mib, 4, NULL, &len, NULL, 0);
- if (error)
- return (NULL);
- len = len * 4 / 3;
- buf = malloc(len);
- if (buf == NULL)
- return (NULL);
- error = sysctl(mib, 4, buf, &len, NULL, 0);
- if (error) {
- free(buf);
- return (NULL);
- }
- /* Pass 1: count items */
- cnt = 0;
- bp = buf;
- eb = buf + len;
- while (bp < eb) {
- kv = (struct kinfo_vmentry *)(uintptr_t)bp;
- if (kv->kve_structsize == 0)
- break;
- bp += kv->kve_structsize;
- cnt++;
- }
- kiv = calloc(cnt, sizeof(*kiv));
- if (kiv == NULL) {
- free(buf);
- return (NULL);
- }
- bp = buf;
- eb = buf + len;
- kp = kiv;
- /* Pass 2: unpack */
- while (bp < eb) {
- kv = (struct kinfo_vmentry *)(uintptr_t)bp;
- if (kv->kve_structsize == 0)
- break;
- /* Copy/expand into pre-zeroed buffer */
- memcpy(kp, kv, kv->kve_structsize);
- /* Advance to next packed record */
- bp += kv->kve_structsize;
- /* Set field size to fixed length, advance */
- kp->kve_structsize = sizeof(*kp);
- kp++;
- }
- free(buf);
- *cntp = cnt;
- return (kiv); /* Caller must free() return value */
- }
- int main(int argc, char **argv)
- {
- /* Method to retreive PIDs and Threads */
- int pid, mib[4];
- int dumpPID;
- char *PIDname = "eboot.bin";
- for (pid = 0; pid < 100; pid++){
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = pid;
- size_t len;
- len = 0x45000;
- char *dump;
- dump = malloc(len);
- if(sysctl(mib, 4, dump, &len, NULL, 0) == -1) {
- printf(" [-] PID %2d ----------------------------------------------------->\t", pid);
- perror("sysctl");
- }
- else if(len > 0) {
- char *processName = dump + 0x1bf;
- char *threadName = dump + 0x18a;
- printf(" [+] PID %2d NAME: %25s THREAD: %15s\n", pid, processName, threadName);
- if(strcmp(processName, PIDname) == 0) dumpPID = pid;
- free(dump);
- }
- }
- /* Method to setup mappings for ptrace to read*/
- struct kinfo_vmentry *kvm0, *kvm;
- int d, cnt, w = 0;
- uint64_t start[1024];
- uint64_t stop[1024];
- uint64_t offsets[1024];
- uint64_t sizes[1024];
- memset(sizes, 0, sizeof(sizes));
- memset(start, 0, sizeof(start));
- memset(stop, 0, sizeof(stop));
- memset(offsets, 0, sizeof(offsets));
- kvm0 = kinfo_getvmmap(dumpPID, &cnt);
- printf(" [+] vm entry list if for %s\n", PIDname);
- for (d = 0, kvm = kvm0; d<cnt; d++, kvm++, w++){
- printf(" [+] process start is: 0x%016llX and process end is: 0x%016llX\n", kvm->kve_start, kvm->kve_end);
- printf(" [+] process location in memory is: 0x%016llX\n", kvm->kve_offset);
- start[w] = kvm->kve_start;
- stop[w] = kvm->kve_end;
- offsets[w] = kvm->kve_offset;
- }
- /* Print out process vm mapping info for debug */
- printf( "[-]type is:%d\n"
- "[-]offset is:0x%016llX\n"
- "[-]fileid is:0x%016llX\n"
- "[-]fsid is:0x%016llX\n"
- "[-]flags are:%d\n"
- "[-]resident page number:%d\n"
- "[-]# of priv pages:%d\n"
- "[-]proc bitmask:%d\n"
- "[-]vm obj ref count:%d\n"
- "[-]vm shadow count:%d\n"
- "[-]vnode type:%d\n"
- "[-]file size:0x%016llX\n"
- "[-]device id:0x%016llX\n"
- "[-]file mode:0x%016llX\n"
- "[-]kve status:0x%016llX\n"
- ,kvm->kve_type
- ,kvm->kve_offset
- ,kvm->kve_vn_fileid
- ,kvm->kve_vn_fsid
- ,kvm->kve_flags
- ,kvm->kve_resident
- ,kvm->kve_private_resident
- ,kvm->kve_protection
- ,kvm->kve_ref_count
- ,kvm->kve_shadow_count
- ,kvm->kve_vn_type
- ,kvm->kve_vn_size
- ,kvm->kve_vn_rdev
- ,kvm->kve_vn_mode
- ,kvm->kve_status);
- printf(" [+] value 0 of start is: 0x%016llX\n and value 0 of stop is: 0x%016llX\n", start[0], stop[0]);
- /* Create socket for TCP-Dump */
- struct sockaddr_in server;
- server.sin_len = sizeof(server);
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = IP(192, 168, 1, 64);
- server.sin_port = htons(9023);
- memset(server.sin_zero, 0, sizeof(server.sin_zero));
- int sock = socket(AF_INET, SOCK_STREAM, 0);
- connect(sock, (struct sockaddr *)&server, sizeof(server));
- int flag = 1;
- setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
- /* Method to trace process and dump its memory locations */
- int x;
- int result = ptrace(PT_ATTACH, dumpPID, NULL, 0);
- printf(" [+] Attaching to process with result: %d\n", result);
- if(result == -1)perror("ptrace");
- for(x = 0; stop[x] != 0; x++){
- uint64_t end = stop[x];
- uint64_t destination = start[x];
- uint64_t mappingSize = end - destination;
- uint64_t mappingAddress = destination;
- uint64_t DUMP_SIZE = mappingSize;
- uint64_t offset;
- struct ptrace_io_desc pt_desc;
- readbuf = mmap(NULL, mappingSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- for(offset = mappingAddress; offset < mappingAddress + mappingSize; offset += DUMP_SIZE) {
- pt_desc.piod_op = PIOD_READ_D;
- pt_desc.piod_addr = readbuf;
- pt_desc.piod_offs = offset;
- pt_desc.piod_len = DUMP_SIZE;
- int ret = ptrace(PT_IO, dumpPID, &pt_desc, 0);
- if(!ret) send(sock, readbuf, pt_desc.piod_len, 0);
- }
- }
- /* Detatch from proccess after dump is complete */
- int endResult = ptrace(PT_DETACH, dumpPID, NULL, 0);
- printf(" [+] Detaching from process: %d\n", endResult);
- /* Close sockets and free the mapped memory */
- close(sock);
- free(kvm0);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement