-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add system call sys_execve and some others
- Loading branch information
thesayol
committed
Mar 31, 2024
1 parent
b75bad8
commit e587453
Showing
18 changed files
with
771 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use core::ffi::c_int; | ||
|
||
#[derive(Debug, Clone, Copy)] | ||
struct UserCapHeader { | ||
/// Linux Cap Version: | ||
/// Version1 = 0x19980330, | ||
/// Version2 = 0x20071026, | ||
/// Version3 = 0x20080522, | ||
version: u32, | ||
pid: i32, | ||
} | ||
|
||
/// The effective, permitted, and inheritable fields are bit masks of the capabilities. | ||
/// Note that the CAP_* values are bit indexes and need to be bit-shifted before ORing into the bit fields. | ||
#[derive(Debug, Clone, Copy)] | ||
struct UserCapData { | ||
effective: u32, | ||
permitted: u32, | ||
inheritable: u32, | ||
} | ||
|
||
/// get thread capabilities. specific to Linux. | ||
pub fn sys_cap_get(cap_user_header: usize, cap_user_data: usize) -> c_int { | ||
let hdrp = cap_user_header as *const UserCapHeader; | ||
let datap = cap_user_data as *mut UserCapData; | ||
unsafe { | ||
debug!( | ||
"sys_cap_get <= pid {:?}, version {:x?} ", | ||
(*hdrp).pid, | ||
(*hdrp).version | ||
); | ||
} | ||
unsafe { | ||
// allow all | ||
(*datap).effective = u32::MAX; | ||
(*datap).inheritable = u32::MAX; | ||
(*datap).permitted = u32::MAX; | ||
}; | ||
syscall_body!(sys_cap_get, Ok(0)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#![allow(unused)] | ||
|
||
pub const AT_NULL: usize = 0; | ||
pub const AT_IGNORE: usize = 1; | ||
|
||
pub const AT_EXECFD: usize = 2; | ||
|
||
/// The address of the program headers of the executable. | ||
pub const AT_PHDR: usize = 3; | ||
|
||
pub const AT_PHENT: usize = 4; | ||
pub const AT_PHNUM: usize = 5; | ||
pub const AT_PAGESZ: usize = 6; | ||
|
||
/// The base address of the program interpreter (usually, the dynamic linker). | ||
pub const AT_BASE: usize = 7; | ||
|
||
pub const AT_FLAGS: usize = 8; | ||
pub const AT_ENTRY: usize = 9; | ||
pub const AT_NOTELF: usize = 10; | ||
pub const AT_UID: usize = 11; | ||
pub const AT_EUID: usize = 12; | ||
pub const AT_GID: usize = 13; | ||
pub const AT_EGID: usize = 14; | ||
pub const AT_PLATFORM: usize = 15; | ||
pub const AT_HWCAP: usize = 16; | ||
pub const AT_CLKTCK: usize = 17; | ||
pub const AT_DCACHEBSIZE: usize = 19; | ||
pub const AT_ICACHEBSIZE: usize = 20; | ||
pub const AT_UCACHEBSIZE: usize = 21; | ||
pub const AT_SECURE: usize = 23; | ||
pub const AT_RANDOM: usize = 25; | ||
|
||
/// A pointer to a string containing the pathname used to execute the program. | ||
pub const AT_EXECFN: usize = 31; | ||
|
||
/// The address of a page containing the vDSO that the kernel creates | ||
pub const AT_SYSINFO_EHDR: usize = 33; | ||
|
||
/// The entry point to the system call function in the vDSO. Not present/needed on all architectures (e.g., absent on x86-64). | ||
pub const AT_SYSINFO: usize = 32; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
use crate::*; | ||
use alloc::vec::Vec; | ||
use core::{ | ||
ffi::c_char, | ||
mem::size_of, | ||
ptr::{null, null_mut}, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub struct ElfProg { | ||
pub name: Vec<u8>, | ||
pub path: Vec<u8>, | ||
pub platform: Vec<u8>, | ||
pub rand: Vec<u64>, | ||
pub base: usize, | ||
pub entry: usize, | ||
pub interp_path: *const c_char, | ||
pub phent: usize, | ||
pub phnum: usize, | ||
pub phdr: usize, | ||
} | ||
|
||
impl ElfProg { | ||
/// read elf from `path`, and copy LOAD segments to a alloacated memory | ||
/// | ||
/// and load interp, if needed. | ||
pub fn new(filepath: *const c_char) -> Self { | ||
let name = ptr2vec(filepath); | ||
let path = ptr2vec(filepath); | ||
// info!("---------------------------------"); | ||
axlog::ax_println!("new elf prog: {}", vec_u8_to_str(&path)); | ||
|
||
// open file | ||
let fd = sys_open(filepath, ctypes::O_RDWR as i32, 0); | ||
// info!("open file, fd {}", fd); | ||
|
||
// get file size | ||
let buf = sys_mmap(null_mut(), size_of::<ctypes::kstat>(), 0, 0, 0, 0); | ||
let bufsize = unsafe { | ||
sys_fstat(fd, buf); | ||
(*(buf as *const ctypes::kstat)).st_size as usize | ||
}; | ||
sys_munmap(buf, size_of::<ctypes::kstat>()); | ||
// info!("fize size {}", bufsize); | ||
|
||
// read file | ||
let buf = sys_mmap(null_mut(), bufsize, 0, 0, fd, 0); | ||
axlog::ax_println!("mmap to read file at {:p} size {:x}", buf, bufsize); | ||
sys_read(fd, buf, bufsize); | ||
|
||
// parse elf | ||
let slice = unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, bufsize) }; | ||
let file = | ||
elf::ElfBytes::<elf::endian::AnyEndian>::minimal_parse(slice).expect("Open test1"); | ||
|
||
// get program's LOAD mem size | ||
let mut msize = 0; | ||
let segs = file.segments().unwrap(); | ||
for seg in segs { | ||
if seg.p_type == elf::abi::PT_LOAD { | ||
msize += seg.p_memsz; | ||
} | ||
} | ||
// info!("msize = {}", msize); | ||
|
||
// mmap memory to copy LOAD segmeants | ||
let a = crate::sys_mmap(null_mut(), msize as usize, 0, 0, 0, 0); | ||
axlog::ax_println!("mmap to copy LOAD at {:p} size {:x}", a, msize); | ||
let base = a as usize; | ||
// info!("base = 0x{:x}", base); | ||
|
||
// copy LOAD segs into base | ||
for seg in segs { | ||
if seg.p_type == elf::abi::PT_LOAD { | ||
// info!("found LOAD: {:?}", seg); | ||
let data = file.segment_data(&seg).unwrap(); | ||
let vaddr = seg.p_vaddr as usize + base; | ||
unsafe { | ||
// info!("write to {:x} datalen = {:x}", vaddr, data.len()); | ||
let c = vaddr as *mut u8; | ||
for (i, d) in data.iter().enumerate() { | ||
*(c.add(i)) = *d; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// phdr | ||
let phdr = base + file.ehdr.e_phoff as usize; | ||
|
||
// get entry | ||
let entry = file.ehdr.e_entry as usize + base; | ||
// info!("entry = 0x{:x}", entry); | ||
|
||
// parse interpreter | ||
// #[allow(non_upper_case_globals)] | ||
// static static_libc_path: &str = "/lib/ld-musl-aarch64.so.1"; | ||
let mut interp_path = null::<c_char>(); | ||
for seg in file.segments().unwrap() { | ||
if seg.p_type == elf::abi::PT_INTERP { | ||
let data = file.segment_data(&seg).unwrap(); | ||
// interp_path = static_libc_path.as_ptr() as *const c_char; | ||
interp_path = data.as_ptr() as *const c_char; | ||
} | ||
} | ||
|
||
let sec = file.section_header_by_name(".got").unwrap().unwrap(); | ||
let addr = sec.sh_addr as usize + base; | ||
ax_println!("got vaddr = {:#X}", addr); | ||
|
||
// return Self | ||
let mut platform = Vec::new(); | ||
for c in b"aarch64" { | ||
platform.push(*c); | ||
} | ||
let ret = Self { | ||
base, | ||
entry, | ||
name, | ||
path, | ||
platform, | ||
rand: alloc::vec![1, 2], | ||
interp_path, | ||
phent: file.ehdr.e_phentsize as usize, | ||
phnum: file.ehdr.e_phnum as usize, | ||
phdr, | ||
}; | ||
|
||
let text_off = file | ||
.section_header_by_name(".text") | ||
.unwrap() | ||
.unwrap() | ||
.sh_offset; | ||
ax_println!( | ||
"loaded ELF in 0x{:x}, .text is 0x{:x}", | ||
ret.base, | ||
ret.base + text_off as usize | ||
); | ||
|
||
// unmap file | ||
sys_munmap(buf, bufsize); | ||
ax_println!("unmap ELF file in memory at {:p} len {:x}", buf, bufsize); | ||
|
||
ret | ||
} | ||
} | ||
|
||
pub fn ptr2vec(s: *const c_char) -> Vec<u8> { | ||
if s as usize == 0 { | ||
return alloc::vec![]; | ||
} | ||
let mut v = Vec::new(); | ||
unsafe { | ||
let mut i = 0; | ||
while *s.add(i) != 0 { | ||
v.push(*s.add(i) as u8); | ||
i += 1; | ||
} | ||
} | ||
v | ||
} | ||
|
||
pub fn vec_u8_to_str(v: &Vec<u8>) -> &str { | ||
if v.is_empty() { | ||
return ""; | ||
} | ||
let a = v.as_slice(); | ||
let s = core::str::from_utf8(a).unwrap(); | ||
s | ||
} |
Oops, something went wrong.