Esempio n. 1
0
SegmentBufInfo *parse_phdr(Elf64_Phdr *phdrs, int num, int *segBufNum) {
    printfsocket("segment num : %d\n", num);
    SegmentBufInfo *infos = (SegmentBufInfo *)malloc(sizeof(SegmentBufInfo) * num);
    int segindex = 0;
    for (int i = 0; i < num; i += 1) {
        Elf64_Phdr *phdr = &phdrs[i];
        print_phdr(phdr);

        if (phdr->p_filesz > 0) {
            if ((!is_segment_in_other_segment(phdr, i, phdrs, num)) || (phdr->p_type == 0x6fffff01)) {
                SegmentBufInfo *info = &infos[segindex];
                segindex += 1;
                info->index = i;
                info->bufsz = (phdr->p_filesz + (phdr->p_align - 1)) & (~(phdr->p_align - 1));
                info->filesz = phdr->p_filesz;
                info->fileoff = phdr->p_offset;
                info->enc = (phdr->p_type != 0x6fffff01) ? TRUE : FALSE;

                printfsocket("seg buf info %d -->\n", segindex);
                printfsocket("    index : %d\n    bufsz : 0x%016llX\n", info->index, info->bufsz);
                printfsocket("    filesz : 0x%016llX\n    fileoff : 0x%016llX\n", info->filesz, info->fileoff);
            }
        }
    }
    *segBufNum = segindex;
    return infos;
}
Esempio n. 2
0
static void dump_phdrs(struct elf_phdr *ep, int pnum)
{
	int i;

	for (i = 0; i < pnum; i++, ep++) {
		if ((ep->p_type == PT_LOAD) ||
		    (ep->p_type == PT_INTERP) ||
		    (ep->p_type == PT_PHDR))
			print_phdr(i, ep);
	}
}
void exec(){
	uint16_t i, j;
	uint64_t addr;
	csh handle;
	cs_insn *insn;
	PHDR ph;
	ELF elf;
	SHDR sh;
	uint8_t *data = NULL;
	va_tbl* TBL = NULL;
	
	
	if (cs_open(CS_ARCH_PPC, CS_MODE_64+CS_MODE_BIG_ENDIAN, &handle) != CS_ERR_OK){
		printf("ERROR:%s\n", get_err(&handle));
		goto end;
	}
	cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
	
	fseek(fp, 0, SEEK_SET);
	fread((void*) &elf, sizeof(ELF), 1, fp);
	revert_elf(&elf); // because it BE on LE machine
	
	if(ELF_MAGIC != *((uint32_t*)&elf.e_ident)){
		printf("Wrong ELF_MAGIC (0x%08x)\n", *((uint32_t*)&elf.e_ident));
		goto end;
	}
	
	if(elf.e_machine != EM_PPC64){
		printf("e_machine (%x) != EM_PPC64\n", elf.e_machine);
		goto end;
	}
	
	TBL = (va_tbl*) malloc(elf.e_shnum*sizeof(va_tbl));
	
	print_elf(&elf);
	
	addr = elf.e_phoff;
	for(i=0; i<elf.e_phnum; i++, addr+=sizeof(PHDR)){
		memset((void*)&ph, 0, sizeof(PHDR));

		fseek(fp, addr, SEEK_SET);
		fread((void*) &ph, sizeof(PHDR), 1, fp);
		revert_phdr(&ph);
		print_phdr(&ph, i);
	}

	addr = elf.e_shoff;
	for(i=0; i<elf.e_shnum; i++, addr+=sizeof(SHDR)){
		memset((void*)&sh, 0, sizeof(SHDR));

		fseek(fp, addr, SEEK_SET);
		fread((void*) &sh, sizeof(SHDR), 1, fp);
		revert_shdr(&sh);
		print_shdr(&sh, i);
		TBL[i].off = addr;
		TBL[i].va  = sh.sh_addr;
		TBL[i].used= 0;
	}

	printf("\n\n#### Disassemble ####\n");
	addr = elf.e_phoff;
	for(i=0; i<elf.e_phnum; i++, addr+=sizeof(PHDR)){
		memset((void*)&ph, 0, sizeof(PHDR));
		fseek(fp, addr, SEEK_SET);
		fread((void*) &ph, sizeof(PHDR), 1, fp);
		revert_phdr(&ph);

		for(j=0;j<elf.e_shnum-1;j++){
			if(TBL[j].used == 0 && TBL[j].va <= ph.p_vaddr){
				TBL[j].used++;
				fseek(fp, TBL[j].off, SEEK_SET);
				fread((void*) &sh, sizeof(SHDR), 1, fp);
				revert_shdr(&sh);
				if(sh.sh_size != 0)
					data = (uint8_t*) malloc(sh.sh_size);
				else
					data = NULL;
				disassemble_data(&sh, data, sh.sh_size, TBL[j].va);
				if(sh.sh_size != 0)
					free(data);
				
			}
		}
		data = (uint8_t*) malloc(ph.p_filesz);
		if(data == NULL){
			printf("Could not alloc %lu bytes\n", ph.p_filesz);
			break;
		}
		fseek(fp, ph.p_offset, SEEK_SET);
		fread((void*) data, ph.p_filesz, 1, fp);
		disassemble(handle, insn, data, ph.p_filesz, ph.p_vaddr);
		free(data);

	}
	for(j=0;j<elf.e_shnum-1;j++){
		if(TBL[j].used == 0){
			TBL[j].used++;
			fseek(fp, TBL[j].off, SEEK_SET);
			fread((void*) &sh, sizeof(SHDR), 1, fp);
			revert_shdr(&sh);
			if(sh.sh_size != 0)
				data = (uint8_t*) malloc(sh.sh_size);
			else
				data = NULL;
			disassemble_data(&sh, data, sh.sh_size, TBL[j].va);
			if(sh.sh_size != 0)
				free(data);
			
		}
	}

end:
	if(TBL)
		free(TBL);
	cs_close(&handle);
}