⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elfinfo.cpp

📁 能将ELF /AFX 文件转换成二进制文件的解析源码
💻 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 + -