📄 elfinfo.cpp
字号:
#include "windows.h"
#include "stdio.h"
#define WORDSWAP(w) (((w) >> 8) | \
(((w) << 8) & 0xFF00))
#define DWORDSWAP(dw) (((dw) >> 24) | \
(((dw) >> 8) & 0x0000FF00) | \
(((dw) << 8) & 0x00FF0000) | \
(((dw) << 24) & 0xFF000000))
// E_machine
#define MACH_EM_386 0x0003 //Intel Architecture
#define MACH_EM_68K 0x0004 //Motorola 68000
#define MACH_EM_88K 0x0005 //Motorola 88000
#define MACH_EM_860 0x0007 //Intel 80860
#define MACH_EM_MIPS 0x0008 //MIPS RS3000 Big-Endian
#define MACH_EM_MIPS_RS4_BE 0x000A //MIPS RS4000 Big-Endian
#define MACH_EM_ARM 0x0028 //ARM/Thumb Architecture
#define CLASS_32BIT 0X01
#define BIG_END_EXCUT_ELF 0x0200 //big endian
#define LTL_END_EXCUT_ELF 0x0002 //little endian
#define ENCODE_MSB 0x02
#define IMAGE_NULL 0
#define IMAGE_LOAD 0x00000001
#define IMAGE_NOTE 0x00000004
#define COMPRESS 0x0001
#define USERCODE 0x0100
#define VALIDELF 0
#define NOT_ELF -1
#define NOT_MC68KCODE -2
#define NOT_EXCUTE -3
#define NOT_MSB -4
#define NOT_32BIT -5
#define UNRECOG_HEADER -6
#define UNOPEN_FILE -7
#pragma pack(1)
#define EI_NIDENT 16
typedef struct {
DWORD ident; // '7F' "ELF"
BYTE fileclass; // 1:32 bit system ; 2:64 bit system
BYTE dataencode; //1: LSB ; 2:MSB
BYTE versionf; // must be 1
BYTE pad; // 0
BYTE reserv[8];// must be 0
WORD type; // 0:No file;/ 1:Relocatable file;/2:Executable file;/3:Shared object file;/4:Core file;/0xff00:Processor-specific;/0xffff:Processor-specific
WORD machine; // 3:Intel Architecture;/ 4:Motorola 68000 : See E_machine macro define
DWORD version; // must to be 1
DWORD entry; // the virtual address to which the system first transfers control,
DWORD phoff; // the program header table's file offset in bytes.
DWORD shoff; // the section header table's file offset in bytes.
DWORD flags; // processor-specific flags associated with the file.
WORD ehsize; // the ELF header's size in bytes.
WORD phentsize;// the size in bytes of one entry in the file's program header table;
WORD phnum; // the number of entries in the program header table.
WORD shentsize;// section header's size in bytes.
WORD shnum; // the number of entries in the section header table.
WORD shstrndx; // the section header table index of the entry associated with the section name string table.
} Elf_hd;
//Program Header
typedef struct
{
DWORD type; // 0 : PT_NULL; 1 : PT_LOAD; 2 : PT_DYNAMIC; 3:PT_INTERP; 4:PT_NOTE; 5:PT_SHLIB; 6:PT_PHDR; 0x70000000:PT_LOPROC; 0x7fffffff:PT_HIPROC
DWORD offset; // offset of the file at which the first byte of the segment resides.
DWORD vaddr; // the virtual address at which the first byte of the segment residesin memory.
DWORD paddr; // reserved for the segment's physical address.
DWORD filesz; // the number of bytes in the file image of the segment;在文件里的长度。
DWORD memsz; // the number of bytes in the memory image of the segment;生成的映象文件长度.多余部份填0 。如bss段
DWORD flags; //
DWORD align; //
}ELF_Phdr;
typedef struct
{
DWORD poffset; //目标段在文件的偏移
DWORD vaddr; //目的地址
DWORD romsize; //目标段在在文件内的大小
DWORD memsize; //目标段在拷贝进目的内存区的大小
} e_BootProg;
typedef struct
{
WORD Type; //类型,如压缩
WORD ProgNum; //所有的程序段总数
DWORD ProgEntry; //程序总的入口地址(实际最后的)
DWORD RomSize; //文件大小
DWORD Reserve;
} e_BOOTinfo;
int GetElfHeader(FILE *fp, Elf_hd &fhdr)
{
int iEndian = BIG_END_EXCUT_ELF;
fread(&fhdr,1,sizeof(fhdr), fp);
/*判断大小端*/
switch( fhdr.type )
{
case BIG_END_EXCUT_ELF:
fhdr.type = WORDSWAP( fhdr.type );
fhdr.machine = WORDSWAP( fhdr.machine );
fhdr.ehsize = WORDSWAP( fhdr.ehsize );
fhdr.phentsize = WORDSWAP( fhdr.phentsize );
fhdr.phnum = WORDSWAP( fhdr.phnum );
fhdr.shentsize = WORDSWAP( fhdr.shentsize );
fhdr.shnum = WORDSWAP( fhdr.shnum );
fhdr.shstrndx = WORDSWAP( fhdr.shstrndx );
fhdr.version = DWORDSWAP( fhdr.version );
fhdr.entry = DWORDSWAP( fhdr.entry );
fhdr.phoff = DWORDSWAP( fhdr.phoff );
fhdr.shoff = DWORDSWAP( fhdr.shoff );
fhdr.flags = DWORDSWAP( fhdr.flags );
iEndian = BIG_END_EXCUT_ELF;
break;
case LTL_END_EXCUT_ELF:
iEndian = LTL_END_EXCUT_ELF;
break;
default:
return NOT_EXCUTE;
break;
}
if( fhdr.ident != 0x464c457f || fhdr.ehsize != 0x0034 || fhdr.phentsize !=0x0020 )
return NOT_ELF;
if( fhdr.fileclass != CLASS_32BIT )//fhdr.machine != MACH_EM_68K ||
return NOT_32BIT;
switch(fhdr.machine )
{
case MACH_EM_68K :
printf(" \n Motorola MC68K code\n");
break;
case MACH_EM_386:
printf(" \n Intel code\n");
break;
case MACH_EM_ARM:
printf(" \n ARM code\n");
default :
break;
}
return iEndian;
}
/*
参数:pShd : Sector/Prog 信息缓存
pfhd : Elf文件头信息
pBootPrg : 映象段信息缓存
nEndian : 大小端
ProgBegin: Sector/Prog 在文件的起始偏移
返回:所有Sector/Prog的大小和
*/
int GetSections(ELF_Phdr * pShd, Elf_hd * pfhd, FILE * pf, \
e_BootProg * pBootPrg ,int nEndian, int * ProgBegin)
{
int btpgsz = sizeof(e_BootProg) * pfhd->phnum;
int copylen = 0;
fseek(pf,pfhd->phoff,SEEK_SET);
for(int num=0; num<pfhd->phnum ;num++)
{
int r=fread(&pShd[num],1,sizeof(ELF_Phdr),pf);
if( nEndian == BIG_END_EXCUT_ELF )
{
pShd[num].type = DWORDSWAP( pShd[num].type );
pShd[num].offset = DWORDSWAP( pShd[num].offset );
pShd[num].vaddr = DWORDSWAP( pShd[num].vaddr );
pShd[num].paddr = DWORDSWAP( pShd[num].paddr );
pShd[num].filesz = DWORDSWAP( pShd[num].filesz );
pShd[num].memsz = DWORDSWAP( pShd[num].memsz );
pShd[num].flags = DWORDSWAP( pShd[num].flags );
pShd[num].align = DWORDSWAP( pShd[num].align );
}
if(pShd[num].type != IMAGE_LOAD && pShd[num].type != IMAGE_NOTE
&& pShd[num].type != IMAGE_NULL)
{
printf("错误,有不可识别的段");
return -1;
}
if(num ==0)
{
*ProgBegin = pShd[num].offset ;
}
pShd[num].offset = pShd[num].offset - *ProgBegin + btpgsz +sizeof(e_BOOTinfo);
pBootPrg[num].memsize = pShd[num].memsz ;
pBootPrg[num].poffset = pShd[num].offset ;
pBootPrg[num].romsize = pShd[num].filesz ;
pBootPrg[num].vaddr = pShd[num].vaddr ;
if( nEndian == BIG_END_EXCUT_ELF )
{
pBootPrg[num].memsize = DWORDSWAP( pBootPrg[num].memsize );
pBootPrg[num].poffset = DWORDSWAP( pBootPrg[num].poffset );
pBootPrg[num].romsize = DWORDSWAP( pBootPrg[num].romsize );
pBootPrg[num].vaddr = DWORDSWAP( pBootPrg[num].vaddr );
}
copylen += pShd[num].filesz ;
}
return copylen;
}
void ShowHelp()
{
printf("\n ELF file tools 1.2\n Copyright ? Yu GuoRong,2004");
printf("\n==============================================================================");
printf("\n\nUseage:");
printf("\n===============================================================================");
printf("\n ELF sourcefile [/parament]");
printf("\n parament as fellow: ");
printf("\n /o filename : Output dat file, Default is 'elf.dat' ") ;
printf("\n /i filename : Output info file, Default add to beginning of the dat file ");
printf("\n /a : Genarate image offset address, Default is 0 (not suport)");
printf("\n /c : Genarate a compressed image, Default is Uncompress (need version >= 1.3)") ;
printf("\n===============================================================================");
getchar();
exit(-1);
}
void ErrorHandle(int nErrorcode)
{
switch( nErrorcode )
{
case NOT_ELF:
printf("错误:打开文件不是有效的ELF文件!");
break;
case NOT_MC68KCODE:
printf("错误:不是MC68000系列代码,不能转换");
break;
case NOT_EXCUTE:
printf("错误:不是可执行代码,请连接后再转换");
break;
case NOT_MSB:
printf("??:怎么会是LSB(低字节在前)?");
case UNOPEN_FILE:
printf("错误:不能打开文件");
break;
}
::fcloseall();
exit(-1);
return;
}
#define POSTADDR 0// 0x01003000
void Elf(char *filename,char * OutDatFile,char * OutInfoFile)
{
int PostAddr = POSTADDR;
int iEndian = BIG_END_EXCUT_ELF;
FILE * fpr = fopen(filename,"rb");
if(fpr == NULL)
{
printf("\nCan't open source file.please Read and try again");
ShowHelp();
}
Elf_hd fhdr;
iEndian = GetElfHeader(fpr,fhdr) ;
switch( iEndian )
{
case BIG_END_EXCUT_ELF:
printf(" Big Endian\n");
break;
case LTL_END_EXCUT_ELF:
printf(" Little Endian\n");
break;
default:
ErrorHandle( iEndian );
return;
}
int btpgsz = sizeof(e_BootProg) * fhdr.phnum;
ELF_Phdr * phdr = new ELF_Phdr[fhdr.phnum];
e_BootProg * pBootPrg = new e_BootProg[fhdr.phnum];
memset(&pBootPrg[0],0,(sizeof(e_BootProg)*fhdr.phnum));
memset(&phdr[0],0, (sizeof(ELF_Phdr) * fhdr.phnum) );
int ProgBegin = 0 ;
int copylen = GetSections(phdr, &fhdr, fpr, pBootPrg, iEndian, &ProgBegin);
if(copylen < 0 )
{
ErrorHandle(UNRECOG_HEADER);
}
e_BOOTinfo info;
if( iEndian == BIG_END_EXCUT_ELF )
{
info.ProgNum = WORDSWAP( fhdr.phnum );
info.Type = WORDSWAP( USERCODE );
info.RomSize = DWORDSWAP( copylen );
info.ProgEntry = DWORDSWAP( fhdr.entry );
info.Reserve = DWORDSWAP( PostAddr );
}
else
{
info.ProgNum = fhdr.phnum;
info.Type = USERCODE;
info.RomSize = copylen;
info.ProgEntry = fhdr.entry;
info.Reserve = PostAddr;
}
FILE * fpinfo =NULL;
if(OutInfoFile[0] != 0)
fpinfo = fopen(OutInfoFile,"wb");
FILE * fpdat = fopen(OutDatFile,"wb");
if( fpdat == NULL)
{
delete phdr;
delete pBootPrg;
ErrorHandle(UNOPEN_FILE);
}
printf("\nCreating info... ");
printf("\nCreating Dat...");
if( fpinfo == NULL)
{
fwrite(&info.Type ,1,sizeof(e_BOOTinfo),fpdat);
fwrite(&pBootPrg[0],1,btpgsz,fpdat);
}
else
{
fwrite(&info.Type ,1,sizeof(e_BOOTinfo),fpinfo);
fwrite(&pBootPrg[0],1,btpgsz,fpinfo);
}
fseek(fpr,ProgBegin,SEEK_SET);
char dat;
for(int i=0;i<copylen;i++)
{
fread(&dat,1,1,fpr);
fwrite(&dat,1,1,fpdat);
}
printf("\nCreat OK! \nPost address offset : %08x\n", PostAddr);
delete phdr;
delete pBootPrg;
fcloseall();
getchar();
}
void main(int argc,char ** argv)
{
int i =1;
if(argc <= 1) ShowHelp();
char filename[1024];
char OutDatFile[512] = {"elf.dat"};
char OutInfoFile[512] ={0};
while(i<argc)
{
if(argv[i][0] == '/' && argv[i][2] == '\0')
{
switch(argv[i][1])
{
case 'o': //out file
case 'O':
strcpy(OutDatFile,argv[++i]);
break;
case 'i': //info file
case 'I':
strcpy(OutInfoFile,argv[++i]);
break;
case 'A': //addr
case 'a':
//int PostAddr = strtoi(argc[++i]);
break;
case 'c':
case 'C':
break;
case '?':
ShowHelp();
break;
}
}
else if(i ==1)
strcpy(filename,argv[i]);
i++;
}
Elf(filename,OutDatFile,OutInfoFile);
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -