Journey to geekos-Analysis of the formats of project1 (parse an elf executable files) and elf files

Source: Internet
Author: User

Before we want to know the assignment of this project, we first need to compile this project and start bochs. The compilation is as fast as the previous project. However, bochs encountered an error during startup.

00000000000p[     ] >>PANIC<< .bochsrc:10: directive 'diskc' not understood

I have read the following sentence in boshrc: 10 diskc: file = diskc. IMG, cyl = 40, heads = 8, SPT = 64

After reading the compiled project1, there is a disk. IMG. What is diskc. IMG? In fact, diskc. IMG is a hard disk image. We need to load this image because we will definitely use it below. the so-called image is the corresponding byte of the original device. therefore, you must. configure disk in bochrc. IMG.

Add the following to boshrc:

ata0-master:type=disk, mode=flat, path=./diskc.img, cylinders=40, heads=8, spt=64

This statement sets the hard disk parameter. The type is (disk, CDROM) mode (flat <a file layout>, Concat <multi-file layout>, external, DLL ....), PATH is the path, cylinders is the cylindrical size, heads is the header size, SPT is the number of sectors per track

This explanation is much clearer. Add it and comment out the 10th rows. Then start.

Started successfully! You can see the assigment of this project:Parse an elf executable image.

Carefully read the attached manual project2's required reading and synopsis. the main task is to implement src/geekos/elf. c's parse_elf_executable () function. the function is used to read the offset, length, user address for the executable's text and data segments in the ELF File. then fill in the exe_format!

Therefore, we need to first understand the ELF format file. The sample for analysis is named a.exe under project1 user. the source code is a. c.

You can search for ELF format file from Google. Here we can also explore the ELF file:

-> Elf is the default executable file format in Linux. Elf contains three types: relocated files (such. O target file), shared file, executable file. the ELF file contains several important parts: Elf header, sections, string table, symbol table, and relocation (Relocation types. let's take a rough look at the organization chart of the ELF File.

The first is the connection view, the second is the execution view, the elf header (ELF header), the program header table (Program header table), and the section header table (node header table)

Starting from the data structure in the elf header, open geekos/elf. C and check the structure below.

14/* 15 * elf header at the beginning of the executable. 16 */17 typedef struct {18 unsigned char | ident [16]; // information 19 unsigned short | type; // file type 20 unsigned short | machine; // hardware system 21 unsigned int | version; 22 unsigned int | entry; // program entry point 23 unsigned int | phoff; // The program header offset 24 unsigned int | sphoff; // segment header offset 25 unsigned int | flags; // processor specific flag 26 unsigned short | ehsize; // elf header length 27 unsigned short | phentsize; // The length of the program header Segment 28 unsigned short | phnum; // The number of program header segments 29 unsigned short | shentsize; // The length of the section header segment 30 unsigned short | shnum; // 31 unsigned short | shstrndx; // segment header segment table index 32} elfheader;

I have commented on the relevant information in it. We will use the readelf-htool to download the.exe file to compare it.

ELF Header:  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00   Class:                             ELF32  Data:                              2's complement, little endian  Version:                           1 (current)  OS/ABI:                            UNIX - System V  ABI Version:                       0  Type:                              EXEC (Executable file)  Machine:                           Intel 80386  Version:                           0x1  Entry point address:               0x1000  Start of program headers:          52 (bytes into file)  Start of section headers:          4420 (bytes into file)  Flags:                             0x0  Size of this header:               52 (bytes)  Size of program headers:           32 (bytes)  Number of program headers:         3  Size of section headers:           40 (bytes)  Number of section headers:         7  Section header string table index: 4

Let's take a look at it. Next we will study the program header table and continue to look at its struct:

34/* 35 * an entry in the ELF Program header table. 36 * This describes a single segment of the executable. 37 */38 typedef struct {39 unsigned int type; // segment type 40 unsigned int offset; // The segment position is relative to the start offset 41 unsigned int vaddr of the file; // The address of the segment in the memory is 42 unsigned int paddr; // the physical address of the segment is 43 unsigned int filesize; // The length of the segment in the file is 44 unsigned int memsize; // The length of the segment in the memory is 45 unsigned int flags; // mark 46 unsigned int alignment; // alignment mark 47} programheader;

Use readelf-L to view the information of a.exe.

Elf file type is EXEC (Executable file)Entry point 0x1000There are 3 program headers, starting at offset 52Program Headers:  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align  LOAD           0x001000 0x00001000 0x00001000 0x000a2 0x000a2 R E 0x1000  LOAD           0x0010c0 0x000020c0 0x000020c0 0x00028 0x00028 RW  0x1000  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4 Section to Segment mapping:  Segment Sections...   00     .text    01     .data    02   

For more information about elf, see the documentation. Let's take a closer look at the elf issue.

The first step is to study the prototype of parse_elf_executable.

int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, struct Exe_Format *exeFormat);

Exefiledata:This buffer contains executable files, that is, elf files.

Exefilelength:This is the length of the execution file.

Exeformat:This struct contains the file segment and entry address.

Return Value: int:RET returns 0 as successful

It is easy to parse the elfheader and programheader struct, and use these two struct to parse the exefiledata contents.

The exefiledata header must start with elfheader, because we have analyzed it before, and then the property of poff is the offset of the program header, the first address + poff can get the first address of the programheader.

33     elfHeader* header = exeFileData;34     programHeader* pHeader = (exeFileData+header->phoff);

Continue to check the struct exe_format.

 77 /* 78  * A struct concisely representing all information needed to 79  * load an execute an executable. 80  */ 81 struct Exe_Format { 82     struct Exe_Segment segmentList[EXE_MAX_SEGMENTS]; /* Definition of segments */ 83     int numSegments;|   |   /* Number of segments contained in the executable */ 84     ulong_t entryAddr;|  |  /* Code entry point address */ 85 };

Segmentlist is an array of segments.

Numsegments is the number of segments.

Entryaddr is the entry address.

Numsegments is the phnum in elfheader, and entryaddr is the entry of elfheader.

Because segmentlist is an array, but each element in it is a struct, we first find out the content of this struct:

 57 /* 58  * A segment of an executable. 59  * It specifies a region of the executable file to be loaded 60  * into memory. 61  */ 62 struct Exe_Segment { 63     ulong_t offsetInFile;|   /* Offset of segment in executable file */ 64     ulong_t lengthInFile;|   /* Length of segment data in executable file */ 65     ulong_t startAddress;|   /* Start address of segment in user memory */ 66     ulong_t sizeInMemory;|   /* Size of segment in memory */ 67     int protFlags;| |    /* VM protection flags; combination of VM_READ,VM_WRITE,VM_EXEC */ 68 };

For a moment, these are not the offset, filesize, vaddr, memsize, and flags of the programheader.

OK. Everything is ready, so I have to write down the program.

30 int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, 31     struct Exe_Format *exeFormat) 32 { 33     elfHeader* header = exeFileData; 34     programHeader* pHeader = (exeFileData+header->phoff); 35     exeFormat->numSegments = header->phnum; 36     exeFormat->entryAddr = header->entry; 37     int i = 0; 38     for (; i< header->phnum; i++) { 39         exeFormat->segmentList[i].offsetInFile = pHeader->offset; 40         exeFormat->segmentList[i].lengthInFile = pHeader->fileSize; 41         exeFormat->segmentList[i].startAddress = pHeader->vaddr; 42         exeFormat->segmentList[i].sizeInMemory = pHeader->memSize; 43         exeFormat->segmentList[i].protFlags = pHeader->flags; 44         pHeader++; 45     } 46      47     return 0; //!! 48  49     //TODO("Parse an ELF executable image"); 50 }

The entire program is as above. Please note that return 0; Do not forget to put it in. The test result is as follows: Continue project 2 below .!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.