Skip to content

Commit

Permalink
More datastructures.
Browse files Browse the repository at this point in the history
  • Loading branch information
WINSDK committed Apr 16, 2024
1 parent 48e7519 commit 4909441
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 26 deletions.
146 changes: 141 additions & 5 deletions binformat/src/elf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::RawSymbol;
use std::fmt;
use crate::{datastructure, RawSymbol};
use processor_shared::{AddressMap, Addressed, Section, SectionKind};
use object::elf;
use object::read::elf::{ElfFile, FileHeader, SectionHeader};
Expand Down Expand Up @@ -144,25 +145,33 @@ fn parse_sections<'data, Elf: FileHeader>(obj: &'data ElfFile<'data, Elf>) -> Ve
// Program data.
elf::SHT_PROGBITS => (SectionKind::Raw, "PROGBITS"),
// Symbol table.
elf::SHT_SYMTAB => (SectionKind::Raw, "SYMTAB"), // array of Elf64_Sym
elf::SHT_SYMTAB => (SectionKind::Raw, "SYMTAB"),
// String table.
elf::SHT_STRTAB => (SectionKind::CString, "STRTAB"),
// Relocation entries with explicit addends.
elf::SHT_RELA => (SectionKind::Raw, "RELA"),
// Symbol hash table.
elf::SHT_HASH => (SectionKind::Raw, "HASH"),
// Dynamic linking information.
elf::SHT_DYNAMIC => (SectionKind::Raw, "DYNAMIC"), // array of Elf64_Dyn
elf::SHT_DYNAMIC => if obj.is_64() {
(SectionKind::Elf64Dyn, "DYNAMIC")
} else {
(SectionKind::Elf32Dyn, "DYNAMIC")
},
// Notes.
elf::SHT_NOTE => (SectionKind::Raw, "NOTE"),
// Program space with no data (bss).
elf::SHT_NOBITS => (SectionKind::Raw, "NOBITS"),
// Relocation entries without explicit addends.
elf::SHT_REL => (SectionKind::Raw, "REL"), // array of Elf64_Dyn
elf::SHT_REL => (SectionKind::Raw, "REL"),
// Reserved section type.
elf::SHT_SHLIB => (SectionKind::Raw, "SHLIB"),
// Dynamic linker symbol table.
elf::SHT_DYNSYM => (SectionKind::Raw, "DYNSYM"),
elf::SHT_DYNSYM => if obj.is_64() {
(SectionKind::Elf64Sym, "DYNSYM")
} else {
(SectionKind::Elf32Sym, "DYNSYM")
},
// Array of constructors.
elf::SHT_INIT_ARRAY => (SectionKind::Raw, "INIT_ARRAY"),
// Array of destructors.
Expand Down Expand Up @@ -250,3 +259,130 @@ fn parse_sections<'data, Elf: FileHeader>(obj: &'data ElfFile<'data, Elf>) -> Ve

sections
}

#[repr(u64)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug)]
pub enum DynTag {
DT_NULL = 0x0,
DT_NEEDED = 0x1,
DT_PLTRELSZ = 0x2,
DT_PLTGOT = 0x3,
DT_HASH = 0x4,
DT_STRTAB = 0x5,
DT_SYMTAB = 0x6,
DT_RELA = 0x7,
DT_RELASZ = 0x8,
DT_RELAENT = 0x9,
DT_STRSZ = 0xa,
DT_SYMENT = 0xb,
DT_INIT = 0xc,
DT_FINI = 0xd,
DT_SONAME = 0xe,
DT_RPATH = 0xf,
DT_SYMBOLIC = 0x10,
DT_REL = 0x11,
DT_RELSZ = 0x12,
DT_RELENT = 0x13,
DT_PLTREL = 0x14,
DT_DEBUG = 0x15,
DT_TEXTREL = 0x16,
DT_JMPREL = 0x17,
DT_BIND_NOW = 0x18,
DT_INIT_ARRAY = 0x19,
DT_FINI_ARRAY = 0x1a,
DT_INIT_ARRAYSZ = 0x1b,
DT_FINI_ARRAYSZ = 0x1c,
DT_RUNPATH = 0x1d,
DT_FLAGS = 0x1e,
DT_ENCODING = 0x1f,
DT_PREINIT_ARRAY = 0x20,
DT_PREINIT_ARRAYSZ = 0x21,
DT_LOOS = 0x6000000d,
DT_SUNW_RTLDINF = 0x6000000e,
DT_HIOS = 0x6ffff000,
DT_VALRNGLO = 0x6ffffd00,
DT_CHECKSUM = 0x6ffffdf8,
DT_PLTPADSZ = 0x6ffffdf9,
DT_MOVEENT = 0x6ffffdfa,
DT_MOVESZ = 0x6ffffdfb,
DT_FEATURE_1 = 0x6ffffdfc,
DT_POSFLAG_1 = 0x6ffffdfd,
DT_SYMINSZ = 0x6ffffdfe,
DT_SYMINENT = 0x6ffffdff,
DT_ADDRRNGLO = 0x6ffffe00,
DT_GNU_HASH = 0x6ffffef5,
DT_CONFIG = 0x6ffffefa,
DT_DEPAUDIT = 0x6ffffefb,
DT_AUDIT = 0x6ffffefc,
DT_PLTPAD = 0x6ffffefd,
DT_MOVETAB = 0x6ffffefe,
DT_SYMINFO = 0x6ffffeff,
DT_RELACOUNT = 0x6ffffff9,
DT_RELCOUNT = 0x6ffffffa,
DT_FLAGS_1 = 0x6ffffffb,
DT_VERDEF = 0x6ffffffc,
DT_VERDEFNUM = 0x6ffffffd,
DT_VERNEED = 0x6ffffffe,
DT_VERNEEDNUM = 0x6fffffff,
DT_VERSYM = 0x6ffffff0,
DT_MIPS_RLD_VERSION = 0x70000001,
DT_MIPS_TIME_STAMP = 0x70000002,
DT_MIPS_ICHECKSUM = 0x70000003,
DT_MIPS_IVERSION = 0x70000004,
DT_MIPS_FLAGS = 0x70000005,
DT_MIPS_BASE_ADDRESS = 0x70000006,
DT_MIPS_CONFLICT = 0x70000008,
DT_MIPS_LIBLIST = 0x70000009,
DT_MIPS_LOCAL_GOTNO = 0x7000000a,
DT_MIPS_CONFLICTNO = 0x7000000b,
DT_MIPS_LIBLISTNO = 0x70000010,
DT_MIPS_SYMTABNO = 0x70000011,
DT_MIPS_UNREFEXTNO = 0x70000012,
DT_MIPS_GOTSYM = 0x70000013,
DT_MIPS_HIPAGENO = 0x70000014,
DT_MIPS_RLD_MAP = 0x70000016,
DT_MIPS_RLD_MAP_REL = 0x70000035
}

impl fmt::LowerHex for DynTag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{:?}", self))
}
}

datastructure! {
pub struct Elf32Sym {
st_name: u32,
st_value: u32,
st_size: u32,
st_info: u8,
st_other: u8,
st_shndx: u16,
}
}

datastructure! {
pub struct Elf64Sym {
st_name: u32,
st_info: u8,
st_other: u8,
st_shndx: u16,
st_value: u64,
st_size: u64,
}
}

datastructure! {
pub struct Elf64Dyn {
d_tag: DynTag,
d_val: u64,
}
}

datastructure! {
pub struct Elf32Dyn {
d_tag: u32,
d_val: u32,
}
}
26 changes: 19 additions & 7 deletions binformat/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,21 @@ fn parse_section_generics<'data, Obj: ObjectSection<'data>>(
(name.to_string(), bytes, start, end)
}

pub struct Datastructure {
pub ident: &'static str,
pub fields: Vec<(usize, &'static str, &'static str, String)>,
}

pub trait ToData {
fn to_fields(&self, addr: usize) -> Datastructure;
}

// FIXME: This assumes little endianness.
#[macro_export]
macro_rules! datastructure {
(
pub struct $name:ident {
$(
$field:ident: $ftype:ty,
)*
$($field:ident: $ftype:ty,)*
}
) => {
// Apply attributes to the struct
Expand All @@ -83,9 +91,8 @@ macro_rules! datastructure {
pub $($field: $ftype),*
}

impl $name {
pub fn to_fields(&self, mut addr: usize)
-> Vec<(usize, &'static str, &'static str, String)> {
impl $crate::ToData for $name {
fn to_fields(&self, mut addr: usize) -> $crate::Datastructure {
let mut fields = Vec::new();
$(
fields.push((
Expand All @@ -97,8 +104,13 @@ macro_rules! datastructure {
#[allow(unused_assignments)]
{ addr += ::std::mem::size_of::<$ftype>(); }
)*
fields
$crate::Datastructure {
ident: stringify!($name),
fields,
}
}
}

unsafe impl object::Pod for $name {}
};
}
2 changes: 0 additions & 2 deletions binformat/src/pe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ datastructure! {
}
}

unsafe impl object::Pod for ExceptionDirectoryEntry {}

pub struct PeDebugInfo<'data, Pe: ImageNtHeaders> {
/// Parsed PE32/64 header.
obj: &'data PeFile<'data, Pe>,
Expand Down
82 changes: 70 additions & 12 deletions processor/src/blocks.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::Processor;
use binformat::elf::{Elf32Dyn, Elf32Sym, Elf64Dyn, Elf64Sym};
use binformat::pe::ExceptionDirectoryEntry;
use binformat::ToData;
use commands::CONFIG;
use debugvault::Symbol;
use object::Endian;
use processor_shared::{encode_hex_bytes_truncated, Section, SectionKind};
use std::{mem::size_of, sync::Arc};
use std::mem::size_of;
use std::sync::Arc;
use tokenizing::{colors, Token, TokenStream};

const BYTES_BLOCK_SIZE: usize = 256;
Expand Down Expand Up @@ -41,7 +44,8 @@ pub enum BlockContent {
},
DataStructure {
ident: &'static str,
fields: Vec<(usize, &'static str, &'static str, String)>, // (addr, field, type, value)
/// (addr, field, type, value).
fields: Vec<(usize, &'static str, &'static str, String)>,
},
Bytes {
bytes: Vec<u8>,
Expand Down Expand Up @@ -82,7 +86,11 @@ impl Block {
stream.push("section started", colors::WHITE);
stream.push_owned(format!(" {} ", section.name), colors::BLUE);
stream.push("{", colors::GRAY60);
stream.push_owned(format!("{:?}", section.kind), colors::MAGENTA);
if section.ident == "UNKNOWN" {
stream.push_owned(format!("{:?}", section.kind), colors::MAGENTA);
} else {
stream.push(section.ident, colors::MAGENTA);
}
stream.push("} ", colors::GRAY60);
stream.push_owned(format!("{:x}", section.start), colors::GREEN);
stream.push("-", colors::GRAY60);
Expand Down Expand Up @@ -251,15 +259,19 @@ impl Processor {
SectionKind::Got64 => self.parse_got(addr, 4, section, &mut blocks),
SectionKind::CString => self.parse_cstring(addr, section, &mut blocks),
SectionKind::ExceptionDirEntry => {
if let Ok(entry) = section.read_at::<ExceptionDirectoryEntry>(addr) {
blocks.push(Block {
addr,
content: BlockContent::DataStructure {
ident: "ExceptionDirectoryEntry",
fields: entry.to_fields(addr),
},
})
}
self.parse_datastructure::<ExceptionDirectoryEntry>(addr, section, &mut blocks);
}
SectionKind::Elf32Sym => {
self.parse_datastructure::<Elf32Sym>(addr, section, &mut blocks);
}
SectionKind::Elf64Sym => {
self.parse_datastructure::<Elf64Sym>(addr, section, &mut blocks);
}
SectionKind::Elf32Dyn => {
self.parse_datastructure::<Elf32Dyn>(addr, section, &mut blocks);
}
SectionKind::Elf64Dyn => {
self.parse_datastructure::<Elf64Dyn>(addr, section, &mut blocks);
}
// For any other section kinds just assume they're made of bytes.
// As a note, we calculate the byte boundaries in blocks of [`BYTES_BLOCK_SIZE`],
Expand All @@ -276,6 +288,24 @@ impl Processor {
blocks
}

fn parse_datastructure<T: ToData + object::Pod>(
&self,
addr: usize,
section: &Section,
blocks: &mut Vec<Block>,
) {
if let Ok(datastructure) = section.read_at::<T>(addr) {
let datastructure = datastructure.to_fields(addr);
blocks.push(Block {
addr,
content: BlockContent::DataStructure {
ident: datastructure.ident,
fields: datastructure.fields,
},
})
}
}

fn parse_got(&self, addr: usize, size: usize, section: &Section, blocks: &mut Vec<Block>) {
let symbol = self.get_symbol_by_addr(addr, section).unwrap_or_default();
blocks.push(Block {
Expand Down Expand Up @@ -449,6 +479,34 @@ impl Processor {
addr += size_of::<ExceptionDirectoryEntry>();
}
}
SectionKind::Elf32Sym => {
let mut addr = section.start;
while addr < section.end {
boundaries.push(addr);
addr += size_of::<Elf32Sym>();
}
}
SectionKind::Elf64Sym => {
let mut addr = section.start;
while addr < section.end {
boundaries.push(addr);
addr += size_of::<Elf64Sym>();
}
}
SectionKind::Elf32Dyn => {
let mut addr = section.start;
while addr < section.end {
boundaries.push(addr);
addr += size_of::<Elf32Dyn>();
}
}
SectionKind::Elf64Dyn => {
let mut addr = section.start;
while addr < section.end {
boundaries.push(addr);
addr += size_of::<Elf64Dyn>();
}
}
// For any other section kinds just assume they evenly
// split in blocks of [`BYTES_BLOCK_SIZE`].
_ => {
Expand Down
8 changes: 8 additions & 0 deletions processor_shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ pub enum SectionKind {
CString,
/// ExceptionDirectoryEntry's (PE only).
ExceptionDirEntry,
/// Elf32Sym.
Elf32Sym,
/// Elf64Sym.
Elf64Sym,
/// Elf32Dyn.
Elf32Dyn,
/// Elf64Dyn.
Elf64Dyn,
/// DWARF debug info.
Debug,
/// Zero sized special sections.
Expand Down

0 comments on commit 4909441

Please sign in to comment.