📄 elf.c
字号:
cp = Malloc(zstat.st_size);
Read(secfd,cp,zstat.st_size);
Write(zipfd,cp,zstat.st_size);
free(cp);
close(secfd);
if (remove_zouts)
unlink(zoutfile);
}
else {
if ((sptr->sh_size) && (sptr->sh_type != SHT_NOBITS)) {
if (debug)
fprintf(stderr,"Read %s offset=%d size=%d\n",
name,sptr->sh_offset,sptr->sh_size);
Lseek(elfFD,sptr->sh_offset,SEEK_SET);
cp = Malloc(sptr->sh_size);
Read(elfFD,cp,sptr->sh_size);
#if USE_OFFSET_DELTA
sptr_z->sh_offset -= offset_delta;
#else
sptr_z->sh_offset = tell(zipfd);
#endif
Write(zipfd,cp,sptr->sh_size);
free(cp);
}
}
if ((sptr->sh_type != SHT_NOBITS) && (sptr->sh_flags & SHF_ALLOC)) {
/* I found that the size of the section does not necessarily */
/* correspond to the point at which the next section starts in */
/* the file, so this makes sure that offset_delta is properly */
/* adjusted if that correspondance does not exist... */
if ((sptr->sh_size + sptr->sh_offset) != (sptr+1)->sh_offset) {
int delta;
delta=((sptr+1)->sh_offset-(sptr->sh_size+sptr->sh_offset));
offset_delta +=
((sptr+1)->sh_offset - (sptr->sh_size + sptr->sh_offset));
if (debug)
fprintf(stderr,"offset_delta compensation = %d\n",delta);
}
}
}
/* Now that all sections have been written to the file, insert the
* section header table at the end. Note that the header may be
* endian-converted, so compensate for this prior to writing to file...
*/
if (1) {
int i;
shoffz = tell(zipfd);
/* The section header table base must be 4-byte aligned.. */
if (shoffz & 3) {
if (debug)
fprintf(stderr,"Shifting scnhdr %d bytes up\n",
4-(shoffz&3));
shoffz = Lseek(zipfd,4-(shoffz&3),SEEK_CUR);
}
if(debug)
fprintf(stderr,"Inserting scnhdr at 0x%x\n",shoffz);
for(i=0;i<Ehdr.e_shnum;i++) {
scntbl_z[i].sh_name = otherEnd32(Ecvt,scntbl_z[i].sh_name);
scntbl_z[i].sh_type = otherEnd32(Ecvt,scntbl_z[i].sh_type);
scntbl_z[i].sh_flags = otherEnd32(Ecvt,scntbl_z[i].sh_flags);
scntbl_z[i].sh_addr = otherEnd32(Ecvt,scntbl_z[i].sh_addr);
scntbl_z[i].sh_offset = otherEnd32(Ecvt,scntbl_z[i].sh_offset);
scntbl_z[i].sh_size = otherEnd32(Ecvt,scntbl_z[i].sh_size);
scntbl_z[i].sh_link = otherEnd32(Ecvt,scntbl_z[i].sh_link);
scntbl_z[i].sh_info = otherEnd32(Ecvt,scntbl_z[i].sh_info);
scntbl_z[i].sh_addralign =
otherEnd32(Ecvt,scntbl_z[i].sh_addralign);
scntbl_z[i].sh_entsize = otherEnd32(Ecvt,scntbl_z[i].sh_entsize);
}
Write(zipfd,(char *)scntbl_z,(int)(Ehdr.e_shnum*Ehdr.e_shentsize));
for(i=0;i<Ehdr.e_shnum;i++) {
scntbl_z[i].sh_name = otherEnd32(Ecvt,scntbl_z[i].sh_name);
scntbl_z[i].sh_type = otherEnd32(Ecvt,scntbl_z[i].sh_type);
scntbl_z[i].sh_flags = otherEnd32(Ecvt,scntbl_z[i].sh_flags);
scntbl_z[i].sh_addr = otherEnd32(Ecvt,scntbl_z[i].sh_addr);
scntbl_z[i].sh_offset = otherEnd32(Ecvt,scntbl_z[i].sh_offset);
scntbl_z[i].sh_size = otherEnd32(Ecvt,scntbl_z[i].sh_size);
scntbl_z[i].sh_link = otherEnd32(Ecvt,scntbl_z[i].sh_link);
scntbl_z[i].sh_info = otherEnd32(Ecvt,scntbl_z[i].sh_info);
scntbl_z[i].sh_addralign =
otherEnd32(Ecvt,scntbl_z[i].sh_addralign);
scntbl_z[i].sh_entsize = otherEnd32(Ecvt,scntbl_z[i].sh_entsize);
}
}
if (debug)
fprintf(stderr,"offset_delta = %d\n",offset_delta);
/* Adjust the file header to point to the new section header table. */
Lseek(zipfd,0x20,SEEK_SET);
shoffz = otherEnd32(Ecvt,shoffz);
Write(zipfd,(char *)&shoffz,4);
close(zipfd);
}
void
ElfToBinary(char *binto)
{
int fd, sidx, firstone;
struct stat buf;
uchar *tfrom, *dfrom, *cp;
unsigned long paddr;
struct elf_shdr *sptr;
unlink(binto);
if ((fd = open(binto,O_RDWR|O_BINARY|O_CREAT,0777))==-1)
{
perror(binto);
exit(1);
}
fprintf(stderr,"Converting %s into %s\n",
elfFname,binto);
firstone = 1;
for(sptr=ScnTbl,sidx=0;sidx<Ehdr.e_shnum;sidx++,sptr++) {
char *name, padbyte;
int padtot;
unsigned long nextpaddr;
name = GetElfSectionName(ScnTbl[sidx].sh_name);
if ((sptr->sh_flags & SHF_ALLOC) &&
(sptr->sh_type != SHT_NOBITS) &&
(sptr->sh_size)) {
if (!firstone) { /* Pad if necessary... */
if (nextpaddr != sptr->sh_addr) {
if (sptr->sh_addr < nextpaddr) {
fprintf(stderr,"Unexpected section address\n");
exit(1);
}
padtot = sptr->sh_addr-nextpaddr;
printf("Pad 0x%x bytes\n",padtot);
padbyte = PadByte;
while(padtot) {
Write(fd,&padbyte,1);
padtot--;
}
}
}
printf("Sec %-8s at 0x%-8x 0x%-6x bytes\n",
name,sptr->sh_addr,sptr->sh_size);
cp = (uchar *)Malloc(sptr->sh_size);
Lseek(elfFD,sptr->sh_offset,SEEK_SET);
read(elfFD,cp,sptr->sh_size);
Write(fd,cp,sptr->sh_size);
free(cp);
nextpaddr = sptr->sh_addr + sptr->sh_size;
firstone = 0;
}
free(name);
}
/* If non-zero, then insert the specified number of bytes just prior */
/* to the end of the binary file. Starting at a point 4-bytes befor */
/* the end. This is needed because of a problem with GNU linker that */
/* does not allow a 4-byte section to exist at 0xfffffffc (branch */
/* instruction location for PPC403GCX). */
if (insertPAD) {
int i;
char branch[4];
Lseek(fd,-4,SEEK_CUR);
Read(fd,branch,4);
Lseek(fd,-4,SEEK_CUR);
for(i=0;i<insertPAD;i++)
Write(fd,&PadByte,1);
Write(fd,branch,4);
}
close(fd);
}
/* StripElfFile():
This is a bit tricky for elf. We can only strip out certain
sections, and the sections are not necessarily at the end of
the file; hence, chunks of the file are removed and the file
offsets in the section header table must be adjusted.
*/
void
StripElfFile(char *stripto,char *append)
{
uchar *cp;
FILE *zout;
unsigned long shoffs, offset_delta;
int stripfd, sidx, newsectot;
struct elf_shdr *sptr, *scntbl_s, *sptr_s;
struct stat zstat;
fprintf(stderr,"Stripping %s into %s \n",elfFname,stripto);
fprintf(stderr,"Not working yet\n");
return;
/* Allocate space for new section header table that may be smaller */
/* than the current table... */
scntbl_s = (struct elf_shdr *)Malloc(Ehdr.e_shnum * Ehdr.e_shentsize);
/* Create the destination file... */
unlink(stripto);
if ((stripfd = open(stripto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1) {
perror(stripto);
exit(1);
}
/* Up to the first section, do a blind copy from original */
/* file to new compressed file... */
if (debug)
fprintf(stderr,"Copying first %ld bytes\n",ScnTbl[1].sh_offset);
Lseek(elfFD,0,SEEK_SET);
cp = Malloc(ScnTbl[1].sh_offset);
Read(elfFD,cp,ScnTbl[1].sh_offset);
Write(stripfd,cp,ScnTbl[1].sh_offset);
free(cp);
scntbl_s[0] = ScnTbl[0];
newsectot = 0;
offset_delta = 0;
sptr_s = scntbl_s+1;
/* For each section, either copy it or remove it... */
for(sptr=&ScnTbl[1],sidx=1;sidx<Ehdr.e_shnum;sidx++,sptr++) {
char *name;
name = GetElfSectionName(ScnTbl[sidx].sh_name);
if (!strcmp(name,".comment")) {
if (verbose)
fprintf(stderr,"Removing %s (%d bytes)\n",name,sptr->sh_size);
offset_delta += sptr->sh_size;
}
else {
*sptr_s++ = *sptr;
newsectot++;
if ((sptr->sh_size) && (sptr->sh_type != SHT_NOBITS)) {
if (verbose)
fprintf(stderr,"Copying %s (%d bytes)\n",
name,sptr->sh_size);
Lseek(elfFD,sptr->sh_offset,SEEK_SET);
cp = Malloc(sptr->sh_size);
Read(elfFD,cp,sptr->sh_size);
Write(stripfd,cp,sptr->sh_size);
sptr_s->sh_offset -= offset_delta;
free(cp);
}
}
/* Assuming the section header table comes just after the section */
/* header string table section, insert the modified table... */
/* Note that the header may be endian-converted, so compensate for */
/* this prior to writing to file... */
if (!strcmp(name,".shstrtab")) {
int i;
sidx++;
sptr++;
sptr_s++;
fprintf(stderr,"section headers at section # %d\n",sidx);
/* Adjust the size of the section header table: */
scntbl_s[sidx].sh_size = newsectot * Ehdr.e_shentsize;
/* Store this current file location: */
shoffs = tell(stripfd);
if(debug)
fprintf(stderr,"Inserting scnhdr at 0x%x\n",shoffs);
for(i=0;i<newsectot;i++) {
scntbl_s[i].sh_name = otherEnd32(Ecvt,scntbl_s[i].sh_name);
scntbl_s[i].sh_type = otherEnd32(Ecvt,scntbl_s[i].sh_type);
scntbl_s[i].sh_flags = otherEnd32(Ecvt,scntbl_s[i].sh_flags);
scntbl_s[i].sh_addr = otherEnd32(Ecvt,scntbl_s[i].sh_addr);
scntbl_s[i].sh_offset = otherEnd32(Ecvt,scntbl_s[i].sh_offset);
scntbl_s[i].sh_size = otherEnd32(Ecvt,scntbl_s[i].sh_size);
scntbl_s[i].sh_link = otherEnd32(Ecvt,scntbl_s[i].sh_link);
scntbl_s[i].sh_info = otherEnd32(Ecvt,scntbl_s[i].sh_info);
scntbl_s[i].sh_addralign =
otherEnd32(Ecvt,scntbl_s[i].sh_addralign);
scntbl_s[i].sh_entsize =
otherEnd32(Ecvt,scntbl_s[i].sh_entsize);
}
Write(stripfd,(char *)scntbl_s,(int)(newsectot*Ehdr.e_shentsize));
for(i=0;i<newsectot;i++) {
scntbl_s[i].sh_name = otherEnd32(Ecvt,scntbl_s[i].sh_name);
scntbl_s[i].sh_type = otherEnd32(Ecvt,scntbl_s[i].sh_type);
scntbl_s[i].sh_flags = otherEnd32(Ecvt,scntbl_s[i].sh_flags);
scntbl_s[i].sh_addr = otherEnd32(Ecvt,scntbl_s[i].sh_addr);
scntbl_s[i].sh_offset = otherEnd32(Ecvt,scntbl_s[i].sh_offset);
scntbl_s[i].sh_size = otherEnd32(Ecvt,scntbl_s[i].sh_size);
scntbl_s[i].sh_link = otherEnd32(Ecvt,scntbl_s[i].sh_link);
scntbl_s[i].sh_info = otherEnd32(Ecvt,scntbl_s[i].sh_info);
scntbl_s[i].sh_addralign =
otherEnd32(Ecvt,scntbl_s[i].sh_addralign);
scntbl_s[i].sh_entsize =
otherEnd32(Ecvt,scntbl_s[i].sh_entsize);
}
offset_delta += (Ehdr.e_shnum - newsectot) * Ehdr.e_shentsize;
}
}
if (debug)
fprintf(stderr,"offset_delta = %d\n",offset_delta);
/* Adjust the file header to point to the new section header table. */
Lseek(stripfd,0x20,SEEK_SET);
shoffs = otherEnd32(Ecvt,shoffs);
Write(stripfd,(char *)&shoffs,4);
close(stripfd);
}
#if 0
if (append) {
struct stat buf;
char *aspace;
if ((afd = open(append,O_RDONLY|O_BINARY))==-1)
{
perror(append);
exit(1);
}
stat(append,&buf);
aspace = Malloc(buf.st_size+32);
read(afd,aspace,buf.st_size);
Write(sfd,aspace,buf.st_size);
free(aspace);
close(afd);
}
close(sfd);
#endif
void
ShowElfMap(int fileoffsets)
{
int i;
unsigned long size;
struct elf_shdr *eshdr;
if (debug >= 2)
fprintf(stderr,"ShowElfMap()\n");
for(i=0;i<Ehdr.e_shnum;i++) {
eshdr = &ScnTbl[i];
size = eshdr->sh_size;
if (size)
size--;
if ((eshdr->sh_flags) || (fileoffsets)) {
printf("%10s: 0x%08x..0x%08x (%ld bytes) %s\n",
GetElfSectionName(eshdr->sh_name),
eshdr->sh_addr,eshdr->sh_addr+size,eshdr->sh_size,
VerboseShflags(eshdr->sh_flags));
if (fileoffsets) {
printf(" ELF file offset: 0x%08x\n",
eshdr->sh_offset);
}
}
}
printf("Entrypoint: 0x%08x\n",Ehdr.e_entry);
}
char *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -