void parse_elf (char* file_name)
{
	init_elf_parser (file_name);

	if (architecture == ELFCLASS32)
	{
		get_num_sections ();
		get_section_names ();
		parse_sections ();
		get_entry_point ();
		find_main ();
	}
	else
	{
		get_num_sections64 ();
		get_section_names64 ();
		parse_sections64 ();
		get_entry_point64 ();
		find_main64 ();
	}
}
Exemple #2
0
sect_info * get_text_section() {
	int i;
	sect_info * tex = (sect_info*)malloc(sizeof(sect_info));
	byte * tbuf;
	for (i=0;i< ex_header->num_sections;i++) {
		if (!strcmp(sects[i]->name,".text")) {
			text = sects[i];
			//printf("%X\n",sects[i]->vaddr);
			break;
		}
	}
	tbuf = (byte*)malloc(sects[i]->raw_data_size);
	fseek(fptr,sects[i]->raw_data_ptr,SEEK_SET);
	fread(tbuf,1,sects[i]->raw_data_size,fptr);
	tex->data = tbuf;
	tex->ep = get_text_off(get_entry_point());
	tex->size = sects[i]->raw_data_size;
	tex->va = sects[i]->vaddr;
	tex->vsize = sects[i]->vsize;
	//printf("%X %X %X\n",sects[i]->raw_data_ptr,tex->ep,sects[i]->raw_data_ptr+tex->ep-text->vaddr);
	return tex;

}
Exemple #3
0
/**
 * Initialize PXE.
 */
void pxe_init(void) {
  bootp_packet_t *bootp;
  pxe_device_t *pxe;

  /* Boot device is set to 0x7f by the PXE boot sector. */
  if (bios_boot_device != 0x7f) { return; }

  if (!get_entry_point())
    return;

  dprintf(
    "pxe: booting via PXE, entry point at %04x:%04x (%p)\n",
    pxe_entry_point >> 16, pxe_entry_point & 0xffff, segoff_to_linear(pxe_entry_point));

  // When using PXE, 0x8d000 onwards is reserved for use by the PXE stack so
  // we need to mark it as internal to ensure we don't load anything there.
  // Also reserve a bit more because the PXE ROM on some machines appears to
  // take a dump over memory below there as well.
  memory_protect(0x80000, 0x1f000);

  // Obtain the BOOTP reply packet.
  bootp = get_bootp_packet();

  // Create a device.
  pxe = malloc(sizeof(*pxe));
  memset(pxe, 0, sizeof(*pxe));
  pxe->net.ops = &pxe_net_ops;
  pxe->net.server_port = PXENV_TFTP_PORT;
  pxe->mount.device = &pxe->net.device;
  pxe->mount.ops = &pxe_fs_ops;
  net_device_register_with_bootp(&pxe->net, bootp, true);
  pxe->net.device.mount = &pxe->mount;

  // register a pre-boot hook to shut down the PXE stack
  loader_register_preboot_hook(shutdown_pxe);
}
//Initialize some globals that have to deal with the ELF we're reading
//Note: this must be called whether or not you're actually using the parser
void init_elf_parser (char* file_name)
{
	init_file_buf (file_name);

	Elf32_Ehdr* header = (Elf32_Ehdr*)file_buf;
	Elf64_Ehdr* header64 = (Elf64_Ehdr*)file_buf;

	//Sanity check
	header = (Elf32_Ehdr*)file_buf;
	if (header->e_ident [EI_MAG0] != 0x7f || header->e_ident [EI_MAG1] != 'E' || header->e_ident [EI_MAG2] != 'L' || header->e_ident [EI_MAG3] != 'F')
	{
		elf_parser_cleanup ();
		printf ("CRITICAL ERROR: Not an ELF file.\n");
		exit (-1);
	}
	if (header->e_shoff > file_size)
	{
		elf_parser_cleanup ();
		printf ("ERROR: ELF file is corrupt. Invalid section header offset. Sections have probably been stripped, please specify a starting address.\n");
		exit (-1);
	}
	if (header->e_phoff > file_size)
	{
		elf_parser_cleanup ();
		printf ("CRITICAL ERROR: ELF file is corrupt Invalid program header offset.\n");
		exit (-1);
	}

	architecture = header->e_ident [EI_CLASS];

	if (architecture == ELFCLASSNONE)
	{
		printf ("CRITICAL ERROR: Invalid architecture");
		exit (-1);
	}
	else if (architecture == ELFCLASS32)
	{
		Elf32_Phdr* program_headers = (Elf32_Phdr*)(file_buf + header->e_phoff);
		int i;

		for (i = 0; i < header->e_phnum; i ++)
		{
			if (program_headers [i].p_type == PT_LOAD)
			{
				base_addr = program_headers [i].p_vaddr;
				executable_segment_size = program_headers [i].p_filesz;
				break;
			}
		}
		if (i == header->e_phnum)
		{
			printf ("CRITICAL ERROR: No loadable segments\n");
			exit (-1);
		}

		symbol_table.arch1 = NULL;
		symbol_table_end.arch1 = NULL;
		num_relocs = 0;
		string_table = NULL;

		get_dyn_syms ();
		get_entry_point ();
		get_text ();
	}
	else if (architecture == ELFCLASS64)
	{
		Elf64_Phdr* program_headers = (Elf64_Phdr*)(file_buf + header64->e_phoff);
		int i;

		for (i = 0; i < header64->e_phnum; i ++)
		{
			if (program_headers [i].p_type == PT_LOAD)
			{
				base_addr = program_headers [i].p_vaddr;
				executable_segment_size = program_headers [i].p_filesz;
				break;
			}
		}
		if (i == header64->e_phnum)
		{
			printf ("CRITICAL ERROR: No loadable segments\n");
			exit (-1);
		}

		symbol_table.arch2 = NULL;
		symbol_table_end.arch2 = NULL;
		num_relocs = 0;
		string_table = NULL;

		get_dyn_syms64 ();
		get_entry_point64 ();
		get_text64 ();
	}
	else
	{
		printf ("CRITICAL ERROR: Invalid ELF class %d", architecture);
		exit (-1);
	}
}
Exemple #5
0
int main(){
    struct Handler *handler_p, *next_handler;
    unsigned hid;
    unsigned oep;
    // This is NOT THE PROPER WAY!!!
    unsigned siginfo[512];
    unsigned baseaddr, memsize;
    enum __ptrace_request pr, pr2;
    //struct user_regs_struct regs;
    //char inst_str[128];
    // Test
    const char *prog = "./try";
    //char indirect = 0;
    //char manual = 0;
    //char plt = 1;
    //int pop = 0;
    //ban = 0x0804841b;
    int wait_status;
    struct user_regs_struct regs;

    init();

    pid_t pid = fork();
    if (pid == 0){
        Ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl(prog, prog, NULL);
    }else if (pid > 0){
        oep = get_entry_point(prog);
        // On loaded
        wait(&wait_status);
        if (WIFSTOPPED(wait_status)){
            // Test, wrong
            memsize = get_memsize(prog);
            baseaddr = get_baseaddr(prog);
            add_module(&whitelist, baseaddr, memsize);
            get_handler(pid, oep, get_trace_option(fopen("/tmp/trace","w"), whitelist));
            get_handler(pid, 0x8048380, get_disable_option(API_TYPE_PLT));
            Ptrace(PTRACE_CONT, pid, NULL, NULL);
        }

        wait(&wait_status);
        // Withdraw control from plugins
        while (WIFSTOPPED(wait_status)){
            Ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
            // Caused by breakpoint
            if (siginfo[2] == 0x80){
                // Discard the 0xcc int 3 instruction
                // So move the eip upper by 1
                Ptrace(PTRACE_GETREGS, pid, NULL, &regs);
                regs.eip --;
                Ptrace(PTRACE_SETREGS, pid ,NULL, &regs);
            }

            // PTRACE_CONT by default because it has the lowest priority
            pr = PTRACE_CONT;
            hid = GETID(regs.eip);

            for (handler_p=global_handler;handler_p;handler_p=next_handler){
                next_handler = handler_p->next_handler;
                pr2 = dispatch(pid, handler_p);
                pr = PRIORITY(pr, pr2);
                pr2 = global_expire(pid, handler_p, &next_handler);
                pr = PRIORITY(pr, pr2);
            }
            for (handler_p=handlers[hid];handler_p;handler_p=next_handler){
                next_handler = handler_p->next_handler;
                pr2 = dispatch(pid, handler_p);
                pr = PRIORITY(pr, pr2);
                pr2 = expire(pid, handler_p, hid, &next_handler);
                pr = PRIORITY(pr, pr2);
            }
            Ptrace(pr, pid, NULL, NULL);
            wait(&wait_status);
        }
    }else{
        perror("Folk failed: ");
        exit(-1);
    }
    finalize();
    return 0;
}