Esempio n. 1
0
//--------------------------------------------------------------------------------------------------
static int symbol_by_name(int d, Elf_Shdr *section, char const *name, Elf_Sym **symbol, size_t *index)
{
    Elf_Shdr *strings_section = NULL;
    char const *strings = NULL;
    Elf_Sym *symbols = NULL;
    size_t i, amount;

    *symbol = NULL;
    *index = 0;

    if (
        section_by_index(d, section->sh_link, &strings_section) ||
        read_string_table(d, strings_section, &strings) ||
        read_symbol_table(d, section, &symbols)
        )
        return errno;

    amount = section->sh_size / sizeof(Elf_Sym);

    for (i = 0; i < amount; ++i)
        if (!strcmp(name, &strings[symbols[i].st_name]))
        {
            *symbol = (Elf_Sym *)malloc(sizeof(Elf_Sym));

            if (NULL == *symbol)
            {
                free(strings_section);
                free((void *)strings);
                free(symbols);

                return errno;
            }

            memcpy(*symbol, symbols + i, sizeof(Elf_Sym));
            *index = i;

            break;
        }

    free(strings_section);
    free((void *)strings);
    free(symbols);

    return 0;
}
Esempio n. 2
0
//--------------------------------------------------------------------------------------------------
int get_module_base_address(char const *module_filename, void *handle, void **base)
{
    int descriptor;  //file descriptor of shared module
    Elf_Shdr *dynsym = NULL, *strings_section = NULL;
    char const *strings = NULL;
    Elf_Sym *symbols = NULL;
    size_t i, amount;
    Elf_Sym *found = NULL;

    *base = NULL;

    descriptor = open(module_filename, O_RDONLY);

    if (descriptor < 0)
        return errno;

    if (section_by_type(descriptor, SHT_DYNSYM, &dynsym) ||  //get ".dynsym" section
        section_by_index(descriptor, dynsym->sh_link, &strings_section) ||
        read_string_table(descriptor, strings_section, &strings) ||
        read_symbol_table(descriptor, dynsym, &symbols))
    {
        free(strings_section);
        free((void *)strings);
        free(symbols);
        free(dynsym);
        close(descriptor);

        return errno;
    }

    amount = dynsym->sh_size / sizeof(Elf_Sym);

    /* Trick to get the module base address in a portable way:
     *   Find the first GLOBAL or WEAK symbol in the symbol table,
     *   look this up with dlsym, then return the difference as the base address
     */
    for (i = 0; i < amount; ++i)
    {
        switch(ELF32_ST_BIND(symbols[i].st_info)) {
        case STB_GLOBAL:
        case STB_WEAK:
            found = &symbols[i];
            break;
        default: // Not interested in this symbol
            break;
        }
    }
    if(found != NULL)
    {
        const char *name = &strings[found->st_name];
        void *sym = dlsym(handle, name); 
        if(sym != NULL)
            *base = (void*)((size_t)sym - found->st_value);
    }

    free(strings_section);
    free((void *)strings);
    free(symbols);
    free(dynsym);
    close(descriptor);

    return *base == NULL;
}
Esempio n. 3
0
File: readrex.c Progetto: 8l/R3X
int main(int argc, char* argv[]){
	ParseArguments(argc, argv);
	if(InputFile == NULL) {
		fprintf(stderr, "Input file not specified\n");
		exit(EXIT_FAILURE);
	}
	FILE* fpin = fopen(InputFile, "r+b");
	if(fpin == NULL){
		perror("fopen failed: ");
		exit(EXIT_FAILURE);
	}
	// seek to end of file
	fseek(fpin, 0L, SEEK_END);
	// get file size
	unsigned int size = ftell(fpin);
	// allocate memory
	uint8_t* InputBuffer = malloc(size);
	// seek reset
	fseek(fpin, 0L, SEEK_SET);
	// read all bytes
	unsigned int sizeread = fread(InputBuffer, sizeof(uint8_t), size, fpin);
	if(sizeread != size){
		fprintf(stderr, "fread failed.\n");
		perror("fread: ");
		exit(EXIT_FAILURE);
	}
	if(*((uint32_t*)&InputBuffer[0]) == EXEC_HEADER) {
		printf("Type: Executable\n");
		r3x_header_t* myheader = (r3x_header_t*)&InputBuffer[0];
		printf("Program header Index: 0x%X\n", myheader->program_header);
		printf("Version (Major).(Minor): %u.%u\n", myheader->major, myheader->minor);
		printf("Location of .text: %u\n", myheader->r3x_init);
		printf("Size of .text: %u\n", myheader->r3x_text_size);
		printf("Location of .symbols: %u\n", myheader->r3x_symbols);
		printf("Size of .symbols: %u\n", myheader->r3x_symbolsize);
		printf("Location of data: %u\n", myheader->r3x_data);
		printf("Size of .data: %u\n", myheader->r3x_data_size);
		printf("Location of .bss: %u\n", myheader->r3x_bss);
		printf("Size of .bss: %u\n", myheader->r3x_bss_size);
		printf("Location of .import: %u\n", myheader->import);
		printf("Size of .import: %u\n", myheader->import_size);
		if(myheader->nameaddr - PROG_EXEC_POINT > size || myheader->pulibsheraddr - PROG_EXEC_POINT > size) {
			printf("Invalid publisher/executable information\n");
		} else {
			printf("Name: %s\n", (char*)&InputBuffer[myheader->nameaddr - PROG_EXEC_POINT]);
			printf("Publisher: %s\n", (char*)&InputBuffer[myheader->pulibsheraddr - PROG_EXEC_POINT]);
		}
		if(myheader->r3x_symbols - PROG_EXEC_POINT > size) {
			printf("Invalid symbol table\n");
		} else {
			read_symbol_table(myheader, InputBuffer, size, 0);
		}
		if(myheader->import - PROG_EXEC_POINT > size) {
		  printf("Invalid .import table\n");
		} else {
		  r3x_header_t* Header = myheader;
		  if(Header->import_size == 0) {
		  } else {
		  uint32_t NumberOfImports = Header->import_size / sizeof(r3x_import_t);
		  r3x_import_t* Imports = (r3x_import_t*)&InputBuffer[Header->import - PROG_EXEC_POINT];
		  printf(".import:\n");
		  for(unsigned int i = 0; i < NumberOfImports; i++) {
			if(Imports[i].SymbolName - PROG_EXEC_POINT > size || Imports[i].LibName - PROG_EXEC_POINT > size) {
			    printf("Corrupted .import table!\n");
			    exit(0);
			}
			printf("%u: %s from %s\n", i, (char*)((uintptr_t)((uintptr_t)InputBuffer + Imports[i].SymbolName - PROG_EXEC_POINT)), (char*)((uintptr_t)((uintptr_t)InputBuffer + Imports[i].LibName - PROG_EXEC_POINT)));
		    }
		  }
		}
	} else if(*((uint32_t*)&InputBuffer[0]) == DLL_HEADER) {
		printf("Type: Dynamic Shared Library\n");
		r3x_dynamic_header_t* myheader = (r3x_dynamic_header_t*)&InputBuffer[0];
		printf("Program header Index: 0x%X\n", 0);
		printf("Version (Major).(Minor): %u.%u\n", myheader->major, myheader->minor);
		printf("Location of .text: %u\n", myheader->text_section);
		printf("Size of .text: %u\n", myheader->text_size);
		printf("Location of data: %u\n", myheader->data_section);
		printf("Size of .data: %u\n", myheader->data_size);
		printf("Location of .bss: %u\n", myheader->bss_section);
		printf("Size of .bss: %u\n", myheader->bss_size);
		if(myheader->nameaddr > size || myheader->publisheraddr > size) {
			printf("Invalid publisher/executable information\n");
		} else {
			printf("Name: %s\n", (char*)&InputBuffer[myheader->nameaddr - 0]);
			printf("Publisher: %s\n", (char*)&InputBuffer[myheader->publisheraddr - 0]);
		}
		printf(".export section: \n"); 
		if(myheader->export_section > size) {
			printf("Bad Export section\n");
		} else {
			export_struct* myexports = (export_struct*)&InputBuffer[myheader->export_section];
			for(unsigned int i = 0; i < myheader->export_size / sizeof(export_struct); i++){
				if(myexports[i].function_id > size) {
					printf("bad export\n");
				} else {
					printf("Export %s, to function at: %u\n", (char*)&InputBuffer[myexports[i].function_id],  myexports[i].instruction_pointer);
				}
			}
		}
	}
}
/*
 exe_commande
    Descr: Execute les différentes opérations demandés par l'utilisateur
    Param:
        - c: Commande (voir #define ci dessus)
        - nomfichier: Nom du fichier à lire
        - nm_index: Argument de l'option -x, NULL si l'option n'a pas été choisis
    Return:
        Etat de sortie de la fonction:
        - -1: Impossible d'ouvrir le fichier donné
        - 0: Ouverture du fichier réussi
 */
int exe_commande(unsigned char c, char *nomfichier,char* nm_index)
{
	if (nomfichier==NULL)
		return NOMFICHIERNULL;
    FILE *f;
    
    Elf32_Ehdr header;
    Elf32_Shdr *section_header_table;
    Elf32_Sym *symbol_tab;
    sectioncontent section;
    
    int nbSym = 0;
    int valid = 0;
    
    f = fopen(nomfichier,"r"); // Ouverture du fichier nomfichier

    if(f == NULL) { // Echec d'ouverture
        return FICHIERINEXISTANT;
    }
    else {
        /* Lecture Header */
        header = read_header(f,&valid);
        
        if(valid==1) { // Header valide
            
            /* Lecture Table de section header */
            section_header_table = read_section_header_table(f,header);
            
            /* Lecture Table des symboles */
            symbol_tab =
                read_symbol_table(f ,section_header_table, header, &nbSym);

            if(c&COMMANDE_HEAD) //COMMANDE_HEAD
            {
                printf("ELF Header:\n");
                print_header(header);
                printf("\n");
                 
            }
            if(c&COMMANDE_SECTIONTAB)//COMMANDE_SECTIONTAB
            {
                printf("Section Headers:\n");
                print_section_header_table(f,section_header_table,header);
                printf("\n");
            }
            
            if(c&COMMANDE_CONTENT)//COMMANDE_CONTENT
            {
                printf("Section %s content:\n", nm_index);
                
                section = read_section_content(f,nm_index, section_header_table, header);
                if(section.content==NULL) {
                    printf("Warning, section : %s,was not dumped because it does not exist \n",nm_index);
                }
                else {
                    print_section_content(section);
                }
            }
            if(c&COMMANDE_RELOC)//COMMANDE_RELOC
            {
                print_all_reloc_table(f, header, section_header_table, symbol_tab);
                printf("\n");
            }
            
           
            if(c&COMMANDE_SYM)//COMMANDE_SYM
            {
                printf("Symbol table\n");
                print_symbol_table(symbol_tab, nbSym, f, section_header_table, header);
                freeSymbolTable(symbol_tab);
            }
            }
        else // Header non valide
        {
            if(valid ==-1) { // Fichier non valid (vide ou autre)
                return FILEEMPTY;fprintf(stderr, "%s : Error while reading the file (possibly empty)\n",nomfichier);
            }
            else if(valid==0) { //Fichier pas au format elf32
                return NOTELF32;
            }
            else { // Cas normalement impossible
                fprintf(stderr, "Impossible error append\n");
            }
        }
            
        fclose(f); // Fermeture du fichier
    }
    return 0;
}
Esempio n. 5
0
static int elf_read(struct mt_elf *mte, struct task *task, const char *filename)
{
	unsigned long loadsize = 0;
	unsigned long loadbase = ~0;
	unsigned long align;
	unsigned long vstart;
	unsigned int loadsegs = 0;

	debug(DEBUG_FUNCTION, "filename=%s", filename);

	if (open_elf(mte, task, filename) < 0)
		return -1;

	GElf_Phdr phdr;
	int i;

	memset(&mte->txt_hdr, 0, sizeof(mte->txt_hdr));
	memset(&mte->eh_hdr, 0, sizeof(mte->eh_hdr));
	memset(&mte->exidx_hdr, 0, sizeof(mte->exidx_hdr));

	for (i = 0; gelf_getphdr(mte->elf, i, &phdr) != NULL; ++i) {
		switch (phdr.p_type) {
		case PT_LOAD:
			loadsegs++;

			align = phdr.p_align;
			if (align)
				align -= 1;

			vstart = phdr.p_vaddr & ~align;

			if (mte->vstart > vstart)
				mte->vstart = vstart;

			if (loadbase > phdr.p_offset)
				loadbase = phdr.p_offset;

			if (loadsize < phdr.p_offset + phdr.p_filesz)
				loadsize = phdr.p_offset + phdr.p_filesz;

			if ((phdr.p_flags & (PF_X | PF_W)) == PF_X)
				mte->txt_hdr = phdr;

			break;
		case PT_GNU_EH_FRAME:
			mte->eh_hdr = phdr;
			break;
#ifdef __arm__
		case PT_ARM_EXIDX:
			mte->exidx_hdr = phdr;
			break;
#endif
		case PT_INTERP:
			mte->interp = phdr.p_vaddr;
			break;
		case PT_DYNAMIC:
			mte->dyn = phdr.p_vaddr;
			break;
		default:
			break;
		}
	}

	if (!loadsegs) {
		fprintf(stderr, "No loadable segemnts in %s\n", filename);
		return -1;
	}

	mte->loadbase = loadbase & ~PAGEALIGN;
	mte->loadsize = (loadsize + (loadbase - mte->loadbase) + PAGEALIGN) & ~PAGEALIGN;

	debug(DEBUG_FUNCTION, "filename=`%s' text offset=%#llx addr=%#llx size=%#llx",
			filename,
			(unsigned long long)mte->txt_hdr.p_offset,
			(unsigned long long)mte->txt_hdr.p_vaddr,
			(unsigned long long)mte->txt_hdr.p_filesz);

	for (i = 1; i < mte->ehdr.e_shnum; ++i) {
		Elf_Scn *scn;
		GElf_Shdr shdr;
		const char *name;

		scn = elf_getscn(mte->elf, i);
		if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) {
			fprintf(stderr, "Couldn't get section #%d from" " \"%s\": %s\n", i, filename, elf_errmsg(-1));
			return -1;
		}

		name = elf_strptr(mte->elf, mte->ehdr.e_shstrndx, shdr.sh_name);
		if (name == NULL) {
			fprintf(stderr, "Couldn't get name of section #%d from \"%s\": %s\n", i, filename, elf_errmsg(-1));
			return -1;
		}

		if (shdr.sh_type == SHT_SYMTAB) {
			read_symbol_table(mte, filename, scn, &shdr, name, &mte->symtab, &mte->symtab_count, &mte->strtab);
		} else if (shdr.sh_type == SHT_DYNSYM) {
			read_symbol_table(mte, filename, scn, &shdr, name, &mte->dynsym, &mte->dynsym_count, &mte->dynstr);
		} else if (shdr.sh_type == SHT_DYNAMIC) {
			Elf_Data *data;
			GElf_Dyn dyn;
			int idx;

			data = elf_getdata(scn, NULL);
			if (data == NULL) {
				fprintf(stderr, "Couldn't get .dynamic data from \"%s\": %s\n", filename, strerror(errno));
				return -1;
			}

			for(idx = 0; gelf_getdyn(data, idx, &dyn); ++idx) {
				if (dyn.d_tag == DT_PLTGOT)  {
					mte->pltgot = dyn.d_un.d_ptr;
					break;
				}
			}
		}
	}

	if (!mte->dynsym || !mte->dynstr) {
		fprintf(stderr, "Couldn't find .dynsym or .dynstr in \"%s\"\n", filename);
		return -1;
	}

	return 0;
}