/** * get_sw_id_from_component_bin_elf() parses the ELF header to get the MBN header * of the hash table segment. Parses the MBN header of hash table segment & checks * total size v/s actual component size. If both differ, it means signature & * certificates are appended at end. * Extract the attestation certificate & read the Subject & retreive the SW_ID. * * @bin_file: struct image_section * */ int get_sw_id_from_component_bin_elf(struct image_section *section) { Elf32_Ehdr *elf; Elf32_Phdr *phdr; Mbn_Hdr *mbn_hdr; uint8_t *fp; int cert_offset; char *sw_version; if (!process_elf(section->file, &fp, &elf, &phdr, &mbn_hdr)) { return 0; } cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + 40; printf("Image with version information\n"); sw_version = find_value(fp + phdr->p_offset + cert_offset, "SW_ID", 17); if (sw_version) { sw_version[8] = '\0'; sscanf(sw_version, "%x", §ion->img_version); printf("SW ID:%d\n", section->img_version); free(sw_version); } return 1; }
int main(int argc, char **argv) { int i; if (argc < 2) { (void) printf("usage: %s elf_file ...\n", argv[0]); return (1); } /* * Initialize the elf library, must be called before elf_begin() * can be called. */ if (elf_version(EV_CURRENT) == EV_NONE) { (void) fprintf(stderr, "elf_version() failed: %s\n", elf_errmsg(0)); return (1); } for (i = 1; i < argc; i++) { int fd; Elf *elf; char *elf_fname; elf_fname = argv[i]; if ((fd = open(elf_fname, O_RDONLY)) == -1) { perror("open"); continue; } /* * Attempt to open an Elf descriptor Read-Only * for each file. */ if ((elf = elf_begin(fd, ELF_C_READ, 0)) == NULL) { (void) fprintf(stderr, "elf_begin() failed: %s\n", elf_errmsg(0)); (void) close(fd); continue; } /* * Process each elf descriptor. */ process_elf(elf, elf_fname, fd, 0); (void) elf_end(elf); (void) close(fd); } return (0); }
static void process_elf(Elf *elf, char *file, int fd, int member) { Elf_Cmd cmd; Elf *_elf; switch (elf_kind(elf)) { case ELF_K_ELF: /* * This is an ELF file, now attempt to find it's * .comment section and to display it. */ print_symtab(elf, file); break; case ELF_K_AR: /* * Archives contain multiple ELF files, which can each * in turn be examined with libelf. * * The below loop will iterate over each member of the * archive and recursively call process_elf(). */ cmd = ELF_C_READ; while ((_elf = elf_begin(fd, cmd, elf)) != NULL) { Elf_Arhdr *arhdr; char buffer[1024]; arhdr = elf_getarhdr(_elf); /* * Build up file names based off of * 'archivename(membername)'. */ (void) snprintf(buffer, 1024, "%s(%s)", file, arhdr->ar_name); /* * Recursively process the ELF members. */ process_elf(_elf, buffer, fd, 1); cmd = elf_next(_elf); (void) elf_end(_elf); } break; default: if (!member) (void) fprintf(stderr, "%s: unexpected elf_kind(): 0x%x\n", file, elf_kind(elf)); return; } }
/** * split_code_signature_cert_from_component_bin_elf splits the component * binary by splitting into code(including ELF header), signature file & * attenstation certificate. * * @bin_file: char * * @src: char * * @sig: char * * @cert: char * */ int split_code_signature_cert_from_component_bin_elf(struct image_section *section, char **src, char **sig, char **cert) { Elf32_Ehdr *elf; Elf32_Phdr *phdr; Mbn_Hdr *mbn_hdr; uint8_t *fp; int sig_offset; int cert_offset; int len; if (!process_elf(section->file, &fp, &elf, &phdr, &mbn_hdr)) { return 0; } sig_offset = mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE; len = MBN_HDR_SIZE + sig_offset; *src = malloc((len + 1) * sizeof(char)); if (*src == NULL) { return 0; } memcpy(*src, fp + phdr->p_offset, len); src_size = len; (*src)[len] = '\0'; *sig = malloc((SIG_SIZE + 1) * sizeof(char)); if (*sig == NULL) { free(*src); return 0; } memcpy(*sig, fp + phdr->p_offset + sig_offset, SIG_SIZE); (*sig)[SIG_SIZE] = '\0'; cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE; *cert = malloc((CERT_SIZE + 1) * sizeof(char)); if (*cert == NULL) { free(*src); free(*sig); return 0; } memcpy(*cert, fp + phdr->p_offset + cert_offset, CERT_SIZE); (*cert)[CERT_SIZE] = '\0'; return 1; }
int main(int argc, char **argv) { struct stat st; char *buffer; int fd, rc; if (argc != 2) { usage(argv[0]); return -1; } binary_file = argv[1]; fd = open(binary_file, O_RDONLY); if (fd < 0) { printf("error: unable to open file\n"); return -1; } rc = fstat(fd, &st); if (rc) { close(fd); printf("error: unable to stat file\n"); return -1; } buffer = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); if (!buffer) { printf("error: unable to map file\n"); return -1; } rc = process_elf(buffer, st.st_size); munmap(buffer, st.st_size); return rc; }
int main (int argc, char **argv) { unsigned int mapfile_fd; hash_node **hashtable; char reverse_mode; if (hash_initialize(&hashtable) == ACRELCONVERT_FUNC_ERROR) exit(EXIT_FAILURE); if (process_parameters(argc, argv, &reverse_mode) == ACRELCONVERT_FUNC_ERROR) exit(EXIT_FAILURE); if ((mapfile_fd = open(argv[2], 0)) == -1) { fprintf(stderr, "Fatal error while opening map file \"%s\"\n", argv[2]); exit(EXIT_FAILURE); } if (process_map_file(mapfile_fd, hashtable, reverse_mode) == ACRELCONVERT_FUNC_ERROR) { close(mapfile_fd); exit(EXIT_FAILURE); } close(mapfile_fd); if (process_elf(argv[3], hashtable) == ACRELCONVERT_FUNC_ERROR) { hash_delete (&hashtable); exit(EXIT_FAILURE); } hash_delete (&hashtable); exit(EXIT_SUCCESS); }
int do_exec(task_t *t, char *path, char **argv, char **env) { unsigned int i=0; addr_t end, eip; unsigned int argc=0, envc=0; int desc; char **backup_argv=0, **backup_env=0; /* Sanity */ if(!t) panic(PANIC_NOSYNC, "Tried to execute with empty task"); if(t == kernel_task) panic(0, "Kernel is being executed at the gallows!"); if(t != current_task) panic(0, "I don't know, was really drunk at the time"); if(t->magic != TASK_MAGIC) panic(0, "Invalid task in exec (%d)", t->pid); if(!path || !*path) return -EINVAL; /* Load the file, and make sure that it is valid and accessable */ if(EXEC_LOG == 2) printk(0, "[%d]: Checking executable file (%s)\n", t->pid, path); struct file *efil; int err_open, num; efil=d_sys_open(path, O_RDONLY, 0, &err_open, &num); if(efil) desc = num; else desc = err_open; if(desc < 0 || !efil) return -ENOENT; if(!permissions(efil->inode, MAY_EXEC)) { sys_close(desc); return -EACCES; } /* Detirmine if the file is a valid ELF */ int header_size = 0; #if CONFIG_ARCH == TYPE_ARCH_X86_64 header_size = sizeof(elf64_header_t); #elif CONFIG_ARCH == TYPE_ARCH_X86 header_size = sizeof(elf32_header_t); #endif char mem[header_size]; read_data(desc, mem, 0, header_size); int other_bitsize=0; #if CONFIG_ARCH == TYPE_ARCH_X86_64 if(is_valid_elf32_otherarch(mem, 2)) other_bitsize = 1; #endif if(!is_valid_elf(mem, 2) && !other_bitsize) { sys_close(desc); return -ENOEXEC; } if(EXEC_LOG == 2) printk(0, "[%d]: Copy data\n", t->pid); /* okay, lets back up argv and env so that we can * clear out the address space and not lose data..*/ if(__is_valid_user_ptr(SYS_EXECVE, argv, 0)) { while(__is_valid_user_ptr(SYS_EXECVE, argv[argc], 0) && *argv[argc]) argc++; backup_argv = (char **)kmalloc(sizeof(addr_t) * argc); for(i=0;i<argc;i++) { backup_argv[i] = (char *)kmalloc(strlen(argv[i]) + 1); _strcpy(backup_argv[i], argv[i]); } } if(__is_valid_user_ptr(SYS_EXECVE, env, 0)) { while(__is_valid_user_ptr(SYS_EXECVE, env[envc], 0) && *env[envc]) envc++; backup_env = (char **)kmalloc(sizeof(addr_t) * envc); for(i=0;i<envc;i++) { backup_env[i] = (char *)kmalloc(strlen(env[i]) + 1); _strcpy(backup_env[i], env[i]); } } /* and the path too! */ char *path_backup = (char *)kmalloc(strlen(path) + 1); _strcpy((char *)path_backup, path); path = path_backup; if(pd_cur_data->count > 1) printk(0, "[exec]: Not sure what to do here...\n"); /* Preexec - This is the point of no return. Here we close out unneeded * file descs, free up the page directory and clear up the resources * of the task */ if(EXEC_LOG) printk(0, "Executing (task %d, cpu %d, tty %d, cwd=%s): %s\n", t->pid, ((cpu_t *)t->cpu)->apicid, t->tty, current_task->thread->pwd->name, path); preexec(t, desc); strncpy((char *)t->command, path, 128); if(other_bitsize) { #if CONFIG_ARCH == TYPE_ARCH_X86_64 if(!process_elf_other(mem, desc, &eip, &end)) eip=0; #endif } else if(!process_elf(mem, desc, &eip, &end)) eip=0; sys_close(desc); if(!eip) { printk(5, "[exec]: Tried to execute an invalid ELF file!\n"); free_dp(backup_argv, argc); free_dp(backup_env, envc); #if DEBUG panic(0, ""); #endif exit(0); } if(EXEC_LOG == 2) printk(0, "[%d]: Updating task values\n", t->pid); /* Setup the task with the proper values (libc malloc stack) */ addr_t end_l = end; end = (end&PAGE_MASK); user_map_if_not_mapped_noclear(end); /* now we need to copy back the args and env into userspace * writeable memory...yippie. */ addr_t args_start = end + PAGE_SIZE; addr_t env_start = args_start; addr_t alen = 0; if(backup_argv) { for(i=0;i<(sizeof(addr_t) * (argc+1))/PAGE_SIZE + 2;i++) user_map_if_not_mapped_noclear(args_start + i * PAGE_SIZE); memcpy((void *)args_start, backup_argv, sizeof(addr_t) * argc); alen += sizeof(addr_t) * argc; *(addr_t *)(args_start + alen) = 0; /* set last argument value to zero */ alen += sizeof(addr_t); argv = (char **)args_start; for(i=0;i<argc;i++) { char *old = argv[i]; char *new = (char *)(args_start+alen); user_map_if_not_mapped_noclear((addr_t)new); unsigned len = strlen(old) + 4; user_map_if_not_mapped_noclear((addr_t)new + len + 1); argv[i] = new; _strcpy(new, old); kfree(old); alen += len; } kfree(backup_argv); } env_start = args_start + alen; alen = 0; if(backup_env) { for(i=0;i<(((sizeof(addr_t) * (envc+1))/PAGE_SIZE) + 2);i++) user_map_if_not_mapped_noclear(env_start + i * PAGE_SIZE); memcpy((void *)env_start, backup_env, sizeof(addr_t) * envc); alen += sizeof(addr_t) * envc; *(addr_t *)(env_start + alen) = 0; /* set last argument value to zero */ alen += sizeof(addr_t); env = (char **)env_start; for(i=0;i<envc;i++) { char *old = env[i]; char *new = (char *)(env_start+alen); user_map_if_not_mapped_noclear((addr_t)new); unsigned len = strlen(old) + 1; user_map_if_not_mapped_noclear((addr_t)new + len + 1); env[i] = new; _strcpy(new, old); kfree(old); alen += len; } kfree(backup_env); } end = (env_start + alen) & PAGE_MASK; t->env = env; t->argv = argv; kfree(path); t->heap_start = t->heap_end = end + PAGE_SIZE; if(other_bitsize) raise_task_flag(t, TF_OTHERBS); user_map_if_not_mapped_noclear(t->heap_start); /* Zero the heap and stack */ memset((void *)end_l, 0, PAGE_SIZE-(end_l%PAGE_SIZE)); memset((void *)(end+PAGE_SIZE), 0, PAGE_SIZE); memset((void *)(STACK_LOCATION - STACK_SIZE), 0, STACK_SIZE); /* Release everything */ if(EXEC_LOG == 2) printk(0, "[%d]: Performing call\n", t->pid); set_int(0); lower_task_flag(t, TF_SCHED); if(!(kernel_state_flags & KSF_HAVEEXECED)) set_ksf(KSF_HAVEEXECED); arch_specific_exec_initializer(t, argc, eip); return 0; }