feat: add cmd_elf

This commit is contained in:
2020-10-02 23:44:48 +08:00
parent a1f3c7921d
commit 8b03df3596
4 changed files with 104 additions and 4 deletions

2
.gitignore vendored
View File

@@ -2,7 +2,7 @@
# Generated by Cargo # Generated by Cargo
# will have compiled files and executables # will have compiled files and executables
/target/ /target/
sample_elf
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk

View File

@@ -2,3 +2,11 @@
Rust Cli - Rust command line util Rust Cli - Rust command line util
ELF
* https://fasterthanli.me/series/making-our-own-executable-packer/part-1
ELF format:
![](https://playsecurity.org/getdoc/3969_4D1E689A0A238F3244FA46D98AF1C404/elf64-file-header.a08515d63bdb6e35.safe.svg)

89
src/cmd_elf.rs Normal file
View File

@@ -0,0 +1,89 @@
use std::io::Read;
use std::fs::File;
use clap::{ ArgMatches, SubCommand, App, Arg };
use crate::cmd::{ Command, CommandError };
pub struct CommandElf;
// https://fasterthanli.me/series/making-our-own-executable-packer/part-1
impl Command for CommandElf {
fn name(&self) -> &str { "elf" }
fn subcommand<'a>(&self) -> App<'a, 'a> {
SubCommand::with_name(self.name()).about("ELF subcommand")
.arg(Arg::with_name("FILE").required(true).index(1).help("ELF file"))
}
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
let file_name = sub_arg_matches.value_of("FILE").unwrap();
let mut file = File::open(file_name)?;
let mut buf = vec![];
let len = file.read_to_end(&mut buf)?;
information!("File: {}, length: {}", file_name, len);
let elf_magic_number = buf.drain(0..4).collect::<Vec<_>>();
if vec![0x7f, 0x45/*'E'*/, 0x4c/*'L'*/, 0x46/*'F'*/] != elf_magic_number {
failure!("File not ELF file: {}", file_name);
return Ok(());
}
let class = buf.remove(0);
if class == 0x01 || class == 0x02 {
information!("File class is: {}", iff!(class == 0x01, "x86", "x64"));
} else {
failure!("File is not x86 or x64: {}", file_name);
return Ok(());
}
let endian = buf.remove(0);
if endian == 0x01 || endian == 0x02 {
information!("File endian is: {}", iff!(class == 0x01, "LittleEndian", "BigEndian"));
} else {
failure!("File is not Little or Big Endian: {}", file_name);
return Ok(());
}
let version = buf.remove(0);
information!("File version: {}", version);
let abi = buf.remove(0);
information!("File ABI: {}", abi);
let padding = buf.drain(0..8).collect::<Vec<_>>();
information!("File padding: {:?}", padding);
let ty = u16::from_le_bytes([buf.remove(0), buf.remove(0)]);
information!("File type: {}", match ty {
0x0 => "NONE".into(),
0x1 => "REL".into(),
0x2 => "EXEC".into(),
0x3 => "DYN".into(),
0x4 => "CORE".into(),
_ => format!("unknown: {}", ty),
});
let machine = u16::from_le_bytes([buf.remove(0), buf.remove(0)]);
information!("File machine: {}", match machine {
0x03 => "x86".into(),
0x3e => "x86-64".into(),
_ => format!("unknown: {}", machine),
});
let encore_version = u32::from_le_bytes([buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0)]);
information!("File encore version: {}", encore_version);
let entry_point = u64::from_le_bytes([buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0),
buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0)]);
information!("File entry point: {}", entry_point);
let table_offset_first_program_header_entry = u64::from_le_bytes([buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0),
buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0)]);
information!("File table offset fist program header entry: {}", table_offset_first_program_header_entry);
let table_offset_first_section_header_entry = u64::from_le_bytes([buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0),
buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0)]);
information!("File table offset fist section header entry: {}", table_offset_first_section_header_entry);
let flags = u32::from_le_bytes([buf.remove(0), buf.remove(0), buf.remove(0), buf.remove(0)]);
information!("File flags: {}", flags);
let header_size = u16::from_le_bytes([buf.remove(0), buf.remove(0)]);
information!("File header size: {}", header_size);
let entry_size = u16::from_le_bytes([buf.remove(0), buf.remove(0)]);
information!("File entry size: {}", entry_size);
let number_of_entries = u16::from_le_bytes([buf.remove(0), buf.remove(0)]);
information!("File number of entries: {}", number_of_entries);
Ok(())
}
}

View File

@@ -1,16 +1,19 @@
#[macro_use] extern crate rust_util;
use clap::App; use clap::App;
mod cmd; mod cmd;
mod cmd_elf;
mod cmd_show; mod cmd_show;
mod cmd_default; mod cmd_default;
use cmd::{ Command, CommandError, }; use cmd::{ Command, CommandError };
use cmd_show::CommandShow;
use cmd_default::CommandDefault; use cmd_default::CommandDefault;
fn main() -> CommandError { fn main() -> CommandError {
let commands: Vec<Box<dyn Command>> = vec![ let commands: Vec<Box<dyn Command>> = vec![
Box::new(CommandShow), Box::new(cmd_elf::CommandElf),
Box::new(cmd_show::CommandShow),
]; ];
let mut app = App::new(env!("CARGO_PKG_NAME")) let mut app = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION")) .version(env!("CARGO_PKG_VERSION"))