draugr.git


draugr

~ single ELF file analysis tool
git clone https://github.com/djnnvx/draugr.git
log | files | refs | archive | README

mapper.odin (2783B)

      1 package analysis
      2 
      3 import "core:fmt"
      4 import "core:os"
      5 
      6 import "../elf"
      7 
      8 map_output :: proc(data: []u8, info: ^elf.ELF_Info, out_path: string) -> string {
      9 	f, err := open_out(out_path)
     10 	if err != "" {
     11 		return err
     12 	}
     13 	defer close_out(f, out_path)
     14 
     15 	fmt.fprintf(f, "ELF Memory Map\n")
     16 	fmt.fprintf(f, "==============\n\n")
     17 
     18 	fmt.fprintf(f, "File Layout:\n")
     19 	fmt.fprintf(f, "%s\n", "------------------------------------------")
     20 	fmt.fprintf(f, "0x%08x: ELF Header (64 bytes)\n", 0)
     21 
     22 	if info.header.phoff > 0 {
     23 		ph_end := info.header.phoff + u64(len(info.program_hdrs)) * u64(info.header.phentsize)
     24 		fmt.fprintf(f, "0x%08x: Program Headers\n", info.header.phoff)
     25 		fmt.fprintf(f, "0x%08x: Program Headers End\n", ph_end)
     26 	}
     27 
     28 	if info.header.shoff > 0 {
     29 		sh_end := info.header.shoff + u64(len(info.section_hdrs)) * u64(info.header.shentsize)
     30 		fmt.fprintf(f, "0x%08x: Section Headers\n", info.header.shoff)
     31 		fmt.fprintf(f, "0x%08x: Section Headers End\n", sh_end)
     32 	}
     33 
     34 	fmt.fprintf(f, "0x%08x: EOF (file size: %d bytes)\n\n", len(data), len(data))
     35 
     36 	fmt.fprintf(f, "Segments:\n")
     37 	fmt.fprintf(f, "%-13s %-10s %-10s %-10s %-10s %s\n", "Type", "Offset", "VirtAddr", "FileSize", "MemSize", "Flags")
     38 	fmt.fprintf(f, "%s\n", "---------------------------------------------------------------------")
     39 
     40 	for i := 0; i < len(info.program_hdrs); i += 1 {
     41 		ph := info.program_hdrs[i]
     42 		type_str := elf.segment_type_str(ph.type)
     43 		flags_str := elf.flags_to_str(ph.flags)
     44 
     45 		fmt.fprintf(f, "%-13s 0x%08x 0x%08x 0x%08x 0x%08x %s\n",
     46 			type_str, ph.offset, ph.vaddr, ph.filesz, ph.memsz, flags_str)
     47 
     48 		if ph.filesz > 0 {
     49 			if ph.type != elf.PT_NULL {
     50 				print_bar(f, ph.offset, ph.filesz, len(data))
     51 			}
     52 		}
     53 	}
     54 
     55 	fmt.fprintf(f, "\n")
     56 
     57 	fmt.fprintf(f, "Sections:\n")
     58 	fmt.fprintf(f, "%-16s %-10s %-10s %-10s %s\n", "Name", "Type", "Addr", "Offset", "Size")
     59 	fmt.fprintf(f, "%s\n", "------------------------------------------------------------")
     60 
     61 	for i := 0; i < len(info.section_hdrs); i += 1 {
     62 		shdr := info.section_hdrs[i]
     63 		name := elf.get_section_name(info, shdr)
     64 		if name == "" {
     65 			name = fmt.tprintf("[%d]", i)
     66 		}
     67 
     68 		type_str := elf.section_type_str(shdr.type)
     69 
     70 		fmt.fprintf(f, "%-16s %-10s 0x%08x 0x%08x 0x%x\n",
     71 			name, type_str, shdr.addr, shdr.offset, shdr.size)
     72 	}
     73 
     74 	return ""
     75 }
     76 
     77 print_bar :: proc(f: ^os.File, offset: u64, size: u64, total: int) {
     78 	if total <= 0 {
     79 		return
     80 	}
     81 	bar_width := 50
     82 	start := int(offset * u64(bar_width) / u64(total))
     83 	end := int((offset + size) * u64(bar_width) / u64(total))
     84 	if end > bar_width {
     85 		end = bar_width
     86 	}
     87 
     88 	fmt.fprintf(f, "  [|")
     89 	for i := 0; i < bar_width; i += 1 {
     90 		if i >= start {
     91 			if i < end {
     92 				fmt.fprintf(f, "#")
     93 			} else {
     94 				fmt.fprintf(f, "-")
     95 			}
     96 		} else {
     97 			fmt.fprintf(f, "-")
     98 		}
     99 	}
    100 	fmt.fprintf(f, "|]\n")
    101 }
    102