int run_program(char *filename,uint32_t limit4k){ uint8_t *file_buffer; uint8_t file; uint32_t task_id; int loadelf_return; file_t fileinfo; entry_t entry; fileinfo = file_info(filename); uint8_t *task_base_address; if(fileinfo.status != 0){ print_string("Read file failed."); return -1; } file_buffer = malloc(fileinfo.item.size); if(file_buffer == NULL){ return -3; } file = read_file(filename,(uint8_t *)file_buffer,fileinfo.item.size); if(file != 0){ print_string("Read file failed."); return -2; } entry = get_elf_entry((uint8_t *)file_buffer); free(file_buffer); if(limit4k > 0){ task_base_address = (uint8_t *)malloc(limit4k*4096); if(task_base_address == NULL){ return -3; } if(loadelf_return = loadelf((uint8_t *)file_buffer,(uint8_t *)task_base_address,fileinfo.item.size)){ return -3-loadelf_return; } task_id = new_task((uint32_t)task_base_address,limit4k,entry,limit4k*4096); }else{ task_base_address = (uint8_t *)malloc(DEFAULT_TASK_LIMIT_4K*4096); if(task_base_address == NULL){ return -3; } print_hex((uint32_t)task_base_address); if(loadelf_return = loadelf((uint8_t *)file_buffer,(uint8_t *)task_base_address,fileinfo.item.size)){ return -3-loadelf_return; } task_id = new_task((uint32_t)task_base_address,DEFAULT_TASK_LIMIT_4K,entry,DEFAULT_TASK_LIMIT_4K*4096); } return task_id; }
static void __create_task_mm(task_t *task, int num, init_server_t *srv) { struct bin_map *emap = get_elf_map(task,srv); per_task_data_t *ptd; vmm_t *vmm = task->task_mm; ulong_t entry = get_elf_entry(task,srv); struct bin_map *cur = emap; ulong_t sseek = 0, psize; void *sbss; int r, flags, kflags; int *argc; uintptr_t ustack_top; uintptr_t *argv, *envp; char *arg1, *envp1; if(!emap) panic("[Service start] Cannot load ELF map of module %d\n", num); /* map image sections */ while(cur) { /* check for override */ if(cur->prev && (cur->virt_addr < PAGE_ALIGN(cur->prev->virt_addr + cur->prev->size))) { sseek = PAGE_ALIGN(cur->virt_addr) - cur->virt_addr; cur->bin_addr += sseek; cur->virt_addr = PAGE_ALIGN(cur->virt_addr); cur->size -= sseek; /* if it's NO_BITS section it should be zeroed */ if(cur->type == SHT_NOBITS) { sbss = user_to_kernel_vaddr(task_get_rpd(task), PAGE_ALIGN_DOWN(cur->virt_addr - sseek)); memset((sbss + PAGE_SIZE) - sseek, 0, sseek); } } /* create vm range for this region */ flags = VMR_PRIVATE | VMR_FIXED; kflags = 0; if(cur->flags & ESH_EXEC) { flags |= VMR_EXEC; kflags |= KMAP_EXEC; } flags |= VMR_READ; kflags |= KMAP_READ; if(cur->flags & ESH_WRITE) { flags |= VMR_WRITE; kflags |= KMAP_WRITE; } if((cur->type == SHT_NOBITS) || (cur->flags & ESH_WRITE)) flags |= VMR_POPULATE; psize = (cur->size + (cur->virt_addr - PAGE_ALIGN_DOWN(cur->virt_addr))) >> PAGE_WIDTH; if(psize<<PAGE_WIDTH < (cur->size + (cur->virt_addr - PAGE_ALIGN_DOWN(cur->virt_addr)))) psize++; #if 0 kprintf("Mapping vmrange %p - %p\n", PAGE_ALIGN_DOWN(cur->virt_addr), PAGE_ALIGN_DOWN(cur->virt_addr) + (psize << PAGE_WIDTH)); #endif r = vmrange_map(generic_memobj, vmm, PAGE_ALIGN_DOWN(cur->virt_addr), psize, flags, 0); if(!PAGE_ALIGN(r)) panic("Server [#%d]: Failed to create VM range for section. (ERR = %d)", num, r); if(cur->type == SHT_PROGBITS) { if(cur->flags & ESH_WRITE) { #if 0 kprintf("Copying to %p kaddr (%p uaddr) from %p baddr(%p kaddr) (%ld size)\n", user_to_kernel_vaddr(task_get_rpd(task), PAGE_ALIGN_DOWN(cur->virt_addr)), PAGE_ALIGN_DOWN(cur->virt_addr), PAGE_ALIGN_DOWN(cur->bin_addr), pframe_id_to_virt((PAGE_ALIGN_DOWN(cur->bin_addr))>>PAGE_WIDTH), psize << PAGE_WIDTH); #endif memcpy((void *)user_to_kernel_vaddr(task_get_rpd(task), PAGE_ALIGN_DOWN(cur->virt_addr)), (const void *)pframe_id_to_virt((PAGE_ALIGN_DOWN(cur->bin_addr))>>PAGE_WIDTH), psize << PAGE_WIDTH); r = 0; } else { #if 0 kprintf("Mapping range %p - %p (%p - %p)\n", PAGE_ALIGN_DOWN(cur->bin_addr), PAGE_ALIGN_DOWN(cur->bin_addr) + (psize << PAGE_WIDTH), PAGE_ALIGN_DOWN(cur->bin_addr - srv->addr), PAGE_ALIGN_DOWN(cur->bin_addr - srv->addr) + (psize << PAGE_WIDTH)); #endif r = mmap_core(vmm, PAGE_ALIGN_DOWN(cur->virt_addr), PAGE_ALIGN_DOWN(cur->bin_addr) >> PAGE_WIDTH, psize, kflags); } if(r) panic("Server [#%d]: Failed to map section. (ERR = %d)", num, r); }
int main(int argc, char **argv, char **envp) { if (argc < 3) { printUsage("Not enough arguments."); return EXIT_SUCCESS; } unsigned long long entrypoint = get_elf_entry(argv[2]); pid_t pid; pid = fork(); if (pid < 0) { printf("Fork failed.\n"); return EXIT_FAILURE; } else if (pid == 0) { /* We are the child. */ ptrace(PTRACE_TRACEME, 0, NULL, NULL); kill(getpid(), SIGSTOP); execve(argv[2], argv+2, envp); /* Apparently the execve causes a SIGTRAP to be sent. */ } else { /* We are the parent. */ /* Wait for execve to finish. */ wait_for_stop(pid); //long ret = 0; //ret = ptrace(PTRACE_ATTACH, pid, 0, 0); //if (ret != 0) { // perror("Failed ptrace() attach."); // exit(EXIT_FAILURE); //} //wait_for_stop(pid); struct user_regs_struct regs; //ptrace(PTRACE_SYSCALL, pid, 0, 0); //wait_for_stop(pid); //long syscall = ptrace(PTRACE_PEEKUSER, pid, sizeof(long)*ORIG_EAX); //printf("EAX: %ld\n", syscall); //ptrace(PTRACE_SYSCALL, pid, 0, 0); //wait_for_stop(pid); //ptrace(PTRACE_GETREGS, pid, NULL, ®s); //printf("EAX: %lx\n", regs.rax); int hit_entrypoint = 0; FILE *output = fopen(argv[1], "w"); if (output == NULL) { perror("Error opening output file."); return EXIT_FAILURE; } while (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) == 0) { wait_for_stop(pid); if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) != 0) { perror("Error getting regs."); } if (regs.rip == entrypoint) { hit_entrypoint = 1; } if (hit_entrypoint) { fprintf(output, "%llx\n", regs.rip); // XXX } } fclose(output); perror("wat"); } return EXIT_SUCCESS; }