$34.99
(This lab is to be done SOLO and NO completion labs will be held)
In the previous lab, you learned to investigate and change ELF files using hexedit, and other command-line tools. In this lab, you will continue to manipulate ELF files, this time using your own code (written in C).
We will parse the ELF file and extract useful information from it. In particular, we will access the data in the section header table, and in the symbol table. We will also learn to use the mmap system call.
Important
This lab is written for 64bit machines. Some of the computers in the labs already run on a 64bit OS (use uname -a to see if the linux OS is 64bit or not). 32bit and 64bit machines have different instruction sets and different memory layout. Make sure to include the -m64 flag when you compile files, and to use the Elf64 data structures (and not the Elf32 ones).
In order to know if an executable file is compiled for 32bit or 64bit platform, you can use readelf, or the file command-line tool (for example: file /bin/ls).
Useful Tips
Print debugging messages: in particular the offsets of the various items, as you discover them from the headers.
Use hexedit and readelf to compare the information you are looking for, especially if you run into unknown problems. hexedit is great if you know the exact location of the item you are looking for.
Note that while the object files you will be processing will be linked using ld, and will, in most cases, use direct system calls in order to make the ELF file simpler, there is no reason why the programs you write need use this interface. You are allowed to use the standard library when building your own C programs.
In order to keep sane in the following lab as well, understand what you are doing and keep track that and your code.
Lab 8 Tasks
You must use only the mmap system call to read/write data into your ELF files from this point onwards.
Task 0
This task is about learning to use the mmap system call. Read about the mmap system call (man mmap).
Write a program that uses the mmap to examine the header of a 64bit ELF file (include and use the structures in elf.h). The program is first activated as:
myELF
The program then uses a menu similar to lab 7, with available operations, as follows:
Choose action:
1-Examine ELF File
2-Quit
Note that the menu should use the same technique as in lab 7, i.e. an array of structures of available options. Quit should unmap and close any mapped or open files, and "exit normally". Examine ELF Files queries the user for an ELF file name to be used and examined henceforth. All file input should be read using the mmap system call. You are NOT ALLOWED to use read, or fread.
To make your life easier throughout the lab, map the entire file with one mmap call.
In Examine ELF File, after getting the file name, you should close any currently open file (indicated by global variable Currentfd) open the file for reading, and then print the following:
1. Bytes 1,2,3 of the magic number (in ASCII)
2. Entry point (in hexadecimal)
Check using readelf that your data is correct.
Once you verified your output, extend examine to print the following information from the header:
1. Bytes 1,2,3 of the magic number (in ASCII). Henceforth, you should check that the number is consistent with an ELF file, and refuse to continue if it is not.
2. The data encoding scheme of the object file.
3. Entry point (hexadecimal address).
4. The file offset in which the section header table resides.
5. The number of section header entries. 6. The size of each section header entry.
7. The file offset in which the program header table resides.
8. The number of program header entries. 9. The size of each program header entry.
The above information should be printed in the above exact order (Print it as nicely as readelf does). If invoked on an ELF file, examine should initialize a global file descriptor variable Currentfd for this file, and leave the file open. When invoked on a non-ELF file, or the file cannot be opened or mapped at all, you should print an error message, unmap the file (if already mapped) close the file (if already open), and set Currentfd to -1 to indicate no valid file. You probably also should use a global map_start variable to indicate the memory location of the mapped file.
Task 1 - Sections
Extend your myELF program from Task 0 to allow printing of all the Section names in an 64bit ELF file (like readelf -S). That is, modify the menu to add a "Print Section Headers" option:
Choose action:
1-Examine ELF File
2-Print Section Headers
3-Quit
Print Section Names should visit all section headers in the section header table, and for each one print its index, name, address, offset, and size in bytes. Note that this is done for the file currently mapped, so if Currentfd is invalid, just print an error message and return.
The format should be:
[index] section_name section_address section_offset section_size section_type [index] section_name section_address section_offset section_size section_type
[index] section_name section_address section_offset section_size section_type
....
Verify your output is correct by comparing it to the output of readelf.
You can test your code on the following files: a.out, test.
Hints
Global information about the ELF file is in the ELF header, including location and size of important tables. The size and name of the sections appear in the section header table. Recall that the actual name strings are stored in an appropriate section (.shstrtab for section names), and not in the section header!
Task 2 - Symbols
Extend your myELF program from task 1 to support an option that displays information on all the symbol names in a 64bit ELF file. Your menu should now be:
Choose action:
1-Examine ELF File
2-Print Section Headers
3-Print Symbols
4-Quit
The new Print Symbols option should visit all the symbols in the current ELF file (if none, print an error message and return). For each symbol, print its index number, its name and the name of the section in which it is defined. (similar to readelf -s). Format should be:
[index] value section_index section_name symbol_name
[index] value section_index section_name symbol_name
[index] value section_index section_name symbol_name
...
Verify your output is correct by comparing it to the output of readelf.
You should finish everything up to here during the lab! NO completion lab will be held for this lab!
Deliverables:
Tasks 1, and 2 must be completed during the regular lab. You must submit source files for tasks 1 and 2 and a makefile that compiles them. The source files must be named task1.c task2.c, and makefile.