├── .gitignore ├── gen_syscalls.sh ├── gen_syscalls.py ├── src ├── bytebuf.rs ├── inferior │ └── mod.rs ├── addressmap.rs ├── process.rs ├── ptrace_util │ └── mod.rs ├── main.rs └── syscalls64.rs ├── .travis.yml ├── Cargo.toml ├── README.md └── gen.py /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /gen_syscalls.sh: -------------------------------------------------------------------------------- 1 | curl -q http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html|grep -o -E "\d+sys_[a-z]+"|sed -E "s/([[:digit:]]+)<\/td>(.+)<\/td>/\1 => { \"\2\" }/"|pbcopy 2 | -------------------------------------------------------------------------------- /gen_syscalls.py: -------------------------------------------------------------------------------- 1 | import json 2 | from pprint import pprint 3 | 4 | with open('TABELLA_64.json') as data_file: 5 | data = json.load(data_file) 6 | 7 | for k, s in data.items(): 8 | print("Syscall{{number: {0}, name: \"{1}\", file: \"{2}\", sysname: \"{3}\"}},".format(s[0], s[1], s[2], s[3])) 9 | -------------------------------------------------------------------------------- /src/bytebuf.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | pub struct ByteBuf<'a>(pub &'a [u8]); 4 | 5 | impl<'a> fmt::LowerHex for ByteBuf<'a> { 6 | fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result { 7 | for byte in self.0 { 8 | try!(fmtr.write_fmt(format_args!("{:02x}", byte))); 9 | } 10 | 11 | Ok(()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: xenial 3 | 4 | before_install: 5 | - sudo apt-get -qq update 6 | - sudo apt-get install -y python python-pip 7 | - pip install capstone 8 | - pip install keystone-engine 9 | 10 | language: rust 11 | 12 | rust: 13 | - stable 14 | - beta 15 | - nightly 16 | 17 | matrix: 18 | allow_failures: 19 | - rust: nightly 20 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tracer" 3 | version = "0.1.0" 4 | authors = ["Remco "] 5 | 6 | [dependencies] 7 | elftools = "0.1.0" 8 | nix = "0.6.0" 9 | libc = "0.2.14" 10 | capstone = "0.0.4" 11 | byteorder = "0.5" 12 | docopt = "0.6.81" 13 | rustc-serialize = "*" 14 | ansi_term = "0.7" 15 | dwarf = "0.0.3" 16 | memmap = "*" 17 | scan_fmt = "*" 18 | -------------------------------------------------------------------------------- /src/inferior/mod.rs: -------------------------------------------------------------------------------- 1 | // (partly) based on http://system.joekain.com/2015/09/07/refactoring-ptrace-code.html 2 | 3 | use libc::pid_t; 4 | use libc::c_void; 5 | 6 | use std::fmt; 7 | use std::ops::{Add, Sub}; 8 | 9 | pub type TrapInferior = pid_t; 10 | 11 | #[derive(Copy, Clone)] 12 | pub enum InferiorState { 13 | Running, 14 | Stopped, 15 | SingleStepping, 16 | } 17 | 18 | #[derive(Copy, Clone)] 19 | pub struct Inferior { 20 | pub pid: pid_t, 21 | pub state: InferiorState, 22 | } 23 | 24 | #[derive(Copy, Clone)] 25 | pub struct InferiorPointer(pub u64); 26 | 27 | impl InferiorPointer { 28 | pub fn as_voidptr(&self) -> *mut c_void { 29 | let &InferiorPointer(u) = self; 30 | u as *mut c_void 31 | } 32 | } 33 | 34 | impl fmt::LowerHex for InferiorPointer { 35 | fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result { 36 | try!(fmtr.write_fmt(format_args!("{:02x}", self.as_voidptr() as u64))); 37 | 38 | Ok(()) 39 | } 40 | } 41 | 42 | impl Add for InferiorPointer { 43 | type Output = InferiorPointer; 44 | fn add(self, rhs: i64) -> InferiorPointer { 45 | let InferiorPointer(u) = self; 46 | if rhs >= 0 { 47 | InferiorPointer(u + rhs as u64) 48 | } else { 49 | InferiorPointer(u - rhs as u64) 50 | } 51 | } 52 | } 53 | 54 | impl Sub for InferiorPointer { 55 | type Output = InferiorPointer; 56 | fn sub(self, rhs: i64) -> InferiorPointer { 57 | let InferiorPointer(u) = self; 58 | if rhs >= 0 { 59 | InferiorPointer(u - rhs as u64) 60 | } else { 61 | InferiorPointer(u + rhs as u64) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/addressmap.rs: -------------------------------------------------------------------------------- 1 | use std::fs::{File}; 2 | use std::io::{BufReader}; 3 | use std::io::prelude::*; 4 | 5 | use libc::pid_t; 6 | 7 | #[derive(Clone, Debug)] 8 | pub struct AddressMap { 9 | pub lower_addr: u64, 10 | pub upper_addr: u64, 11 | pub path: String, 12 | } 13 | 14 | 15 | #[derive(Clone, Debug)] 16 | pub struct Maps { 17 | map: Vec, 18 | } 19 | 20 | impl Maps { 21 | pub fn resolve(&self, address: u64) -> Option<&AddressMap> { 22 | self.map.iter().find(|m| m.lower_addr < address && address < m.upper_addr) 23 | } 24 | 25 | pub fn parse(&self) {} 26 | 27 | pub fn load(pid: pid_t) -> Result { 28 | let file = match File::open(format!("/proc/{:}/maps", pid)) { 29 | Err(why) => panic!("couldn't open proc map: {}", why), 30 | Ok(file) => file, 31 | }; 32 | 33 | let mut addressmap = vec![]; 34 | 35 | let f = BufReader::new(file); 36 | for line in f.lines() { 37 | let l = line.unwrap(); 38 | 39 | let (lower, upper, lib) = scan_fmt!(l.as_str(), 40 | "{x}-{x} {*} {*} {*} {*} {}", 41 | String, 42 | String, 43 | String); 44 | 45 | let lower_addr = u64::from_str_radix(&lower.unwrap().as_str(), 16).map_err(|_| ()); 46 | let upper_addr = u64::from_str_radix(&upper.unwrap().as_str(), 16).map_err(|_| ()); 47 | 48 | addressmap.push(AddressMap { 49 | lower_addr: lower_addr.unwrap(), 50 | upper_addr: upper_addr.unwrap(), 51 | path: lib.unwrap_or(String::from("")), 52 | }); 53 | } 54 | 55 | Ok(Maps { map: addressmap }) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/process.rs: -------------------------------------------------------------------------------- 1 | use ptrace_util::Process; 2 | use elftools::*; 3 | use std::collections::HashMap; 4 | use inferior::InferiorPointer; 5 | use std::mem; 6 | 7 | impl Process { 8 | pub fn is_elf(&mut self) -> bool { 9 | let base_addr = InferiorPointer(0x400000); 10 | 11 | let mut elf_header: [u8; 4] = [0, 0, 0, 0]; 12 | self.peek_text_bytes(base_addr, &mut elf_header[0..]); 13 | 14 | elf_header == [b'\x7f', b'E', b'L', b'F'] 15 | } 16 | 17 | pub fn ehdr(&mut self) -> Result { 18 | let base_addr = InferiorPointer(0x400000); 19 | 20 | let ehdr: Elf64_Ehdr = self.read_struct::(base_addr).expect("Ehdr"); 21 | Ok(ehdr) 22 | } 23 | 24 | pub fn program_headers(&mut self) -> Result< HashMap, ()> { 25 | let ehdr = self.ehdr().unwrap(); 26 | let base_addr = InferiorPointer(0x400000); 27 | 28 | let mut program_headers: HashMap = HashMap::new(); 29 | 30 | for n in 0..ehdr.e_phnum { 31 | let phdr = self.read_struct::(base_addr + ehdr.e_phoff as i64 + 32 | (ehdr.e_phentsize as i64 * n as i64)) 33 | .expect("Could not read elf phdr"); 34 | 35 | program_headers.insert(phdr.p_type, phdr.clone()); 36 | } 37 | 38 | Ok(program_headers) 39 | } 40 | 41 | pub fn sections(&mut self, tag: i32 ) -> Result< Vec, () > { 42 | let mut program_headers: HashMap = self.program_headers().unwrap(); 43 | 44 | let dynamic_section = program_headers.get(&(PT_DYNAMIC as Elf64_Word)) 45 | .expect("pt_dynamic not found"); 46 | 47 | let mut s = vec![]; 48 | 49 | let mut dyn_addr = InferiorPointer(dynamic_section.p_vaddr as u64); 50 | 51 | loop { 52 | let dyn = self.read_struct::(dyn_addr).expect("dyn"); 53 | 54 | if dyn.d_tag == 0 { 55 | break; 56 | } else if dyn.d_tag == tag as i64 { 57 | s.push(InferiorPointer(dyn.d_ptr as u64)) 58 | } 59 | 60 | dyn_addr = dyn_addr + mem::size_of::() as i64; 61 | } 62 | 63 | Ok(s) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tracer [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dutchcoders/tracer?utm_source=badge&utm_medium=badge&utm_campaign=&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/dutchcoders/tracer.svg?branch=master)](https://travis-ci.org/dutchcoders/tracer) 2 | 3 | The system tracer will show all syscalls, methods and optionally assembly that is being executed. This allows tracing of complete program flows. Tracer can be run for new processes, but also be attached to existing processes. 4 | 5 | # Usage 6 | 7 | ## Start a new process 8 | 9 | ```sh 10 | $ cargo run -- -a -c "/bin/ls" 11 | ... 12 | /bin/ls 4021f0 ff254a9e2100 jmp localtime 13 | /bin/ls 4021f0 6805000000 push localtime 14 | /bin/ls 4021f0 e990ffffff jmp localtime 15 | /bin/ls 4021f0 ff254a9e2100 jmp localtime 16 | /bin/ls 4021f0 6805000000 push localtime 17 | /bin/ls 4021f0 e990ffffff jmp localtime 18 | /bin/ls 402270 ff250a9e2100 jmp __fpending 19 | /bin/ls 402270 680d000000 push __fpending 20 | /bin/ls 402270 e910ffffff jmp __fpending 21 | /bin/ls 402310 ff25ba9d2100 jmp fclose 22 | /bin/ls 402310 6817000000 push fclose 23 | /bin/ls 402310 e970feffff jmp fclose 24 | unknown 7fc465c63b0e 0f05 syscall close( 3) ( fd: 01 ) 25 | ... 26 | ``` 27 | 28 | ## Connect to an existing process 29 | 30 | ```sh 31 | $ cargo run -- -a --pid 0 32 | ``` 33 | 34 | ## References 35 | 36 | * http://system.joekain.com/2015/07/15/rust-load-and-ptrace.html 37 | * http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 38 | * https://github.com/hoelzro/rust-execution-tracer/blob/master/posix.rs 39 | * https://github.com/eliben/pyelftools/blob/5d3b1545df30d4bc3a6cfa8741b1f08cb6bf204b/elftools/elf/elffile.py 40 | * http://man7.org/linux/man-pages/man5/proc.5.html 41 | * http://www.tldp.org/LDP/LG/issue85/sandeep.html 42 | * https://github.com/larsbergstrom/rust-egl/blob/master/test/egl-android-glue/jni/android-dl.cpp 43 | * https://opensource.apple.com/source/gdb/gdb-908/src/binutils/readelf.c 44 | * http://www.sco.com/developers/gabi/1998-04-29/ch4.eheader.html 45 | * https://grugq.github.io/docs/subversiveld.pdf 46 | * http://lxr.free-electrons.com/source/include/uapi/linux/elf.h#L277 47 | * http://www.tldp.org/LDP/LG/issue85/sandeep.html 48 | 49 | ## TODO 50 | 51 | * libbacktrace 52 | * add dwarf support 53 | * parse arguments, file get x64 54 | * diff changed register 55 | * check repetitions 56 | * disable colorcoding when piping 57 | * searching 58 | * filtering 59 | * all params 60 | * ptrace_syscall flag? 61 | * PT_DENY_ATTACH 62 | * dl_addr 63 | * /proc/%d/mem 64 | * /proc/%d/maps 65 | * https://github.com/djpnewton/libcorkscrew_ndk/blob/master/ptrace.c 66 | * load_symbol_table 67 | * http://osxr.org:8080/android/source/system/core/libcorkscrew/symbol_table.c 68 | * load_ptrace_context 69 | -------------------------------------------------------------------------------- /gen.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | import re 4 | from pprint import pprint 5 | 6 | def lines(): 7 | h = requests.get("https://raw.githubusercontent.com/lattera/glibc/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/elf/elf.h").text 8 | for line in h.splitlines(): 9 | yield line 10 | 11 | 12 | def parseTypeDef(s): 13 | print s 14 | 15 | print ("// AUTO-GENERATED FILE, DO NOT EDIT [elftools_const.rs]") 16 | print ("\n") 17 | print ("extern crate libc;") 18 | # print ("use libc::void_t;") 19 | print ("\n") 20 | 21 | test = ["^typedef", parseTypeDef] 22 | type_mapping = { 23 | "uint16_t": "u16", 24 | "uint32_t": "u32", 25 | "uint64_t": "u64", 26 | "int16_t": "i16", 27 | "int32_t": "i32", 28 | "int64_t": "i64", 29 | } 30 | 31 | h = requests.get("https://raw.githubusercontent.com/lattera/glibc/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/elf/elf.h").text 32 | i = 0 33 | while i < len(h): 34 | end = h.find("\n", i) + 1 35 | 36 | p = re.compile("^typedef\s+struct\s+{(((?:\s+.+?)\n)+)}\s+(\w+)\;", re.MULTILINE).match(h, i, end) 37 | if p: 38 | #print ("struct {0} {1}".format(p.start(), p.end())) 39 | #pprint(p) 40 | i = p.end() 41 | continue 42 | 43 | p = re.compile("^typedef\s+([A-Za-z0-9_]+)\s+([A-Za-z0-9_]+);$", re.MULTILINE).match(h, i, end) 44 | if p: 45 | #print ("typedef2 {0} {1} {2}".format(h[p.start():p.end()], p.group(1), p.group(2))) 46 | t = p.group(1) 47 | try: 48 | t = type_mapping[p.group(1)] 49 | except: 50 | pass 51 | print "#[allow(non_camel_case_types)]\npub type {1} = {0};".format(t, p.group(2)) 52 | # pprint(p) 53 | i = p.end() 54 | continue 55 | 56 | p = re.compile("^\/\/", re.MULTILINE).match(h, i, end) 57 | if p: 58 | # search for end */ 59 | print ("{0}".format(h[p.start():p.end()])) 60 | i = p.end() 61 | continue 62 | 63 | p = re.compile("^\/\*", re.MULTILINE).match(h, i, end) 64 | if p: 65 | # search for end */ 66 | n = re.compile("\*\/").search(h, p.end()) 67 | print ("{0}".format(h[p.start():n.end()])) 68 | i = n.end() 69 | continue 70 | 71 | p = re.compile("^#define\s+([A-Za-z0-9_]+)\s+([A-Za-z0-9_]+)\s*(\/\*.+?\*\/)?\s*$", re.MULTILINE).match(h, i, end) 72 | #define STT_HP_OPAQUE (STT_LOOS + 0x1) 73 | if p: 74 | """ 75 | bitflags! { 76 | pub flags Mode : u32 { 77 | const MODE_LITTLE_ENDIAN = 0, 78 | const MODE_BIG_ENDIAN = 1073741824, 79 | const MODE_ARM = 1, 80 | const MODE_THUMB = 16, 81 | const MODE_V8 = 64, 82 | const MODE_MICRO = 16, 83 | const MODE_MIPS3 = 32, 84 | const MODE_MIPS32R6 = 64, 85 | const MODE_MIPS32 = 4, 86 | const MODE_MIPS64 = 8, 87 | const MODE_16 = 2, 88 | const MODE_32 = 4, 89 | const MODE_64 = 8, 90 | const MODE_PPC32 = 4, 91 | const MODE_PPC64 = 8, 92 | const MODE_QPX = 16, 93 | const MODE_SPARC32 = 4, 94 | const MODE_SPARC64 = 8, 95 | const MODE_V9 = 16, 96 | } 97 | } 98 | """ 99 | 100 | print ("pub const {0}: u32 = {1};".format(p.group(1), p.group(2))) 101 | #pprint(p) 102 | i = p.end() 103 | continue 104 | 105 | # find next line 106 | i = end 107 | print ("\n") 108 | continue 109 | 110 | import sys 111 | sys.exit(0) 112 | 113 | #print (h) 114 | 115 | #m = re.search('typedef\s+struct\s+{(.+?)}\s+\w+\;', h) 116 | m = re.compile('typedef\s+struct\s+{(((?:\s+.+?)\n)+)}\s+(\w+)\;', re.MULTILINE) 117 | result = m.finditer(h) 118 | for n in result: 119 | #print n.group(0) 120 | print "#[derive(Debug)]\npub struct {0} {{".format(n.group(2)) 121 | for l in n.group(1).split('\n'): 122 | print l 123 | #pprint (n.group(1)) 124 | #print n.group(3) 125 | 126 | print "}" 127 | 128 | 129 | m = re.compile('#define\s+(\w+)\s+(.+?)\s+(\/\*.+?\*\/)?\n', re.MULTILINE) 130 | result = m.finditer(h) 131 | for n in result: 132 | print "pub const {0} : i32 = {1}; {2}".format(n.group(1), n.group(2), n.group(3) or "") 133 | 134 | # 135 | #typedef struct 136 | #{ 137 | # unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ 138 | # Elf64_Half e_type; /* Object file type */ 139 | # Elf64_Half e_machine; /* Architecture */ 140 | # Elf64_Word e_version; /* Object file version */ 141 | # Elf64_Addr e_entry; /* Entry point virtual address */ 142 | # Elf64_Off e_phoff; /* Program header table file offset */ 143 | # Elf64_Off e_shoff; /* Section header table file offset */ 144 | # Elf64_Word e_flags; /* Processor-specific flags */ 145 | # Elf64_Half e_ehsize; /* ELF header size in bytes */ 146 | # Elf64_Half e_phentsize; /* Program header table entry size */ 147 | # Elf64_Half e_phnum; /* Program header table entry count */ 148 | # Elf64_Half e_shentsize; /* Section header table entry size */ 149 | # Elf64_Half e_shnum; /* Section header table entry count */ 150 | # Elf64_Half e_shstrndx; /* Section header string table index */ 151 | #} Elf64_Ehdr; 152 | # 153 | # 154 | -------------------------------------------------------------------------------- /src/ptrace_util/mod.rs: -------------------------------------------------------------------------------- 1 | // (partly) based on http://system.joekain.com/2015/09/07/refactoring-ptrace-code.html 2 | 3 | extern crate std; 4 | 5 | use libc::pid_t; 6 | use nix::sys::ptrace::*; 7 | use nix::sys::ptrace::ptrace::*; 8 | use std::ptr; 9 | use libc::c_void; 10 | use std::str; 11 | 12 | use inferior::InferiorPointer; 13 | use std::slice; 14 | 15 | use std::mem; 16 | 17 | use libc::wait; 18 | use libc::c_int; 19 | use libc::WIFSTOPPED; 20 | use std::fs::{self, File}; 21 | use std::io::{self, BufRead, BufReader, Read, Seek, SeekFrom}; 22 | use std::ffi::{CString, CStr}; 23 | use std::ffi::IntoStringError; 24 | 25 | pub mod user { 26 | pub mod regs { 27 | pub const R15: i64 = 0 * 8; 28 | pub const R14: i64 = 1 * 8; 29 | pub const R13: i64 = 2 * 8; 30 | pub const R12: i64 = 3 * 8; 31 | pub const RBP: i64 = 4 * 8; 32 | pub const RBX: i64 = 5 * 8; 33 | pub const R11: i64 = 6 * 8; 34 | pub const R10: i64 = 7 * 8; 35 | pub const R9: i64 = 8 * 8; 36 | pub const R8: i64 = 9 * 8; 37 | pub const RAX: i64 = 10 * 8; 38 | pub const RCX: i64 = 11 * 8; 39 | pub const RDX: i64 = 12 * 8; 40 | pub const RSI: i64 = 13 * 8; 41 | pub const RDI: i64 = 14 * 8; 42 | pub const ORIG_RAX: i64 = 15 * 8; 43 | pub const RIP: u64 = 16 * 8; 44 | pub const CS: i64 = 17 * 8; 45 | pub const EFLAGS: i64 = 18 * 8; 46 | pub const RSP: i64 = 19 * 8; 47 | pub const SS: i64 = 20 * 8; 48 | pub const FS_BASE: i64 = 21 * 8; 49 | pub const GS_BASE: i64 = 22 * 8; 50 | pub const DS: i64 = 23 * 8; 51 | pub const ES: i64 = 24 * 8; 52 | pub const FS: i64 = 25 * 8; 53 | pub const GS: i64 = 26 * 8; 54 | } 55 | } 56 | 57 | // get_regs 58 | 59 | pub struct Process { 60 | pub pid: pid_t, 61 | pub memfile: BufReader, 62 | } 63 | 64 | impl Process { 65 | pub fn new(pid: pid_t) -> Self { 66 | let mut memfile = fs::OpenOptions::new() 67 | .read(true) 68 | .write(false) 69 | .create(false) 70 | .open(format!("/proc/{:}/mem", pid)) 71 | .unwrap(); 72 | 73 | let mut reader = BufReader::new(memfile); 74 | 75 | Process { 76 | pid: pid, 77 | memfile: reader, 78 | } 79 | } 80 | 81 | pub fn rax(&self) -> Result { 82 | self.peek_user(user::regs::RAX as *mut c_void) 83 | } 84 | 85 | pub fn rbx(&self) -> Result { 86 | self.peek_user(user::regs::RBX as *mut c_void) 87 | } 88 | 89 | pub fn rdx(&self) -> Result { 90 | self.peek_user(user::regs::RDX as *mut c_void) 91 | } 92 | 93 | pub fn rdi(&self) -> Result { 94 | self.peek_user(user::regs::RDI as *mut c_void) 95 | } 96 | 97 | pub fn rsi(&self) -> Result { 98 | self.peek_user(user::regs::RSI as *mut c_void) 99 | } 100 | 101 | pub fn rip(&self) -> Result { 102 | self.peek_user(user::regs::RIP as *mut c_void) 103 | } 104 | 105 | pub fn peek_user(&self, addr: *mut c_void) -> Result { 106 | match ptrace(PTRACE_PEEKUSER, self.pid, addr, ptr::null_mut()) { 107 | Ok(raw) => Result::Ok(InferiorPointer(raw as u64)), 108 | Err(e) => Result::Err(String::from("")), 109 | } 110 | } 111 | 112 | pub fn peek_text(&self, address: InferiorPointer) -> i64 { 113 | ptrace(PTRACE_PEEKTEXT, 114 | self.pid, 115 | address.as_voidptr(), 116 | ptr::null_mut()) 117 | .ok() 118 | .expect("Failed PTRACE_PEEKTEXT") 119 | } 120 | 121 | pub fn read_struct(&mut self, address: InferiorPointer) -> io::Result { 122 | self.memfile.seek(SeekFrom::Start(address.as_voidptr() as u64)).expect("seek"); 123 | 124 | let num_bytes = ::std::mem::size_of::(); 125 | unsafe { 126 | let mut s = ::std::mem::uninitialized(); 127 | let mut buffer = slice::from_raw_parts_mut(&mut s as *mut T as *mut u8, num_bytes); 128 | match self.memfile.read_exact(buffer) { 129 | Ok(()) => Ok(s), 130 | Err(e) => { 131 | ::std::mem::forget(s); 132 | Err(e) 133 | } 134 | } 135 | } 136 | } 137 | 138 | // pub fn struct_at(&mut self, address: InferiorPointer) -> Result { 139 | // let mut str2 : A = unsafe {std::mem::uninitialized()}; 140 | // unsafe { 141 | // let mut buf = Vec::with_capacity(std::mem::size_of::()); 142 | // self.memfile.read(&buf ); 143 | // 144 | // memfile.seek(p.as_voidptr() as usize, io::SeekFrom::Start); 145 | // 146 | // let x2 : A = mem::transmute(&mut str2); 147 | // self.memfile.seek(SeekFrom::Start(address.as_voidptr() as u64)).expect("seek"); 148 | // process.peek_text_bytes(strtab, std::mem::transmute::<&mut u32, &mut [u8; 4]>(&mut str2)); 149 | // let mut buf = std::mem::transmute::<&A, *mut u8>(&mut str2); 150 | // self.memfile.read(buf as &mut[u8]); 151 | // } 152 | // Ok(String::from("test")) 153 | // } 154 | // 155 | 156 | pub fn string_at(&mut self, address: InferiorPointer) -> Result { 157 | self.memfile.seek(SeekFrom::Start(address.as_voidptr() as u64)).expect("seek"); 158 | 159 | let mut buf = Vec::::new(); 160 | self.memfile.read_until(b'\0', &mut buf).expect("read_until failed"); 161 | 162 | // let c_str: &CStr = unsafe { CStr::from_ptr(buf.as_ref()) }; 163 | // let buf: &[u8] = c_str.to_bytes(); 164 | // let str_slice: &str = str::from_utf8(buf).unwrap(); 165 | // 166 | 167 | 168 | let s = CStr::from_bytes_with_nul(buf.as_ref()).unwrap(); 169 | Ok(s.to_str().unwrap().to_string()) 170 | 171 | // let str_slice: &str = str::from_utf8(buf.as_ref()).unwrap(); 172 | // Ok(str_slice.to_string()) 173 | // String::from_str(str_slice) 174 | // (unsafe { CString::from_vec_unchecked(buf).into_string() }) 175 | } 176 | 177 | pub fn peek_text_bytes(&mut self, address: InferiorPointer, bytes: &mut [u8]) { 178 | self.memfile.seek(SeekFrom::Start(address.as_voidptr() as u64)).expect("seek"); 179 | // memfile.seek(p.as_voidptr() as usize, io::SeekFrom::Start); 180 | self.memfile.read(&mut bytes[0..]); 181 | 182 | // let filename = ptrace(PTRACE_PEEKTEXT, self.pid, address.as_voidptr(), ptr::null_mut()) 183 | // .ok() 184 | // .expect("Failed PTRACE_PEEKTEXT"); 185 | // let mut raw_filename : Vec = Vec::new(); 186 | // let mut raw_filename : [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; 187 | // 188 | // let mut i = 0; 189 | // while i < 8 { // mem::size_of::() { 190 | // raw_filename.push(((filename >> (i*8)) & 0xFF) as u8); 191 | // raw_filename[i] = (((filename >> (i*8)) & 0xFF) as u8); 192 | // i+=1; 193 | // } 194 | // 195 | // bytes[0..8].clone_from_slice(&raw_filename); 196 | // raw_filename 197 | // 198 | } 199 | 200 | 201 | pub fn single_step(&self) -> Result<(), ()> { 202 | match ptrace(PTRACE_SINGLESTEP, 203 | self.pid, 204 | ptr::null_mut(), 205 | ptr::null_mut()) { 206 | Ok(_) => Ok(()), 207 | Err(e) => Err(()), 208 | } 209 | } 210 | 211 | // TODO: don't think this should be in process. It is more of parent. 212 | pub fn wait() -> c_int { 213 | let mut wait_status: c_int = 0; 214 | unsafe { 215 | wait(&mut wait_status); 216 | } 217 | wait_status 218 | } 219 | 220 | pub fn WIFSTOPPED(wait_status: c_int) -> bool { 221 | unsafe { WIFSTOPPED(wait_status) } 222 | } 223 | } 224 | 225 | pub fn trace_me() -> () { 226 | ptrace(PTRACE_TRACEME, 0, ptr::null_mut(), ptr::null_mut()) 227 | .ok() 228 | .expect("Failed PTRACE_TRACEME"); 229 | } 230 | 231 | pub fn syscall(pid: pid_t) -> () { 232 | let raw = ptrace(PTRACE_SYSCALL, pid, ptr::null_mut(), ptr::null_mut()) 233 | .ok() 234 | .expect("Failed PTRACE_SYSCALL"); 235 | } 236 | 237 | 238 | pub fn get_rax(pid: pid_t) -> InferiorPointer { 239 | let raw = ptrace(PTRACE_PEEKUSER, 240 | pid, 241 | user::regs::RAX as *mut c_void, 242 | ptr::null_mut()) 243 | .ok() 244 | .expect("Failed PTRACE_PEEKUSER"); 245 | InferiorPointer(raw as u64) 246 | } 247 | 248 | pub fn get_rdx(pid: pid_t) -> InferiorPointer { 249 | let raw = ptrace(PTRACE_PEEKUSER, 250 | pid, 251 | user::regs::RDX as *mut c_void, 252 | ptr::null_mut()) 253 | .ok() 254 | .expect("Failed PTRACE_PEEKUSER"); 255 | InferiorPointer(raw as u64) 256 | } 257 | 258 | 259 | pub fn get_rsi(pid: pid_t) -> InferiorPointer { 260 | let raw = ptrace(PTRACE_PEEKUSER, 261 | pid, 262 | user::regs::RSI as *mut c_void, 263 | ptr::null_mut()) 264 | .ok() 265 | .expect("Failed PTRACE_PEEKUSER"); 266 | InferiorPointer(raw as u64) 267 | } 268 | 269 | 270 | pub fn get_rdi(pid: pid_t) -> InferiorPointer { 271 | let raw = ptrace(PTRACE_PEEKUSER, 272 | pid, 273 | user::regs::RDI as *mut c_void, 274 | ptr::null_mut()) 275 | .ok() 276 | .expect("Failed PTRACE_PEEKUSER"); 277 | InferiorPointer(raw as u64) 278 | } 279 | 280 | pub fn get_instruction_pointer(pid: pid_t) -> InferiorPointer { 281 | let raw = ptrace(PTRACE_PEEKUSER, 282 | pid, 283 | user::regs::RIP as *mut c_void, 284 | ptr::null_mut()) 285 | .ok() 286 | .expect("Failed PTRACE_PEEKUSER"); 287 | InferiorPointer(raw as u64) 288 | } 289 | 290 | // pub fn set_instruction_pointer(pid: pid_t, ip: InferiorPointer) -> () { 291 | // ptrace(PTRACE_POKEUSER, pid, user::regs::RIP as * mut c_void, ip.as_voidptr()) 292 | // .ok() 293 | // .expect("Failed PTRACE_POKEUSER"); 294 | // } 295 | // 296 | // pub fn cont(pid: pid_t) -> () { 297 | // ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut()) 298 | // .ok() 299 | // .expect("Failed PTRACE_CONTINUE"); 300 | // } 301 | // 302 | 303 | pub fn peek_text(pid: pid_t, address: InferiorPointer) -> i64 { 304 | ptrace(PTRACE_PEEKTEXT, pid, address.as_voidptr(), ptr::null_mut()) 305 | .ok() 306 | .expect("Failed PTRACE_PEEKTEXT") 307 | } 308 | 309 | pub fn peek_text_bytes(pid: pid_t, address: InferiorPointer) -> [u8; 8] { 310 | let filename = ptrace(PTRACE_PEEKTEXT, pid, address.as_voidptr(), ptr::null_mut()) 311 | .ok() 312 | .expect("Failed PTRACE_PEEKTEXT"); 313 | // let mut raw_filename : Vec = Vec::new(); 314 | let mut raw_filename: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; 315 | 316 | let mut i = 0; 317 | while i < 8 { 318 | // mem::size_of::() { 319 | // raw_filename.push(((filename >> (i*8)) & 0xFF) as u8); 320 | raw_filename[i] = (((filename >> (i * 8)) & 0xFF) as u8); 321 | i += 1; 322 | } 323 | 324 | raw_filename 325 | } 326 | 327 | // pub fn peek_text_str(pid: pid_t, address: InferiorPointer) -> &str { 328 | // let filename = ptrace(PTRACE_PEEKTEXT, pid, address.as_voidptr(), ptr::null_mut()) 329 | // .ok() 330 | // .expect("Failed PTRACE_PEEKTEXT"); 331 | // let mut raw_filename : Vec = Vec::new(); 332 | // let mut raw_filename : [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; 333 | // 334 | // let mut i = 0; 335 | // while i < 8 { // mem::size_of::() { 336 | // raw_filename.push(((filename >> (i*8)) & 0xFF) as u8); 337 | // raw_filename[i] = (((filename >> (i*8)) & 0xFF) as u8); 338 | // i+=1; 339 | // } 340 | // 341 | // let s = match str::from_utf8(&raw_filename) { 342 | // Ok(v) => v, 343 | // Err(e) => panic!("Invalid UTF-8 sequence: {}", e), 344 | // }; 345 | // 346 | // s.clone() 347 | // } 348 | // 349 | 350 | pub fn poke_text(pid: pid_t, address: InferiorPointer, value: i64) -> () { 351 | ptrace(PTRACE_POKETEXT, 352 | pid, 353 | address.as_voidptr(), 354 | value as *mut c_void) 355 | .ok() 356 | .expect("Failed PTRACE_POKETEXT"); 357 | } 358 | 359 | pub fn single_step(pid: pid_t) -> () { 360 | ptrace(PTRACE_SINGLESTEP, pid, ptr::null_mut(), ptr::null_mut()) 361 | .ok() 362 | .expect("Failed PTRACE_SINGLESTEP"); 363 | } 364 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate nix; 2 | extern crate libc; 3 | extern crate capstone; 4 | extern crate byteorder; 5 | extern crate docopt; 6 | extern crate rustc_serialize; 7 | extern crate ansi_term; 8 | extern crate dwarf; 9 | extern crate memmap; 10 | extern crate elftools; 11 | 12 | use elftools::*; 13 | 14 | use memmap::{Mmap, Protection}; 15 | 16 | use ansi_term::Colour::*; 17 | 18 | use docopt::Docopt; 19 | 20 | use std::process::Command; 21 | use std::str; 22 | 23 | use nix::sys::signal::*; 24 | use nix::sys::ptrace::*; 25 | use nix::unistd::*; 26 | 27 | use std::fs::{self, File}; 28 | use std::io::{self, BufReader}; 29 | use std::io::prelude::*; 30 | 31 | use std::ffi::CStr; 32 | 33 | use libc::pid_t; 34 | use libc::wait; 35 | use libc::c_void; 36 | use libc::c_int; 37 | use libc::WIFSTOPPED; 38 | use libc::dladdr; 39 | use libc::Dl_info; 40 | 41 | use std::mem; 42 | use std::fmt; 43 | use std::ffi::CString; 44 | 45 | use std::collections::HashMap; 46 | 47 | use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian, ByteOrder}; 48 | 49 | mod ptrace_util; 50 | use ptrace_util::Process; 51 | 52 | mod inferior; 53 | use inferior::*; 54 | 55 | mod syscalls64; 56 | use syscalls64::*; 57 | 58 | mod addressmap; 59 | use addressmap::*; 60 | 61 | mod bytebuf; 62 | use bytebuf::*; 63 | 64 | mod process; 65 | 66 | // #[macro_use] extern crate text_io; 67 | #[macro_use] 68 | extern crate scan_fmt; 69 | 70 | const USAGE: &'static str = " 71 | Program. 72 | 73 | Usage: program [options] 74 | tracer --command= 75 | tracer --pid= 76 | tracer --version 77 | 78 | Options: 79 | -p --pid=VALUE 80 | -c --command=VALUE 81 | -a --assembly 82 | "; 83 | 84 | #[derive(Debug, RustcDecodable)] 85 | struct Args { 86 | arg_name: Option, 87 | flag_command: Option, 88 | flag_pid: Option, 89 | flag_version: bool, 90 | flag_assembly: bool, 91 | } 92 | 93 | #[derive(Clone, Debug)] 94 | pub struct link_map { 95 | // These first few members are part of the protocol with the debugger. 96 | // This is the same format used in SVR4. 97 | pub l_addr: Elf64_Addr, // Base address shared object is loaded at. 98 | pub l_name: Elf64_Addr, // Absolute file name object was found in. 99 | pub l_ld: Elf64_Addr, // Dynamic section of the shared object. 100 | pub l_next: Elf64_Addr, 101 | pub l_prev: Elf64_Addr, // Chain of loaded objects. 102 | } 103 | 104 | fn dump_program_headers(process: &mut Process) { 105 | let program_headers: HashMap = process.program_headers().unwrap(); 106 | 107 | println!("Program headers"); 108 | println!("********"); 109 | 110 | for ph in program_headers.iter() { 111 | println!("{:?}", ph); 112 | } 113 | 114 | println!(""); 115 | println!(""); 116 | } 117 | 118 | fn dump_symbols(process: &mut Process) { 119 | let symtab = *(process.sections(DT_SYMTAB).unwrap().first().unwrap()); 120 | let strtab = *(process.sections(DT_STRTAB).unwrap().first().unwrap()); 121 | 122 | println!("Symbols"); 123 | println!("********"); 124 | 125 | let mut offset = symtab; 126 | 127 | // symbols 128 | let mut sym = process.read_struct::(offset).expect("sym"); 129 | for n in 0..128 { 130 | // ehdr.e_shnum { 131 | 132 | let c_str2 = process.string_at(strtab + (sym.st_name as i64)) 133 | .expect("could not read string"); 134 | println!("{:?} {:x} {:?} {:?}", n, offset, sym, c_str2); 135 | 136 | // st_name, st_value, offset? 137 | offset = offset + mem::size_of::() as i64; 138 | sym = process.read_struct::(offset).expect("sym"); 139 | } 140 | 141 | println!(""); 142 | } 143 | 144 | fn dump_relocations(process: &mut Process) { 145 | let dt_jmprel = *(process.sections(DT_JMPREL).unwrap().first().unwrap()); 146 | 147 | // Relocation 148 | println!("Relocations"); 149 | println!("********"); 150 | 151 | let mut offset = dt_jmprel; 152 | let mut rela = process.read_struct::(offset).expect("rela"); 153 | for n in 0..128 { 154 | // ehdr.e_shnum { 155 | // type and offset 156 | // 157 | println!("Rela {:?} {:?} {:?} {:?} {:x}", 158 | n, 159 | rela, 160 | (rela.r_info >> 32), 161 | (rela.r_info & 0xffffffff), 162 | rela.r_offset); 163 | 164 | offset = offset + mem::size_of::() as i64; 165 | rela = process.read_struct::(offset).expect("sym"); 166 | } 167 | 168 | println!(""); 169 | } 170 | 171 | fn dump_needed(process: &mut Process) { 172 | println!("Needed"); 173 | println!("********"); 174 | 175 | let strtab = *(process.sections(DT_STRTAB).unwrap().first().unwrap()); 176 | let needed = process.sections(DT_NEEDED).unwrap(); 177 | for s in needed.into_iter() { 178 | let c_str2 = process.string_at(strtab + (s.as_voidptr() as i64)) 179 | .expect("could not read string"); 180 | println!("Needed: {:?}", c_str2); 181 | } 182 | 183 | println!(""); 184 | } 185 | 186 | 187 | fn main() { 188 | let args: Args = Docopt::new(USAGE) 189 | .and_then(|d| d.decode()) 190 | .unwrap_or_else(|e| e.exit()); 191 | 192 | if args.flag_pid.is_some() { 193 | } 194 | 195 | let filename = args.flag_command.unwrap(); 196 | 197 | // dwarf::elf::load(&filename.clone()).expect("could not read dwarf data"); 198 | 199 | match fork().expect("fork failed") { 200 | ForkResult::Parent { child } => { 201 | println!("{}", Yellow.paint(format!("Waiting for child with pid {:}.", child))); 202 | 203 | let mut wait_status: c_int = Process::wait(); 204 | 205 | println!("{}", Yellow.paint("Child ready.")); 206 | 207 | let mut process = Process::new(child); 208 | 209 | let map = Maps::load(child).unwrap(); 210 | 211 | let base_addr = InferiorPointer(0x400000); 212 | 213 | if !process.is_elf() { 214 | println!("{}", Red.paint("Child is not an elf binary.")); 215 | return; 216 | } 217 | 218 | dump_program_headers(&mut process); 219 | 220 | dump_needed(&mut process); 221 | 222 | dump_symbols(&mut process); 223 | 224 | dump_relocations(&mut process); 225 | 226 | let ehdr: Elf64_Ehdr = process.ehdr().unwrap(); 227 | 228 | let symtab = *(process.sections(DT_SYMTAB).unwrap().first().unwrap()); 229 | let strtab = *(process.sections(DT_STRTAB).unwrap().first().unwrap()); 230 | let dt_jmprel = *(process.sections(DT_JMPREL).unwrap().first().unwrap()); 231 | 232 | let engine = capstone::Capstone::new(capstone::CsArch::ARCH_X86, capstone::CsMode::MODE_64) 233 | .expect("could not init engine"); 234 | 235 | let mut next = 0; 236 | while Process::WIFSTOPPED(wait_status) { 237 | let p = process.rip().ok().expect(""); 238 | 239 | if next != p.as_voidptr() as u64 { 240 | // println!(""); 241 | } 242 | 243 | let curr_addr_map = map.resolve(p.as_voidptr() as u64); 244 | 245 | next = p.as_voidptr() as u64; 246 | 247 | // allow max 16 bits instructions 248 | let mut raw_bytes : [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 249 | 250 | process.peek_text_bytes(p, &mut raw_bytes[0..]); 251 | 252 | match engine 253 | .disasm(&raw_bytes, p.as_voidptr() as u64, 0) { 254 | Some(insns) => { 255 | for i in insns.iter() { 256 | next+=i.size as u64; 257 | 258 | let size = i.size as u8; 259 | let bytes : &[u8] = unsafe { std::slice::from_raw_parts(i.bytes.as_ptr(), size as usize) }; 260 | 261 | // jmp far 262 | if raw_bytes[0x0] == 0xff && raw_bytes[0x1] == 0x25 { 263 | let address = byteorder::LittleEndian::read_u32(&raw_bytes[2..]) - 2; 264 | 265 | let mut ndx: u64 = 0; 266 | 267 | let mut offset = dt_jmprel; 268 | let mut rela = process.read_struct::(offset).expect("rela"); 269 | for n in 0..ehdr.e_shnum { 270 | if rela.r_offset == (p + address as i64).as_voidptr() as u64 { 271 | ndx = (rela.r_info >> 32) + 1; 272 | } else { 273 | // println!("Rela {:?} {:?} {:?} {:?} {:x} {:x}", n, rela, (rela.r_info >> 32), (rela.r_info & 0xffffffff), rela.r_offset, p + address as i64 + 2 as i64); 274 | } 275 | 276 | offset = offset + mem::size_of::() as i64; 277 | rela = process.read_struct::(offset).expect("rela"); 278 | } 279 | 280 | if ndx == 0 { 281 | // could not find symbol 282 | continue; 283 | } 284 | 285 | let mut offset = symtab; 286 | 287 | // symbols 288 | let mut sym = process.read_struct::(offset).expect("sym"); 289 | for n in 0..ehdr.e_shnum { 290 | 291 | let c_str2 = process.string_at(strtab + (sym.st_name as i64)).expect("could not read string"); 292 | if (n as u64) == ndx { 293 | // sym.st_shndx -> ref section header 294 | 295 | if (sym.st_info >> 4) == elftools::STB_WEAK as u8 { 296 | // println!("WEAK"); 297 | } else if (sym.st_info >> 4) == elftools::STB_GLOBAL as u8{ 298 | // println!("GLOBAL {:}", Red.paint(c_str2.clone())); 299 | } else if (sym.st_info >> 4) == elftools::STB_LOCAL as u8{ 300 | // println!("LOCAL"); 301 | } 302 | 303 | if (sym.st_info & 0xf) == elftools::STT_NOTYPE as u8 { 304 | // println!("NOTYPE"); 305 | } else if (sym.st_info & 0xf) == elftools::STT_OBJECT as u8{ 306 | // println!("OBJECT"); 307 | } else if (sym.st_info & 0xf) == elftools::STT_FUNC as u8{ 308 | println!("{:<32} {:12x} {:>20} {:} {:}", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), c_str2.clone()); 309 | } else if (sym.st_info & 0xf) == elftools::STT_SECTION as u8{ 310 | // println!("SECTIOn"); 311 | } else if (sym.st_info & 0xf) == elftools::STT_FILE as u8{ 312 | // println!("FILE"); 313 | } else if (sym.st_info & 0xf) == elftools::STT_COMMON as u8{ 314 | // println!("COMMON"); 315 | } else if (sym.st_info & 0xf) == elftools::STT_TLS as u8{ 316 | // println!("TLS"); 317 | } 318 | } 319 | 320 | // st_name, st_value, offset? 321 | offset = offset + mem::size_of::() as i64; 322 | sym = process.read_struct::(offset).expect("sym"); 323 | } 324 | } else if raw_bytes[0x0] == 0x0f && raw_bytes[0x1] == 0x05 { 325 | // syscall 326 | 327 | // rax contains syscall number 328 | let rax = ptrace_util::get_rax(child).as_voidptr() as u16; 329 | let text = match syscalls64.iter().find(|&r|r.number == rax) { 330 | Some(v) => v.name, 331 | None => "unknown", 332 | }; 333 | 334 | // dump syscall 335 | if rax == 0 { 336 | // read 337 | let rdi = ptrace_util::get_rdi(child); 338 | println!("{:<32} {:12x} {:>20} {:} {:}{:}({:2x}) ( fd: {:2x} )", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), i.op_str().unwrap(), text, rax, rdi); 339 | } else if rax == 1 { 340 | // write 341 | let rdi = ptrace_util::get_rdi(child); 342 | println!("{:<32} {:12x} {:>20} {:} {:}{:}({:2x}) ( fd: {:2x} )", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), i.op_str().unwrap(), text, rax, rdi); 343 | } else if rax == 2 { 344 | // open 345 | 346 | let rdi = ptrace_util::get_rdi(child); 347 | let rsi = ptrace_util::get_rsi(child); 348 | let rdx = ptrace_util::get_rdx(child); 349 | 350 | let s = process.string_at(rdi); 351 | println!("{:<32} {:12x} {:>20} {:} {:}{:}({:2x}) ( *filename: {:} )", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), i.op_str().unwrap(), text, rax, s.unwrap()); 352 | } else if rax == 3 { 353 | // write 354 | let rdi = ptrace_util::get_rdi(child); 355 | println!("{:<32} {:12x} {:>20} {:} {:}{:}({:2x}) ( fd: {:2x} )", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), i.op_str().unwrap(), text, rax, rdi); 356 | } else if rax == 4 { 357 | // stat 358 | 359 | let rdi = ptrace_util::get_rdi(child); 360 | let rsi = ptrace_util::get_rsi(child); 361 | let rdx = ptrace_util::get_rdx(child); 362 | 363 | let s = process.string_at(rdi); 364 | println!("{:<32} {:12x} {:>20} {:} {:}{:}({:2x}) ( *filename: {:} )", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), i.op_str().unwrap(), text, rax, s.unwrap()); 365 | } else { 366 | println!("{:<32} {:12x} {:>20} {:} {:}{:}", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), Green.paint(i.mnemonic().unwrap()), i.op_str().unwrap(), text); 367 | } 368 | break; 369 | } 370 | if args.flag_assembly { 371 | println!("{:<32} {:12x} {:>20} {:} {:}", curr_addr_map.map_or(String::from("unknown"), |m|m.path.clone()), p.as_voidptr() as u64, Yellow.paint(format!("{:>20}", format!("{:2x}", ByteBuf(bytes)))), i.mnemonic().unwrap(), i.op_str().unwrap()); 372 | } 373 | } 374 | } 375 | None => { 376 | println!("{:12x} {:x} FAILED", p.as_voidptr() as u64, ByteBuf(&raw_bytes)); 377 | } 378 | } 379 | 380 | process.single_step().unwrap(); 381 | 382 | wait_status = Process::wait(); 383 | } 384 | } 385 | ForkResult::Child => { 386 | ptrace_util::trace_me(); 387 | 388 | let c_filename = CString::new(filename).unwrap(); //.to_str().unwrap()).unwrap(); 389 | 390 | 391 | let args = &[c_filename]; 392 | 393 | execve(&args[0], args, &[]) 394 | .ok() 395 | .expect("Failed execve"); 396 | } 397 | } 398 | } 399 | -------------------------------------------------------------------------------- /src/syscalls64.rs: -------------------------------------------------------------------------------- 1 | pub struct SyscallParameters { 2 | pub name: String, 3 | pub sysname: String, 4 | } 5 | 6 | 7 | #[derive(Debug)] 8 | pub struct Syscall { 9 | pub number: u16, 10 | pub name: &'static str, 11 | pub sysname: &'static str, 12 | pub file: &'static str, // parameters: Option>, 13 | } 14 | 15 | pub const syscalls64: [Syscall; 314] = [ 16 | Syscall{number: 216, name: "remap_file_pages", file: "sys_remap_file_pages", sysname: "mm/fremap.c"}, 17 | Syscall{number: 217, name: "getdents64", file: "sys_getdents64", sysname: "fs/readdir.c"}, 18 | Syscall{number: 214, name: "epoll_ctl_old", file: "None", sysname: "None"}, 19 | Syscall{number: 215, name: "epoll_wait_old", file: "None", sysname: "None"}, 20 | Syscall{number: 212, name: "lookup_dcookie", file: "sys_lookup_dcookie", sysname: "fs/dcookies.c"}, 21 | Syscall{number: 213, name: "epoll_create", file: "sys_epoll_create", sysname: "fs/eventpoll.c"}, 22 | Syscall{number: 210, name: "io_cancel", file: "sys_io_cancel", sysname: "fs/aio.c"}, 23 | Syscall{number: 211, name: "get_thread_area", file: "None", sysname: "arch/x86/kernel/tls.c"}, 24 | Syscall{number: 165, name: "mount", file: "sys_mount", sysname: "fs/namespace.c"}, 25 | Syscall{number: 264, name: "renameat", file: "sys_renameat", sysname: "fs/namei.c"}, 26 | Syscall{number: 265, name: "linkat", file: "sys_linkat", sysname: "fs/namei.c"}, 27 | Syscall{number: 218, name: "set_tid_address", file: "sys_set_tid_address", sysname: "kernel/fork.c"}, 28 | Syscall{number: 219, name: "restart_syscall", file: "sys_restart_syscall", sysname: "kernel/signal.c"}, 29 | Syscall{number: 133, name: "mknod", file: "sys_mknod", sysname: "fs/namei.c"}, 30 | Syscall{number: 132, name: "utime", file: "sys_utime", sysname: "fs/utimes.c"}, 31 | Syscall{number: 131, name: "sigaltstack", file: "sys_sigaltstack", sysname: "kernel/signal.c"}, 32 | Syscall{number: 130, name: "rt_sigsuspend", file: "sys_rt_sigsuspend", sysname: "kernel/signal.c"}, 33 | Syscall{number: 137, name: "statfs", file: "sys_statfs", sysname: "fs/statfs.c"}, 34 | Syscall{number: 136, name: "ustat", file: "sys_ustat", sysname: "fs/statfs.c"}, 35 | Syscall{number: 135, name: "personality", file: "sys_personality", sysname: "kernel/exec_domain.c"}, 36 | Syscall{number: 134, name: "uselib", file: "None", sysname: "fs/exec.c"}, 37 | Syscall{number: 139, name: "sysfs", file: "sys_sysfs", sysname: "fs/filesystems.c"}, 38 | Syscall{number: 138, name: "fstatfs", file: "sys_fstatfs", sysname: "fs/statfs.c"}, 39 | Syscall{number: 166, name: "umount2", file: "sys_umount", sysname: "fs/namespace.c"}, 40 | Syscall{number: 24, name: "sched_yield", file: "sys_sched_yield", sysname: "kernel/sched/core.c"}, 41 | Syscall{number: 25, name: "mremap", file: "sys_mremap", sysname: "mm/mmap.c"}, 42 | Syscall{number: 26, name: "msync", file: "sys_msync", sysname: "mm/msync.c"}, 43 | Syscall{number: 27, name: "mincore", file: "sys_mincore", sysname: "mm/mincore.c"}, 44 | Syscall{number: 20, name: "writev", file: "sys_writev", sysname: "fs/read_write.c"}, 45 | Syscall{number: 21, name: "access", file: "sys_access", sysname: "fs/open.c"}, 46 | Syscall{number: 22, name: "pipe", file: "sys_pipe", sysname: "fs/pipe.c"}, 47 | Syscall{number: 23, name: "select", file: "sys_select", sysname: "fs/select.c"}, 48 | Syscall{number: 160, name: "setrlimit", file: "sys_setrlimit", sysname: "kernel/sys.c"}, 49 | Syscall{number: 28, name: "madvise", file: "sys_madvise", sysname: "mm/madvise.c"}, 50 | Syscall{number: 29, name: "shmget", file: "sys_shmget", sysname: "ipc/shm.c"}, 51 | Syscall{number: 161, name: "chroot", file: "sys_chroot", sysname: "fs/open.c"}, 52 | Syscall{number: 289, name: "signalfd4", file: "sys_signalfd4", sysname: "fs/signalfd.c"}, 53 | Syscall{number: 0, name: "read", file: "sys_read", sysname: "fs/read_write.c"}, 54 | Syscall{number: 4, name: "stat", file: "sys_newstat", sysname: "fs/stat.c"}, 55 | Syscall{number: 281, name: "epoll_pwait", file: "sys_epoll_pwait", sysname: "fs/eventpoll.c"}, 56 | Syscall{number: 8, name: "lseek", file: "sys_lseek", sysname: "fs/read_write.c"}, 57 | Syscall{number: 283, name: "timerfd_create", file: "sys_timerfd_create", sysname: "fs/timerfd.c"}, 58 | Syscall{number: 163, name: "acct", file: "sys_acct", sysname: "kernel/acct.c"}, 59 | Syscall{number: 285, name: "fallocate", file: "sys_fallocate", sysname: "fs/open.c"}, 60 | Syscall{number: 284, name: "eventfd", file: "sys_eventfd", sysname: "fs/eventfd.c"}, 61 | Syscall{number: 287, name: "timerfd_gettime", file: "sys_timerfd_gettime", sysname: "fs/timerfd.c"}, 62 | Syscall{number: 286, name: "timerfd_settime", file: "sys_timerfd_settime", sysname: "fs/timerfd.c"}, 63 | Syscall{number: 119, name: "setresgid", file: "sys_setresgid", sysname: "kernel/sys.c"}, 64 | Syscall{number: 271, name: "ppoll", file: "sys_ppoll", sysname: "fs/select.c"}, 65 | Syscall{number: 258, name: "mkdirat", file: "sys_mkdirat", sysname: "fs/namei.c"}, 66 | Syscall{number: 120, name: "getresgid", file: "sys_getresgid", sysname: "kernel/sys.c"}, 67 | Syscall{number: 121, name: "getpgid", file: "sys_getpgid", sysname: "kernel/sys.c"}, 68 | Syscall{number: 122, name: "setfsuid", file: "sys_setfsuid", sysname: "kernel/sys.c"}, 69 | Syscall{number: 123, name: "setfsgid", file: "sys_setfsgid", sysname: "kernel/sys.c"}, 70 | Syscall{number: 124, name: "getsid", file: "sys_getsid", sysname: "kernel/sys.c"}, 71 | Syscall{number: 125, name: "capget", file: "sys_capget", sysname: "kernel/capability.c"}, 72 | Syscall{number: 126, name: "capset", file: "sys_capset", sysname: "kernel/capability.c"}, 73 | Syscall{number: 127, name: "rt_sigpending", file: "sys_rt_sigpending", sysname: "kernel/signal.c"}, 74 | Syscall{number: 128, name: "rt_sigtimedwait", file: "sys_rt_sigtimedwait", sysname: "kernel/signal.c"}, 75 | Syscall{number: 129, name: "rt_sigqueueinfo", file: "sys_rt_sigqueueinfo", sysname: "kernel/signal.c"}, 76 | Syscall{number: 269, name: "faccessat", file: "sys_faccessat", sysname: "fs/open.c"}, 77 | Syscall{number: 268, name: "fchmodat", file: "sys_fchmodat", sysname: "fs/open.c"}, 78 | Syscall{number: 167, name: "swapon", file: "sys_swapon", sysname: "mm/swapfile.c"}, 79 | Syscall{number: 118, name: "getresuid", file: "sys_getresuid", sysname: "kernel/sys.c"}, 80 | Syscall{number: 59, name: "execve", file: "stub_execve", sysname: "fs/exec.c"}, 81 | Syscall{number: 58, name: "vfork", file: "stub_vfork", sysname: "kernel/fork.c"}, 82 | Syscall{number: 55, name: "getsockopt", file: "sys_getsockopt", sysname: "net/socket.c"}, 83 | Syscall{number: 54, name: "setsockopt", file: "sys_setsockopt", sysname: "net/socket.c"}, 84 | Syscall{number: 57, name: "fork", file: "stub_fork", sysname: "kernel/fork.c"}, 85 | Syscall{number: 56, name: "clone", file: "stub_clone", sysname: "kernel/fork.c"}, 86 | Syscall{number: 51, name: "getsockname", file: "sys_getsockname", sysname: "net/socket.c"}, 87 | Syscall{number: 50, name: "listen", file: "sys_listen", sysname: "net/socket.c"}, 88 | Syscall{number: 53, name: "socketpair", file: "sys_socketpair", sysname: "net/socket.c"}, 89 | Syscall{number: 52, name: "getpeername", file: "sys_getpeername", sysname: "net/socket.c"}, 90 | Syscall{number: 259, name: "mknodat", file: "sys_mknodat", sysname: "fs/namei.c"}, 91 | Syscall{number: 312, name: "kcmp", file: "sys_kcmp", sysname: "kernel/kcmp.c"}, 92 | Syscall{number: 298, name: "perf_event_open", file: "sys_perf_event_open", sysname: "kernel/events/core.c"}, 93 | Syscall{number: 299, name: "recvmmsg", file: "sys_recvmmsg", sysname: "net/socket.c"}, 94 | Syscall{number: 296, name: "pwritev", file: "sys_pwritev", sysname: "fs/read_write.c"}, 95 | Syscall{number: 297, name: "rt_tgsigqueueinfo", file: "sys_rt_tgsigqueueinfo", sysname: "kernel/signal.c"}, 96 | Syscall{number: 294, name: "inotify_init1", file: "sys_inotify_init1", sysname: "fs/notify/inotify/inotify_user.c"}, 97 | Syscall{number: 295, name: "preadv", file: "sys_preadv", sysname: "fs/read_write.c"}, 98 | Syscall{number: 292, name: "dup3", file: "sys_dup3", sysname: "fs/file.c"}, 99 | Syscall{number: 293, name: "pipe2", file: "sys_pipe2", sysname: "fs/pipe.c"}, 100 | Syscall{number: 290, name: "eventfd2", file: "sys_eventfd2", sysname: "fs/eventfd.c"}, 101 | Syscall{number: 291, name: "epoll_create1", file: "sys_epoll_create1", sysname: "fs/eventpoll.c"}, 102 | Syscall{number: 164, name: "settimeofday", file: "sys_settimeofday", sysname: "kernel/time.c"}, 103 | Syscall{number: 201, name: "time", file: "sys_time", sysname: "kernel/time.c"}, 104 | Syscall{number: 199, name: "fremovexattr", file: "sys_fremovexattr", sysname: "fs/xattr.c"}, 105 | Syscall{number: 179, name: "quotactl", file: "sys_quotactl", sysname: "fs/quota/quota.c"}, 106 | Syscall{number: 200, name: "tkill", file: "sys_tkill", sysname: "kernel/signal.c"}, 107 | Syscall{number: 195, name: "llistxattr", file: "sys_llistxattr", sysname: "fs/xattr.c"}, 108 | Syscall{number: 194, name: "listxattr", file: "sys_listxattr", sysname: "fs/xattr.c"}, 109 | Syscall{number: 197, name: "removexattr", file: "sys_removexattr", sysname: "fs/xattr.c"}, 110 | Syscall{number: 178, name: "query_module", file: "None", sysname: "None"}, 111 | Syscall{number: 191, name: "getxattr", file: "sys_getxattr", sysname: "fs/xattr.c"}, 112 | Syscall{number: 190, name: "fsetxattr", file: "sys_fsetxattr", sysname: "fs/xattr.c"}, 113 | Syscall{number: 193, name: "fgetxattr", file: "sys_fgetxattr", sysname: "fs/xattr.c"}, 114 | Syscall{number: 192, name: "lgetxattr", file: "sys_lgetxattr", sysname: "fs/xattr.c"}, 115 | Syscall{number: 115, name: "getgroups", file: "sys_getgroups", sysname: "kernel/groups.c"}, 116 | Syscall{number: 114, name: "setregid", file: "sys_setregid", sysname: "kernel/sys.c"}, 117 | Syscall{number: 88, name: "symlink", file: "sys_symlink", sysname: "fs/namei.c"}, 118 | Syscall{number: 89, name: "readlink", file: "sys_readlink", sysname: "fs/stat.c"}, 119 | Syscall{number: 111, name: "getpgrp", file: "sys_getpgrp", sysname: "kernel/sys.c"}, 120 | Syscall{number: 110, name: "getppid", file: "sys_getppid", sysname: "kernel/sys.c"}, 121 | Syscall{number: 113, name: "setreuid", file: "sys_setreuid", sysname: "kernel/sys.c"}, 122 | Syscall{number: 112, name: "setsid", file: "sys_setsid", sysname: "kernel/sys.c"}, 123 | Syscall{number: 82, name: "rename", file: "sys_rename", sysname: "fs/namei.c"}, 124 | Syscall{number: 83, name: "mkdir", file: "sys_mkdir", sysname: "fs/namei.c"}, 125 | Syscall{number: 80, name: "chdir", file: "sys_chdir", sysname: "fs/open.c"}, 126 | Syscall{number: 81, name: "fchdir", file: "sys_fchdir", sysname: "fs/open.c"}, 127 | Syscall{number: 86, name: "link", file: "sys_link", sysname: "fs/namei.c"}, 128 | Syscall{number: 87, name: "unlink", file: "sys_unlink", sysname: "fs/namei.c"}, 129 | Syscall{number: 84, name: "rmdir", file: "sys_rmdir", sysname: "fs/namei.c"}, 130 | Syscall{number: 85, name: "creat", file: "sys_creat", sysname: "fs/open.c"}, 131 | Syscall{number: 251, name: "ioprio_set", file: "sys_ioprio_set", sysname: "fs/ioprio.c"}, 132 | Syscall{number: 304, name: "open_by_handle_at", file: "sys_open_by_handle_at", sysname: "fs/fhandle.c"}, 133 | Syscall{number: 198, name: "lremovexattr", file: "sys_lremovexattr", sysname: "fs/xattr.c"}, 134 | Syscall{number: 256, name: "migrate_pages", file: "sys_migrate_pages", sysname: "mm/mempolicy.c"}, 135 | Syscall{number: 206, name: "io_setup", file: "sys_io_setup", sysname: "fs/aio.c"}, 136 | Syscall{number: 226, name: "timer_delete", file: "sys_timer_delete", sysname: "kernel/posix-timers.c"}, 137 | Syscall{number: 257, name: "openat", file: "sys_openat", sysname: "fs/open.c"}, 138 | Syscall{number: 3, name: "close", file: "sys_close", sysname: "fs/open.c"}, 139 | Syscall{number: 177, name: "get_kernel_syms", file: "None", sysname: "None"}, 140 | Syscall{number: 254, name: "inotify_add_watch", file: "sys_inotify_add_watch", sysname: "fs/notify/inotify/inotify_user.c"}, 141 | Syscall{number: 7, name: "poll", file: "sys_poll", sysname: "fs/select.c"}, 142 | Syscall{number: 247, name: "waitid", file: "sys_waitid", sysname: "kernel/exit.c"}, 143 | Syscall{number: 273, name: "set_robust_list", file: "sys_set_robust_list", sysname: "kernel/futex.c"}, 144 | Syscall{number: 255, name: "inotify_rm_watch", file: "sys_inotify_rm_watch", sysname: "fs/notify/inotify/inotify_user.c"}, 145 | Syscall{number: 308, name: "setns", file: "sys_setns", sysname: "kernel/nsproxy.c"}, 146 | Syscall{number: 309, name: "getcpu", file: "sys_getcpu", sysname: "kernel/sys.c"}, 147 | Syscall{number: 300, name: "fanotify_init", file: "sys_fanotify_init", sysname: "fs/notify/fanotify/fanotify_user.c"}, 148 | Syscall{number: 301, name: "fanotify_mark", file: "sys_fanotify_mark", sysname: "fs/notify/fanotify/fanotify_user.c"}, 149 | Syscall{number: 302, name: "prlimit64", file: "sys_prlimit64", sysname: "kernel/sys.c"}, 150 | Syscall{number: 303, name: "name_to_handle_at", file: "sys_name_to_handle_at", sysname: "fs/fhandle.c"}, 151 | Syscall{number: 225, name: "timer_getoverrun", file: "sys_timer_getoverrun", sysname: "kernel/posix-timers.c"}, 152 | Syscall{number: 305, name: "clock_adjtime", file: "sys_clock_adjtime", sysname: "kernel/posix-timers.c"}, 153 | Syscall{number: 306, name: "syncfs", file: "sys_syncfs", sysname: "fs/sync.c"}, 154 | Syscall{number: 307, name: "sendmmsg", file: "sys_sendmmsg", sysname: "net/socket.c"}, 155 | Syscall{number: 245, name: "mq_getsetattr", file: "sys_mq_getsetattr", sysname: "ipc/mqueue.c"}, 156 | Syscall{number: 244, name: "mq_notify", file: "sys_mq_notify", sysname: "ipc/mqueue.c"}, 157 | Syscall{number: 108, name: "getegid", file: "sys_getegid", sysname: "kernel/sys.c"}, 158 | Syscall{number: 109, name: "setpgid", file: "sys_setpgid", sysname: "kernel/sys.c"}, 159 | Syscall{number: 241, name: "mq_unlink", file: "sys_mq_unlink", sysname: "ipc/mqueue.c"}, 160 | Syscall{number: 240, name: "mq_open", file: "sys_mq_open", sysname: "ipc/mqueue.c"}, 161 | Syscall{number: 243, name: "mq_timedreceive", file: "sys_mq_timedreceive", sysname: "ipc/mqueue.c"}, 162 | Syscall{number: 242, name: "mq_timedsend", file: "sys_mq_timedsend", sysname: "ipc/mqueue.c"}, 163 | Syscall{number: 102, name: "getuid", file: "sys_getuid", sysname: "kernel/sys.c"}, 164 | Syscall{number: 103, name: "syslog", file: "sys_syslog", sysname: "kernel/printk/printk.c"}, 165 | Syscall{number: 100, name: "times", file: "sys_times", sysname: "kernel/sys.c"}, 166 | Syscall{number: 101, name: "ptrace", file: "sys_ptrace", sysname: "kernel/ptrace.c"}, 167 | Syscall{number: 106, name: "setgid", file: "sys_setgid", sysname: "kernel/sys.c"}, 168 | Syscall{number: 107, name: "geteuid", file: "sys_geteuid", sysname: "kernel/sys.c"}, 169 | Syscall{number: 104, name: "getgid", file: "sys_getgid", sysname: "kernel/sys.c"}, 170 | Syscall{number: 105, name: "setuid", file: "sys_setuid", sysname: "kernel/sys.c"}, 171 | Syscall{number: 39, name: "getpid", file: "sys_getpid", sysname: "kernel/sys.c"}, 172 | Syscall{number: 38, name: "setitimer", file: "sys_setitimer", sysname: "kernel/itimer.c"}, 173 | Syscall{number: 33, name: "dup2", file: "sys_dup2", sysname: "fs/file.c"}, 174 | Syscall{number: 32, name: "dup", file: "sys_dup", sysname: "fs/file.c"}, 175 | Syscall{number: 31, name: "shmctl", file: "sys_shmctl", sysname: "ipc/shm.c"}, 176 | Syscall{number: 30, name: "shmat", file: "sys_shmat", sysname: "ipc/shm.c"}, 177 | Syscall{number: 37, name: "alarm", file: "sys_alarm", sysname: "kernel/timer.c"}, 178 | Syscall{number: 36, name: "getitimer", file: "sys_getitimer", sysname: "kernel/itimer.c"}, 179 | Syscall{number: 35, name: "nanosleep", file: "sys_nanosleep", sysname: "kernel/hrtimer.c"}, 180 | Syscall{number: 34, name: "pause", file: "sys_pause", sysname: "kernel/signal.c"}, 181 | Syscall{number: 246, name: "kexec_load", file: "sys_kexec_load", sysname: "kernel/kexec.c"}, 182 | Syscall{number: 310, name: "process_vm_readv", file: "sys_process_vm_readv", sysname: "mm/process_vm_access.c"}, 183 | Syscall{number: 282, name: "signalfd", file: "sys_signalfd", sysname: "fs/signalfd.c"}, 184 | Syscall{number: 252, name: "ioprio_get", file: "sys_ioprio_get", sysname: "fs/ioprio.c"}, 185 | Syscall{number: 205, name: "set_thread_area", file: "None", sysname: "arch/x86/kernel/tls.c"}, 186 | Syscall{number: 223, name: "timer_settime", file: "sys_timer_settime", sysname: "kernel/posix-timers.c"}, 187 | Syscall{number: 176, name: "delete_module", file: "sys_delete_module", sysname: "kernel/module.c"}, 188 | Syscall{number: 60, name: "exit", file: "sys_exit", sysname: "kernel/exit.c"}, 189 | Syscall{number: 61, name: "wait4", file: "sys_wait4", sysname: "kernel/exit.c"}, 190 | Syscall{number: 62, name: "kill", file: "sys_kill", sysname: "kernel/signal.c"}, 191 | Syscall{number: 63, name: "uname", file: "sys_newuname", sysname: "kernel/sys.c"}, 192 | Syscall{number: 64, name: "semget", file: "sys_semget", sysname: "ipc/sem.c"}, 193 | Syscall{number: 65, name: "semop", file: "sys_semop", sysname: "ipc/sem.c"}, 194 | Syscall{number: 66, name: "semctl", file: "sys_semctl", sysname: "ipc/sem.c"}, 195 | Syscall{number: 67, name: "shmdt", file: "sys_shmdt", sysname: "ipc/shm.c"}, 196 | Syscall{number: 68, name: "msgget", file: "sys_msgget", sysname: "ipc/msg.c"}, 197 | Syscall{number: 69, name: "msgsnd", file: "sys_msgsnd", sysname: "ipc/msg.c"}, 198 | Syscall{number: 175, name: "init_module", file: "sys_init_module", sysname: "kernel/module.c"}, 199 | Syscall{number: 174, name: "create_module", file: "None", sysname: "None"}, 200 | Syscall{number: 173, name: "ioperm", file: "sys_ioperm", sysname: "arch/x86/kernel/ioport.c"}, 201 | Syscall{number: 172, name: "iopl", file: "stub_iopl", sysname: "arch/x86/kernel/ioport.c"}, 202 | Syscall{number: 171, name: "setdomainname", file: "sys_setdomainname", sysname: "kernel/sys.c"}, 203 | Syscall{number: 170, name: "sethostname", file: "sys_sethostname", sysname: "kernel/sys.c"}, 204 | Syscall{number: 203, name: "sched_setaffinity", file: "sys_sched_setaffinity", sysname: "kernel/sched/core.c"}, 205 | Syscall{number: 222, name: "timer_create", file: "sys_timer_create", sysname: "kernel/posix-timers.c"}, 206 | Syscall{number: 288, name: "accept4", file: "sys_accept4", sysname: "net/socket.c"}, 207 | Syscall{number: 181, name: "getpmsg", file: "None", sysname: "None"}, 208 | Syscall{number: 253, name: "inotify_init", file: "sys_inotify_init", sysname: "fs/notify/inotify/inotify_user.c"}, 209 | Syscall{number: 248, name: "add_key", file: "sys_add_key", sysname: "security/keys/keyctl.c"}, 210 | Syscall{number: 182, name: "putpmsg", file: "None", sysname: "None"}, 211 | Syscall{number: 183, name: "afs_syscall", file: "None", sysname: "None"}, 212 | Syscall{number: 180, name: "nfsservctl", file: "None", sysname: "None"}, 213 | Syscall{number: 2, name: "open", file: "sys_open", sysname: "fs/open.c"}, 214 | Syscall{number: 162, name: "sync", file: "sys_sync", sysname: "fs/sync.c"}, 215 | Syscall{number: 187, name: "readahead", file: "sys_readahead", sysname: "mm/readahead.c"}, 216 | Syscall{number: 184, name: "tuxcall", file: "None", sysname: "None"}, 217 | Syscall{number: 6, name: "lstat", file: "sys_newlstat", sysname: "fs/stat.c"}, 218 | Syscall{number: 220, name: "semtimedop", file: "sys_semtimedop", sysname: "ipc/sem.c"}, 219 | Syscall{number: 186, name: "gettid", file: "sys_gettid", sysname: "kernel/sys.c"}, 220 | Syscall{number: 188, name: "setxattr", file: "sys_setxattr", sysname: "fs/xattr.c"}, 221 | Syscall{number: 189, name: "lsetxattr", file: "sys_lsetxattr", sysname: "fs/xattr.c"}, 222 | Syscall{number: 311, name: "process_vm_writev", file: "sys_process_vm_writev", sysname: "mm/process_vm_access.c"}, 223 | Syscall{number: 202, name: "futex", file: "sys_futex", sysname: "kernel/futex.c"}, 224 | Syscall{number: 313, name: "finit_module", file: "sys_finit_module", sysname: "kernel/module.c"}, 225 | Syscall{number: 196, name: "flistxattr", file: "sys_flistxattr", sysname: "fs/xattr.c"}, 226 | Syscall{number: 221, name: "fadvise64", file: "sys_fadvise64", sysname: "mm/fadvise.c"}, 227 | Syscall{number: 185, name: "security", file: "None", sysname: "None"}, 228 | Syscall{number: 99, name: "sysinfo", file: "sys_sysinfo", sysname: "kernel/sys.c"}, 229 | Syscall{number: 98, name: "getrusage", file: "sys_getrusage", sysname: "kernel/sys.c"}, 230 | Syscall{number: 168, name: "swapoff", file: "sys_swapoff", sysname: "mm/swapfile.c"}, 231 | Syscall{number: 169, name: "reboot", file: "sys_reboot", sysname: "kernel/reboot.c"}, 232 | Syscall{number: 229, name: "clock_getres", file: "sys_clock_getres", sysname: "kernel/posix-timers.c"}, 233 | Syscall{number: 228, name: "clock_gettime", file: "sys_clock_gettime", sysname: "kernel/posix-timers.c"}, 234 | Syscall{number: 91, name: "fchmod", file: "sys_fchmod", sysname: "fs/open.c"}, 235 | Syscall{number: 90, name: "chmod", file: "sys_chmod", sysname: "fs/open.c"}, 236 | Syscall{number: 93, name: "fchown", file: "sys_fchown", sysname: "fs/open.c"}, 237 | Syscall{number: 92, name: "chown", file: "sys_chown", sysname: "fs/open.c"}, 238 | Syscall{number: 95, name: "umask", file: "sys_umask", sysname: "kernel/sys.c"}, 239 | Syscall{number: 94, name: "lchown", file: "sys_lchown", sysname: "fs/open.c"}, 240 | Syscall{number: 97, name: "getrlimit", file: "sys_getrlimit", sysname: "kernel/sys.c"}, 241 | Syscall{number: 96, name: "gettimeofday", file: "sys_gettimeofday", sysname: "kernel/time.c"}, 242 | Syscall{number: 11, name: "munmap", file: "sys_munmap", sysname: "mm/mmap.c"}, 243 | Syscall{number: 10, name: "mprotect", file: "sys_mprotect", sysname: "mm/mprotect.c"}, 244 | Syscall{number: 13, name: "rt_sigaction", file: "sys_rt_sigaction", sysname: "kernel/signal.c"}, 245 | Syscall{number: 12, name: "brk", file: "sys_brk", sysname: "mm/mmap.c"}, 246 | Syscall{number: 15, name: "rt_sigreturn", file: "stub_rt_sigreturn", sysname: "arch/x86/kernel/signal.c"}, 247 | Syscall{number: 14, name: "rt_sigprocmask", file: "sys_rt_sigprocmask", sysname: "kernel/signal.c"}, 248 | Syscall{number: 17, name: "pread64", file: "sys_pread64", sysname: "fs/read_write.c"}, 249 | Syscall{number: 16, name: "ioctl", file: "sys_ioctl", sysname: "fs/ioctl.c"}, 250 | Syscall{number: 19, name: "readv", file: "sys_readv", sysname: "fs/read_write.c"}, 251 | Syscall{number: 18, name: "pwrite64", file: "sys_pwrite64", sysname: "fs/read_write.c"}, 252 | Syscall{number: 117, name: "setresuid", file: "sys_setresuid", sysname: "kernel/sys.c"}, 253 | Syscall{number: 250, name: "keyctl", file: "sys_keyctl", sysname: "security/keys/keyctl.c"}, 254 | Syscall{number: 116, name: "setgroups", file: "sys_setgroups", sysname: "kernel/groups.c"}, 255 | Syscall{number: 274, name: "get_robust_list", file: "sys_get_robust_list", sysname: "kernel/futex.c"}, 256 | Syscall{number: 204, name: "sched_getaffinity", file: "sys_sched_getaffinity", sysname: "kernel/sched/core.c"}, 257 | Syscall{number: 275, name: "splice", file: "sys_splice", sysname: "fs/splice.c"}, 258 | Syscall{number: 151, name: "mlockall", file: "sys_mlockall", sysname: "mm/mlock.c"}, 259 | Syscall{number: 150, name: "munlock", file: "sys_munlock", sysname: "mm/mlock.c"}, 260 | Syscall{number: 153, name: "vhangup", file: "sys_vhangup", sysname: "fs/open.c"}, 261 | Syscall{number: 152, name: "munlockall", file: "sys_munlockall", sysname: "mm/mlock.c"}, 262 | Syscall{number: 155, name: "pivot_root", file: "sys_pivot_root", sysname: "fs/namespace.c"}, 263 | Syscall{number: 154, name: "modify_ldt", file: "sys_modify_ldt", sysname: "arch/x86/um/ldt.c"}, 264 | Syscall{number: 157, name: "prctl", file: "sys_prctl", sysname: "kernel/sys.c"}, 265 | Syscall{number: 156, name: "_sysctl", file: "sys_sysctl", sysname: "kernel/sysctl_binary.c"}, 266 | Syscall{number: 159, name: "adjtimex", file: "sys_adjtimex", sysname: "kernel/time.c"}, 267 | Syscall{number: 158, name: "arch_prctl", file: "sys_arch_prctl", sysname: "arch/x86/um/syscalls_64.c"}, 268 | Syscall{number: 277, name: "sync_file_range", file: "sys_sync_file_range", sysname: "fs/sync.c"}, 269 | Syscall{number: 234, name: "tgkill", file: "sys_tgkill", sysname: "kernel/signal.c"}, 270 | Syscall{number: 238, name: "set_mempolicy", file: "sys_set_mempolicy", sysname: "mm/mempolicy.c"}, 271 | Syscall{number: 239, name: "get_mempolicy", file: "sys_get_mempolicy", sysname: "mm/mempolicy.c"}, 272 | Syscall{number: 279, name: "move_pages", file: "sys_move_pages", sysname: "mm/migrate.c"}, 273 | Syscall{number: 207, name: "io_destroy", file: "sys_io_destroy", sysname: "fs/aio.c"}, 274 | Syscall{number: 235, name: "utimes", file: "sys_utimes", sysname: "fs/utimes.c"}, 275 | Syscall{number: 236, name: "vserver", file: "None", sysname: "None"}, 276 | Syscall{number: 237, name: "mbind", file: "sys_mbind", sysname: "mm/mempolicy.c"}, 277 | Syscall{number: 230, name: "clock_nanosleep", file: "sys_clock_nanosleep", sysname: "kernel/posix-timers.c"}, 278 | Syscall{number: 231, name: "exit_group", file: "sys_exit_group", sysname: "kernel/exit.c"}, 279 | Syscall{number: 232, name: "epoll_wait", file: "sys_epoll_wait", sysname: "fs/eventpoll.c"}, 280 | Syscall{number: 233, name: "epoll_ctl", file: "sys_epoll_ctl", sysname: "fs/eventpoll.c"}, 281 | Syscall{number: 224, name: "timer_gettime", file: "sys_timer_gettime", sysname: "kernel/posix-timers.c"}, 282 | Syscall{number: 280, name: "utimensat", file: "sys_utimensat", sysname: "fs/utimes.c"}, 283 | Syscall{number: 48, name: "shutdown", file: "sys_shutdown", sysname: "net/socket.c"}, 284 | Syscall{number: 49, name: "bind", file: "sys_bind", sysname: "net/socket.c"}, 285 | Syscall{number: 46, name: "sendmsg", file: "sys_sendmsg", sysname: "net/socket.c"}, 286 | Syscall{number: 47, name: "recvmsg", file: "sys_recvmsg", sysname: "net/socket.c"}, 287 | Syscall{number: 44, name: "sendto", file: "sys_sendto", sysname: "net/socket.c"}, 288 | Syscall{number: 45, name: "recvfrom", file: "sys_recvfrom", sysname: "net/socket.c"}, 289 | Syscall{number: 42, name: "connect", file: "sys_connect", sysname: "net/socket.c"}, 290 | Syscall{number: 43, name: "accept", file: "sys_accept", sysname: "net/socket.c"}, 291 | Syscall{number: 40, name: "sendfile", file: "sys_sendfile64", sysname: "fs/read_write.c"}, 292 | Syscall{number: 41, name: "socket", file: "sys_socket", sysname: "net/socket.c"}, 293 | Syscall{number: 1, name: "write", file: "sys_write", sysname: "fs/read_write.c"}, 294 | Syscall{number: 5, name: "fstat", file: "sys_newfstat", sysname: "fs/stat.c"}, 295 | Syscall{number: 9, name: "mmap", file: "sys_mmap", sysname: "arch/x86/kernel/sys_x86_64.c"}, 296 | Syscall{number: 272, name: "unshare", file: "sys_unshare", sysname: "kernel/fork.c"}, 297 | Syscall{number: 146, name: "sched_get_priority_max", file: "sys_sched_get_priority_max", sysname: "kernel/sched/core.c"}, 298 | Syscall{number: 147, name: "sched_get_priority_min", file: "sys_sched_get_priority_min", sysname: "kernel/sched/core.c"}, 299 | Syscall{number: 144, name: "sched_setscheduler", file: "sys_sched_setscheduler", sysname: "kernel/sched/core.c"}, 300 | Syscall{number: 145, name: "sched_getscheduler", file: "sys_sched_getscheduler", sysname: "kernel/sched/core.c"}, 301 | Syscall{number: 142, name: "sched_setparam", file: "sys_sched_setparam", sysname: "kernel/sched/core.c"}, 302 | Syscall{number: 143, name: "sched_getparam", file: "sys_sched_getparam", sysname: "kernel/sched/core.c"}, 303 | Syscall{number: 140, name: "getpriority", file: "sys_getpriority", sysname: "kernel/sys.c"}, 304 | Syscall{number: 141, name: "setpriority", file: "sys_setpriority", sysname: "kernel/sys.c"}, 305 | Syscall{number: 209, name: "io_submit", file: "sys_io_submit", sysname: "fs/aio.c"}, 306 | Syscall{number: 208, name: "io_getevents", file: "sys_io_getevents", sysname: "fs/aio.c"}, 307 | Syscall{number: 148, name: "sched_rr_get_interval", file: "sys_sched_rr_get_interval", sysname: "kernel/sched/core.c"}, 308 | Syscall{number: 149, name: "mlock", file: "sys_mlock", sysname: "mm/mlock.c"}, 309 | Syscall{number: 77, name: "ftruncate", file: "sys_ftruncate", sysname: "fs/open.c"}, 310 | Syscall{number: 76, name: "truncate", file: "sys_truncate", sysname: "fs/open.c"}, 311 | Syscall{number: 75, name: "fdatasync", file: "sys_fdatasync", sysname: "fs/sync.c"}, 312 | Syscall{number: 74, name: "fsync", file: "sys_fsync", sysname: "fs/sync.c"}, 313 | Syscall{number: 73, name: "flock", file: "sys_flock", sysname: "fs/locks.c"}, 314 | Syscall{number: 72, name: "fcntl", file: "sys_fcntl", sysname: "fs/fcntl.c"}, 315 | Syscall{number: 71, name: "msgctl", file: "sys_msgctl", sysname: "ipc/msg.c"}, 316 | Syscall{number: 70, name: "msgrcv", file: "sys_msgrcv", sysname: "ipc/msg.c"}, 317 | Syscall{number: 278, name: "vmsplice", file: "sys_vmsplice", sysname: "fs/splice.c"}, 318 | Syscall{number: 79, name: "getcwd", file: "sys_getcwd", sysname: "fs/dcache.c"}, 319 | Syscall{number: 78, name: "getdents", file: "sys_getdents", sysname: "fs/readdir.c"}, 320 | Syscall{number: 263, name: "unlinkat", file: "sys_unlinkat", sysname: "fs/namei.c"}, 321 | Syscall{number: 249, name: "request_key", file: "sys_request_key", sysname: "security/keys/keyctl.c"}, 322 | Syscall{number: 262, name: "newfstatat", file: "sys_newfstatat", sysname: "fs/stat.c"}, 323 | Syscall{number: 227, name: "clock_settime", file: "sys_clock_settime", sysname: "kernel/posix-timers.c"}, 324 | Syscall{number: 261, name: "futimesat", file: "sys_futimesat", sysname: "fs/utimes.c"}, 325 | Syscall{number: 270, name: "pselect6", file: "sys_pselect6", sysname: "fs/select.c"}, 326 | Syscall{number: 260, name: "fchownat", file: "sys_fchownat", sysname: "fs/open.c"}, 327 | Syscall{number: 276, name: "tee", file: "sys_tee", sysname: "fs/splice.c"}, 328 | Syscall{number: 267, name: "readlinkat", file: "sys_readlinkat", sysname: "fs/stat.c"}, 329 | Syscall{number: 266, name: "symlinkat", file: "sys_symlinkat", sysname: "fs/namei.c"}, 330 | ]; 331 | --------------------------------------------------------------------------------