UNIX / ELF file format and viral analysis
Author: Silvio Cesare
Both the high-end expansion segment or to the low-end expansion data segment may cause segment overlap, and a segment of the memory is positioned again to generate problems with the absolute address. It can be considered to extend the data segment to the high-end, which is not a good idea, some Unix implements the memory protection mechanism, and the data segment is not executable. The page fills on the segment border provide a place inserted into the parasitic code, as long as the space is allowed. Inserting the parasitic code here does not destroy the original segment, no relocation is required. The page fill at the end of the text section is a good place, and finally looks like this: Keywords: [...] a complete page V parasitic code T text segment content d Data segment content P padding page number # 1 [TTTTTTTTTTTTVVVPP] <- Text Segment # 2 [PpppdddddddddddPPPPP] <- A more complete ELF executable layout is as follows: Elf Header Program Header Table Segment 1 Segment 2 Section Header Table Section 1. Typical, additional The section (which there is no corresponding segment) is used to store debug information, symbol table, and so on. Here are some content from the ELF specification: The ELF header is at the beginning, saving a "road map", describing the organizational structure of the file. Save a large number of link information, symbolic table, relocation information, etc. If there is a "Program HEADER TABLE", you will tell the operating system how to create a process image (execute a program). The executable must have a "Program Header Table", which can be positioned without the table. "Section Header Table" describes the section organization of the file. Each section has a group in this table, and the entry contains information such as the celebrities, segment size. The files used during the link must have a "section header table", and other target files can have no table. After inserting parasitic code, the ELF file layout is as follows: Elf Header Program Header Table Segment 1 - Text Segment (Main Code) - Parasitic Segment 2 Segment Header Table Segment 1. The section n parasitic code must be physically inserted into the ELF file, text segment You must expand to include new code.
The following information is from /usr/include/elf.h/* the elf file header. This Appers at the start of every Elf file. * / # Define ei_nident (16) typef strunt {unsigned char e_ident [ei_nident]; / * MAGIC number and other info * / Elf32_Half e_type; / * Object file type * / Elf32_Half e_machine; / * Architecture * / Elf32_Word e_version; / * Object file version * / Elf32_Addr e_entry; / * Entry point virtual address * / Elf32_Off e_phoff; / * Program header table file offset * / Elf32_Off e_shoff; / * Section header table file offset * / Elf32_Word e_flags; / * Processor-specific flags * / Elf32_Half e_ehsize; / * ELF header size in bytes * / Elf32_Half e_phentsize; / * Program header table Entry size * / ELF32_HALF E_PHNUM; / * Program Header Table Entry Count * / ELF32_HALF E_SHENTSIZE; / * Section Header Table Entry Size * / ELF32_HALF E_SHNUM; / * Section header Table entry count * / ELF32_HALF E_SHSTRNDX; / * section header string Table index * /} ELF32_EHDR; E_ENTRY Save the virtual address of the program entry point. E_PHOFF is the offset of "Program Header Table" in the file. Therefore, in order to read "Program Header Table", it is necessary to call LSeek () to locate the table. E_SHOFF is the offset of "Section Header Table" in the file. This table is located at the end of the file. After inserting parasitic code at the end of the text segment, the E_SHOFF must be updated to the new offset.
. / * Program segment header * / typedef struct {Elf32_Word p_type; / * Segment type * / Elf32_Off p_offset; / * Segment file offset * / Elf32_Addr p_vaddr; / * Segment virtual address * / Elf32_Addr p_paddr; / * Segment physical address * / Elf32_Word p_filesz; / * segment size in file * / Elf32_Word p_memsz; / * segment size in memory * / Elf32_Word p_flags; / * segment flags * / Elf32_Word p_align; / * segment alignment * /} Elf32_Phdr; loadable segment (text segment / Data Section) The member variable p_type identifies is loaded in "Program HEADER", its value is PT_LOAD (1). Like E_SHOFF in "Elf Header", the P_OFFSET member here must update the parasitic code to point to the new offset. P_vaddr Specifies the starting virtual address of the segment. The base address is re-calculated with the p_vaddr, and you can specify where the program stream begins. You can use the p_vaddr to specify where the program stream begins. P_filesz and p_memsz respectively occupy the file size and memory size that should be occupied. The .BSS section corresponds to the data section that is not initialized in the data segment. We don't want to make uninitialized data, but the process image must ensure that enough memory space can be assigned. The .BSS section is located at the end of the data segment, and any positioning of the file size is assumed to be located in this section. . / * Section header * / typedef struct {Elf32_Word sh_name; / * Section name (string tbl index) * / Elf32_Word sh_type; / * Section type * / Elf32_Word sh_flags; / * Section flags * / Elf32_Addr sh_addr; / * Section virtual addr at execution * / Elf32_Off sh_offset; / * Section file offset * / Elf32_Word sh_size; / * Section size in bytes * / Elf32_Word sh_link; / * Link to another section * / Elf32_Word sh_info; / * Additional section information * / Elf32_Word sh_addralign; / * Section alignment * / ELF32_WORD SH_ENTSIZE; / * ENTRY SIZE IF Section Holds Table * /} ELF32_SHDR; SH_OFFSET Specifies the offset in the file.
In order to insert parasitic code at the end of the text section, we must do the following: * Fixed the p_shoff * in "Elf Header" Position "Text Segment Program" * Fix P_Filesz * Fix P_MEMSZ * Other phDr * Fixed P_offset after text paragraph PHDR * correction p_offset * For SHDR * correcting sh_offset * in the file due to the insertion of parasitic code, physically inserting parasitic code to this location text segment p_offset p_filesz (Original) There is a big problem here, and the ELF specification points out, p_vaddr mod PAGE_SIZE == p_offset mod PAGE_SIZE in order to meet this requirement: * Fixed "ELF header" in p_shoff, increase the size * PAGE_SIZE locate "text segment program header" * Fixed p_filesz * Fixed p_memsz * for other phdr after the text segment * Fixed phdr P_offset, increasing Page_Size Size * Increases Page_Size Size * For SHDR * correcting sh_offset that affects the shift of parasitic code, adding page_size size * Physically inserted parasitic code and fill in the file (make sure to make a full page) to this location Text segment P_offset p_filesz (Original) We also need to correct the virtual address of the program entry point, so that the parasitic code is executed in the host code. At the same time, it is necessary to jump back to the end of the host code in the end of the parasitic code to continue the normal process. * Fixed P_SHOFF in "Elf Header", increase the page_size size * correct the end of the parasitic code, enabling it to jump back to the original code original mouthpoint * Locate "Text Segment Program" * Fix "Elf Header" in the "Elf Header", pointing P_vaddr p_filesz * Fixed P_Filesz * Fixed P_MEMSZ * Fixed P_OffSet after text segment phdr, increase Page_SIZE Size * For the last shdr * correcting sh_len (should be sh_size, uncertain) for text segments (should be sh_size, uncertain), increase parasitic code size * Increase the SHDR * correcting SH_OFFSET, which affects the offset of the parasitic code, adds the page_size size * Physically inserted parasitic code in the file and fill (make sure to make a full page) to this location Text segment p_offset p_filesz (Original The virus can randomly traverse a directory tree, find files that E_TYPE equal to ET_EXEC or ET_DYN, which is infected, which is the executable file and dynamic link library file. ★ Analyze Linux virus virus requirements Do not use libraries, avoid libc, and use system call mechanisms. In order to dynamically apply for a heap, a BRK system call should be called. The address of the constant string is obtained using the same technique as the buffer overflows. Use GCC -S to compile C code and observe the adjustment ASM code.