[fix] fix race condition.
This commit is contained in:
@@ -7,7 +7,7 @@ edition = "2024"
|
|||||||
dynasmrt = "4.0.1"
|
dynasmrt = "4.0.1"
|
||||||
iced-x86 = { version = "1.21.0", features = ["code_asm"] }
|
iced-x86 = { version = "1.21.0", features = ["code_asm"] }
|
||||||
libc = "0.2.177"
|
libc = "0.2.177"
|
||||||
nix = { version = "0.30.1", features = ["ptrace", "uio"] }
|
nix = { version = "0.30.1", features = ["ptrace", "uio", "signal"] }
|
||||||
ctor = "0.6.0"
|
ctor = "0.6.0"
|
||||||
libloading = "0.8.9"
|
libloading = "0.8.9"
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
mod helper;
|
mod helper;
|
||||||
|
|
||||||
use nix::sys::ptrace;
|
use nix::sys::ptrace;
|
||||||
|
use nix::sys::signal::{Signal, kill};
|
||||||
use nix::unistd::Pid;
|
use nix::unistd::Pid;
|
||||||
use std::arch::asm;
|
use std::arch::asm;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
|
||||||
use helper::*;
|
use helper::*;
|
||||||
use iced_x86::code_asm::{eax, r8, r9, r10, rax, rdi, rdx, rsi, rcx, rsp, rbp};
|
use iced_x86::code_asm::{eax, r8, r9, r10, rax, rbp, rcx, rdi, rdx, rsi, rsp};
|
||||||
use libc::{RTLD_NEXT, c_void, dlsym};
|
use libc::{RTLD_NEXT, c_void, dlsym};
|
||||||
use libc::{ptrace, user_regs_struct};
|
use libc::{ptrace, user_regs_struct};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -103,7 +104,7 @@ fn inject2(pid: Pid, seg_rw: (u64, u64)) -> Result<(), Box<dyn std::error::Error
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject3(pid: Pid, seg_rw: (u64, u64)) -> Result<(), Box<dyn std::error::Error>> // thread inject
|
fn inject3(pid: Pid, seg_rw: (u64, u64)) -> Result<i32, Box<dyn std::error::Error>> // thread inject
|
||||||
{
|
{
|
||||||
let regs = ptrace::getregs(pid)?;
|
let regs = ptrace::getregs(pid)?;
|
||||||
// Alloc rwx memory
|
// Alloc rwx memory
|
||||||
@@ -150,7 +151,11 @@ fn inject3(pid: Pid, seg_rw: (u64, u64)) -> Result<(), Box<dyn std::error::Error
|
|||||||
);
|
);
|
||||||
|
|
||||||
let injected_data = "[%d] I am the injected thread, I am running... \r\n";
|
let injected_data = "[%d] I am the injected thread, I am running... \r\n";
|
||||||
write_memory_vm(pid, page_addr + 0x200, &CString::new(injected_data).unwrap().as_bytes_with_nul())?;
|
write_memory_vm(
|
||||||
|
pid,
|
||||||
|
page_addr + 0x200,
|
||||||
|
&CString::new(injected_data).unwrap().as_bytes_with_nul(),
|
||||||
|
)?;
|
||||||
write_memory_vm(pid, page_addr + 0x300, &1i64.to_le_bytes())?;
|
write_memory_vm(pid, page_addr + 0x300, &1i64.to_le_bytes())?;
|
||||||
write_memory_vm(pid, page_addr + 0x308, &0u64.to_le_bytes())?;
|
write_memory_vm(pid, page_addr + 0x308, &0u64.to_le_bytes())?;
|
||||||
|
|
||||||
@@ -184,8 +189,8 @@ fn inject3(pid: Pid, seg_rw: (u64, u64)) -> Result<(), Box<dyn std::error::Error
|
|||||||
println!("{GREEN}[trace]{RESET} write payload to {:#016x}", page_addr);
|
println!("{GREEN}[trace]{RESET} write payload to {:#016x}", page_addr);
|
||||||
|
|
||||||
// Start Trigger
|
// Start Trigger
|
||||||
let regs = ptrace::getregs(pid)?;
|
// let regs = ptrace::getregs(pid)?;
|
||||||
// ptrace::setregs(pid, regs)?;
|
ptrace::setregs(pid, regs)?;
|
||||||
|
|
||||||
let injected_trigger = assemble(regs.rip as u64, |asm| {
|
let injected_trigger = assemble(regs.rip as u64, |asm| {
|
||||||
asm.mov(rax, 56u64)?; // Syscall 56 (clone)
|
asm.mov(rax, 56u64)?; // Syscall 56 (clone)
|
||||||
@@ -221,9 +226,34 @@ fn inject3(pid: Pid, seg_rw: (u64, u64)) -> Result<(), Box<dyn std::error::Error
|
|||||||
wait(pid);
|
wait(pid);
|
||||||
|
|
||||||
let regs = ptrace::getregs(pid)?;
|
let regs = ptrace::getregs(pid)?;
|
||||||
|
let pid_new_thread = Pid::from_raw(regs.rax as i32);
|
||||||
println!("{GREEN}[trace]{RESET} int3 at {:#016x}", regs.rip);
|
println!("{GREEN}[trace]{RESET} int3 at {:#016x}", regs.rip);
|
||||||
|
println!(
|
||||||
|
"{GREEN}[trace]{RESET} new thread is {}, which will be suspend.",
|
||||||
|
pid_new_thread
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
ptrace::attach(pid_new_thread)?;
|
||||||
|
wait(pid_new_thread);
|
||||||
|
println!("{GREEN}[trace]{RESET} attached new thread.");
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let regs = ptrace::getregs(pid_new_thread)?;
|
||||||
|
println!(
|
||||||
|
"{GREEN}[trace]{RESET} rip in new thread is {:#016x}.",
|
||||||
|
regs.rip
|
||||||
|
);
|
||||||
|
|
||||||
|
if regs.rip >= page_addr as u64 && regs.rip < (page_addr + 0x1000) as u64 {
|
||||||
|
println!("{GREEN}[trace]{RESET} rip in new thread return to inject payload.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrace::step(pid_new_thread, None)?;
|
||||||
|
wait(pid_new_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(pid_new_thread.as_raw())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@@ -262,22 +292,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
ptrace::step(pid, None)?;
|
ptrace::step(pid, None)?;
|
||||||
wait(pid);
|
wait(pid);
|
||||||
|
|
||||||
// ↓ Old behavior, but maybe the process stay in their libraries forever ?
|
|
||||||
|
|
||||||
// loop{
|
|
||||||
// // Single-stepping, so that RIP returns to the user space of the process itself,
|
|
||||||
// // rather than in some other library
|
|
||||||
// let regs = ptrace::getregs(pid)?;
|
|
||||||
// if is_address_in_range(regs.rip, &lines)
|
|
||||||
// {
|
|
||||||
// println!("{GREEN}[trace]{RESET} Address: {:#016x}", regs.rip);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// println!("{GREEN}[trace]{RESET} Skipped: {:#016x}", regs.rip);
|
|
||||||
// ptrace::step(pid, None)?;
|
|
||||||
// waitpid(pid, None)?;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Save context
|
// Save context
|
||||||
let regs = ptrace::getregs(pid)?; // Save current registers
|
let regs = ptrace::getregs(pid)?; // Save current registers
|
||||||
let buffer = read_memory_vm(pid, seg_x.0 as usize, 4096)?; // Save current memory context
|
let buffer = read_memory_vm(pid, seg_x.0 as usize, 4096)?; // Save current memory context
|
||||||
@@ -296,7 +310,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
// Do inject here
|
// Do inject here
|
||||||
|
|
||||||
inject3(pid, seg_rw)?;
|
let c = inject3(pid, seg_rw)?;
|
||||||
|
|
||||||
// End inject logics
|
// End inject logics
|
||||||
|
|
||||||
@@ -306,6 +320,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
write_memory_vm(pid, seg_rw.0 as usize, &buffer_rw)?;
|
write_memory_vm(pid, seg_rw.0 as usize, &buffer_rw)?;
|
||||||
|
|
||||||
ptrace::detach(pid, None)?;
|
ptrace::detach(pid, None)?;
|
||||||
|
ptrace::detach(Pid::from_raw(c), None)?;
|
||||||
|
|
||||||
|
let mut input = String::new();
|
||||||
|
std::io::stdin()
|
||||||
|
.read_line(&mut input)
|
||||||
|
.expect("Failed to read line");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -4,6 +4,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
pid_t pid = getpid();
|
pid_t pid = getpid();
|
||||||
@@ -11,6 +12,7 @@ int main()
|
|||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
sleep(0);
|
usleep(1000 * 300);
|
||||||
|
write(1, ".", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user