📄 elf.c
字号:
VerboseShtype(unsigned long type)
{
switch(type) {
case SHT_NULL:
return("null");
case SHT_PROGBITS:
return("progbits");
case SHT_SYMTAB:
return("symtab");
case SHT_STRTAB:
return("strtab");
case SHT_RELA:
return("rela");
case SHT_HASH:
return("hash");
case SHT_DYNAMIC:
return("dynamic");
case SHT_NOTE:
return("note");
case SHT_NOBITS:
return("nobits");
case SHT_REL:
return("rel");
case SHT_SHLIB:
return("shlib");
case SHT_DYNSYM:
return("dynsym");
default:
fprintf(stderr,"Unexpeced type: 0x%x\n",type);
exit(1);
}
}
char *
VerboseShflags(unsigned long flags)
{
static char buf[32];
*buf = 0;
if (flags & SHF_ALLOC)
strcat(buf,"allocated ");
if (flags & SHF_WRITE)
strcat(buf,"writeable ");
if (flags & SHF_EXECINSTR)
strcat(buf,"text ");
return(buf);
}
char *
GetElfSectionName(unsigned long index)
{
static char buf[64];
char *strings, *bp, *end, *name;
struct elf_shdr *eshdr;
if (debug >= 2)
fprintf(stderr,"GetElfSectionName(%d)\n",index);
buf[0] = (char)0;
eshdr = &ScnTbl[Ehdr.e_shstrndx];
Lseek(elfFD,eshdr->sh_offset,SEEK_SET);
strings = Malloc((unsigned)(eshdr->sh_size));
Read(elfFD,strings,(unsigned)(eshdr->sh_size));
name = Malloc(strlen(&strings[index]) + 1);
strcpy(name,&strings[index]);
free(strings);
return(name);
}
/* GetElfFileHdr():
Retrieve the header from the file and do a endian conversion
on each of its members.
*/
struct elf_fhdr *
GetElfFileHdr(struct elf_fhdr *efhdr)
{
static int pass = 0;
if (debug >= 2)
fprintf(stderr,"GetElfFileHdr()\n");
retry:
/* Read in the elf header. */
Lseek(elfFD,0,SEEK_SET);
Read(elfFD,(char *)efhdr,(unsigned)sizeof(struct elf_fhdr));
/* If this is the first pass through this function, then
* read in the size of the program header. If the size is
* greater than 4k, then assume we need to do an endian
* adjustment...
*/
if (pass == 0) {
pass++;
efhdr->e_phentsize = otherEnd16(Ecvt,efhdr->e_phentsize);
if (efhdr->e_phentsize > 0x1000) {
printf("Automatic endianness adjustment\n");
#if HOST_IS_SOLARIS
Ecvt = 1;
#else
Ecvt = 0;
#endif
goto retry;
}
}
efhdr->e_type = otherEnd16(Ecvt,efhdr->e_type);
efhdr->e_machine = otherEnd16(Ecvt,efhdr->e_machine);
efhdr->e_version = otherEnd32(Ecvt,efhdr->e_version);
efhdr->e_entry = otherEnd32(Ecvt,efhdr->e_entry);
efhdr->e_phoff = otherEnd32(Ecvt,efhdr->e_phoff);
efhdr->e_shoff = otherEnd32(Ecvt,efhdr->e_shoff);
efhdr->e_flags = otherEnd32(Ecvt,efhdr->e_flags);
efhdr->e_ehsize = otherEnd16(Ecvt,efhdr->e_ehsize);
efhdr->e_phentsize = otherEnd16(Ecvt,efhdr->e_phentsize);
efhdr->e_phnum = otherEnd16(Ecvt,efhdr->e_phnum);
efhdr->e_shentsize = otherEnd16(Ecvt,efhdr->e_shentsize);
efhdr->e_shnum = otherEnd16(Ecvt,efhdr->e_shnum);
efhdr->e_shstrndx = otherEnd16(Ecvt,efhdr->e_shstrndx);
return(efhdr);
}
Elf32_Half
GetElfSectionHdrs(void)
{
int i, size;
/* Allocate space for the section table in memory. */
size = Ehdr.e_shnum * Ehdr.e_shentsize;
ScnTbl = (struct elf_shdr *)Malloc(size);
/* Read in the elf section headers. */
Lseek(elfFD,Ehdr.e_shoff,SEEK_SET);
Read(elfFD,(char *)ScnTbl,size);
for(i=0;i<Ehdr.e_shnum;i++) {
ScnTbl[i].sh_name = otherEnd32(Ecvt,ScnTbl[i].sh_name);
ScnTbl[i].sh_type = otherEnd32(Ecvt,ScnTbl[i].sh_type);
ScnTbl[i].sh_flags = otherEnd32(Ecvt,ScnTbl[i].sh_flags);
ScnTbl[i].sh_addr = otherEnd32(Ecvt,ScnTbl[i].sh_addr);
ScnTbl[i].sh_offset = otherEnd32(Ecvt,ScnTbl[i].sh_offset);
ScnTbl[i].sh_size = otherEnd32(Ecvt,ScnTbl[i].sh_size);
ScnTbl[i].sh_link = otherEnd32(Ecvt,ScnTbl[i].sh_link);
ScnTbl[i].sh_info = otherEnd32(Ecvt,ScnTbl[i].sh_info);
ScnTbl[i].sh_addralign = otherEnd32(Ecvt,ScnTbl[i].sh_addralign);
ScnTbl[i].sh_entsize = otherEnd32(Ecvt,ScnTbl[i].sh_entsize);
}
return(Ehdr.e_shnum);
}
Elf32_Half
GetElfProgramHdrTbl(void)
{
int i, size;
/* Allocate space for the program header table in memory.
*/
size = Ehdr.e_phnum * Ehdr.e_phentsize;
PhdrTbl = (struct elf_phdr *)Malloc(size);
/* Read in the elf section headers. */
Lseek(elfFD,Ehdr.e_phoff,SEEK_SET);
Read(elfFD,(char *)PhdrTbl,size);
for(i=0;i<Ehdr.e_phnum;i++) {
PhdrTbl[i].p_type = otherEnd32(Ecvt,PhdrTbl[i].p_type);
PhdrTbl[i].p_offset = otherEnd32(Ecvt,PhdrTbl[i].p_offset);
PhdrTbl[i].p_vaddr = otherEnd32(Ecvt,PhdrTbl[i].p_vaddr);
PhdrTbl[i].p_paddr = otherEnd32(Ecvt,PhdrTbl[i].p_paddr);
PhdrTbl[i].p_filesz = otherEnd32(Ecvt,PhdrTbl[i].p_filesz);
PhdrTbl[i].p_memsz = otherEnd32(Ecvt,PhdrTbl[i].p_memsz);
PhdrTbl[i].p_flags = otherEnd32(Ecvt,PhdrTbl[i].p_flags);
PhdrTbl[i].p_align = otherEnd32(Ecvt,PhdrTbl[i].p_align);
}
return(Ehdr.e_phnum);
}
char *usage_txt[] = {
"Usage: elf [options] {filename}",
" Options:",
" -a{filename} append file to end of -S file",
" -A print what was appended by -a",
" -B{filename} elf-2-bin to filename",
" -c endian convert",
" -d debug mode (for development only)",
" -f show elf file header",
" -i# insert '#' pad bytes, 4 bytes prior to end of binary",
" -M show elf map with file offsets",
" -m show elf map without file offsets",
" -p dump program header table.",
" -P{pad byte} byte to use for padding (default = 0xff)",
" -s show elf section headers",
" -S{filename} strip to specified file",
" -V display version of tool",
" -v verbose mode",
" -z{zlvl} compress sections of filename to 'filename.ezip'",
" zlvl can range from 1-9 (typically 6) where...",
" 1 is faster/lighter compression",
" 9 is slower/heavier compression",
" -Z{zlvl} same as -z, but compressed section files are not removed",
0,
};
main(argc,argv)
int argc;
char *argv[];
{
extern int optind;
extern char *optarg;
char fname[128], buf[16], *append, *binto, *stripto;
int i, opt, showstuff, zlevel;
elfFD = 0;
zlevel = 0;
debug = 0;
xdebug = 0;
verbose = 0;
insertPAD = 0;
showstuff = 0;
#if HOST_IS_SOLARIS
Ecvt = 0;
#else
Ecvt = 1;
#endif
PadByte = 0xff;
binto = (char *)0;
append = (char *)0;
stripto = (char *)0;
elfFname = (char *)0;
while ((opt=getopt(argc,argv,"Aa:B:cdfi:mMpP:S:sVvxz:Z:")) != EOF) {
switch(opt) {
case 'a':
append = optarg;
break;
case 'A':
showstuff |= SHOWAPPEND;
break;
case 'B':
binto = optarg;
break;
case 'c':
#if HOST_IS_SOLARIS
Ecvt = 1;
#else
Ecvt = 0;
#endif
break;
case 'd':
debug++;
break;
case 'f':
showstuff |= SHOWELFHDR;
break;
case 'i':
insertPAD = strtol(optarg,0,0);
break;
case 'M':
showstuff |= SHOWMAPOFFSET;
break;
case 'm':
showstuff |= SHOWMAP;
break;
case 'p':
showstuff |= SHOWPRGMHDR;
break;
case 'P':
PadByte = strtol(optarg,0,0);
break;
case 's':
showstuff |= SHOWSECTIONS;
break;
case 'S':
stripto = optarg;
break;
case 'V':
showVersion();
break;
case 'v':
verbose = 1;
break;
case 'x':
xdebug++;
break;
case 'Z':
remove_zouts = 0;
zlevel = atoi(optarg);
if ((zlevel < 1) || (zlevel > 9))
usage("zlvl out of range\n");
break;
case 'z':
zlevel = atoi(optarg);
if ((zlevel < 1) || (zlevel > 9))
usage("zlvl out of range\n");
break;
default:
usage(0);
}
}
if (argc != (optind+1))
usage("Missing filename");
strcpy(fname,argv[optind]);
if (!fileexists(fname)) {
fprintf(stderr,"No such file: %s\n",fname);
exit(1);
}
if ((elfFD = open(fname,O_RDONLY | O_BINARY)) == -1) {
perror(fname);
return(0);
}
/* Start by verifying that the file is ELF format... */
Read(elfFD,buf,4);
if ((buf[0] != 0x7f) || (buf[1] != 'E') ||
(buf[2] != 'L') || (buf[3] != 'F')) {
fprintf(stderr,"File '%s' not ELF format\n",fname);
exit(1);
}
elfFname = StrAllocAndCopy(fname);
GetElfFileHdr(&Ehdr);
GetElfProgramHdrTbl();
GetElfSectionHdrs();
if (zlevel) {
ZipElfSections(zlevel);
}
else if (binto) {
ElfToBinary(binto);
}
else if (stripto) {
StripElfFile(stripto,append);
}
else {
if (showstuff & SHOWAPPEND)
ShowAppend();
if (showstuff & SHOWMAPOFFSET)
ShowElfMap(1);
if (showstuff & SHOWMAP)
ShowElfMap(0);
if (showstuff & SHOWELFHDR)
ShowElfHdr();
if (showstuff & SHOWSECTIONS)
ShowSections(verbose);
if (showstuff & SHOWPRGMHDR)
ShowProgramHdrTbl(verbose);
}
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -