Giter VIP home page Giter VIP logo

rust_syscalls's Introduction

RUST_SYSCALLS

Single stub direct and indirect syscalling with runtime SSN resolving for windows.


Features:

  • One single line for all your syscalls
  • Function name hashing at compilation time
  • Direct or indirect sycalls
  • x86_64, WOW64 and x86 native support
  • Designed to allow the implementation of custom SSN fetching methods (check the end of this readme for more info)

How to use:

  1. Add the git repository / local path to the library to your dependencies:

    rust_syscalls = {git = "https://github.com/janoglezcampos/rust_syscalls"}

    or

    rust_syscalls = {path = <path to library folder>}

  2. Choose direct or indirect method by setting _DIRECT_ or _INDIRECT_ as a feature:

    rust_syscalls = {path = <path to library folder>}, features = ["_INDIRECT_"]}

  3. Import

    use rust_syscalls::syscall;

  4. Syscall:

    NTSTATUS status = syscall!("NtClose", handle);


Example:

    #![allow(non_snake_case)]
    use ntapi::ntapi_base::CLIENT_ID;
    use rust_syscalls::syscall;

    use winapi::shared::ntdef::{OBJECT_ATTRIBUTES, HANDLE, NULL, NTSTATUS, PVOID};
    use winapi::um::winnt::{PROCESS_VM_WRITE, PROCESS_VM_READ, MEMORY_BASIC_INFORMATION};
    use std::mem::size_of;
    
    fn main(){
        let pid             : u64      = 3268; //Process PID
        let currentProcess  : HANDLE = -1isize as _;
        let mem_info_len    : usize = size_of::<MEMORY_BASIC_INFORMATION>() as _;

        let mut handle      : HANDLE   = NULL;
        let mut status      : NTSTATUS;
    
        let mem_info: MEMORY_BASIC_INFORMATION = MEMORY_BASIC_INFORMATION {
            BaseAddress: NULL,
            AllocationBase: NULL,
            AllocationProtect: 0,
            RegionSize: 0,
            State: 0,
            Protect: 0,
            Type: 0,
        };

        let oa : OBJECT_ATTRIBUTES = OBJECT_ATTRIBUTES {
            Length: size_of::<OBJECT_ATTRIBUTES>() as _,
            RootDirectory: NULL,
            ObjectName: NULL as _,
            Attributes: 0,
            SecurityDescriptor: NULL,
            SecurityQualityOfService: NULL
        };

        let cid : CLIENT_ID = CLIENT_ID {
            UniqueProcess: pid as _,
            UniqueThread: 0 as _
        };

        unsafe {
            status = syscall!("NtOpenProcess", &mut handle, PROCESS_VM_WRITE | PROCESS_VM_READ, &oa, &cid);
        }
        
        println!("\n\t[-] NtOpenProcess status: {:#02X}", status);

        if status != 0 {
            return;
        }

        unsafe {
            status = syscall!("NtQueryVirtualMemory", currentProcess, &pid, 0, &mem_info, mem_info_len, NULL as PVOID);
        }
        
        println!("\n\t[-] NtQueryVirtualMemory status: {:#02X}", status);
        
        if status != 0 {
            return;
        }

        println!("\n\t[-] Protect value: {:#02X}\n\t", mem_info.Protect);

        unsafe {
            status = syscall!("NtClose", handle);
        }
        
        println!("\t[-] NtClose       status: {:#02X}", status);
    }

Implementing new SSN and syscall addresses runtime resolving methods:

All the code required to do the SSN and address fetching is included in the file src\syscall_resolve.rs.

There is one core function used to retrieve the values called get_ssn, with 4 implementations, where the received argument is the result of calling crate::obf!(\<your function name\>), and the return values are the ssn (u16), and, in case of indirect syscalling, the address of the syscall/sysenter instruction that you want to use.

  • x86_64 direct:

    fn get_ssn(hash: u32) -> (u16);

  • x86_64 indirect:

    fn get_ssn(hash: u32) -> (u16, u64);

  • x86 direct:

    fn get_ssn(hash: u32) -> (u16);

  • x86 indirect:

    fn get_ssn(hash: u32) -> (u16, u32);

Just reimplement this functions with your desired fetching method.


Thanks to SysWhispers3 for being a strong pilar on the development of this library

rust_syscalls's People

Contributors

frereit avatar janoglezcampos avatar sh0ckfr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rust_syscalls's Issues

Hi I have a question

Hello, I have a question. I have written code to read the LDR through syscalls. However, when I use this code in a library, I encounter the error C0000005. Interestingly, the same code works perfectly fine when used locally. I can't figure out why this is happening.
code

main

    let pid = 16676;
    let  a  = unsafe { OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid) }.unwrap();
    println!("aaaaaa");
    // let p = unsafe { get_peb(a) }.unwrap();
    // let e = unsafe  {testt(a).unwrap()};
    // let mut ldr = unsafe { get_all_ldr_module(a) }.unwrap();
    let mut ldr = unsafe { get_module_list_address(a) };

get_module_list_address

pub unsafe fn get_module_list_address(hProcess:HANDLE) -> PVOID {
    let peb_addr = get_peb(hProcess).unwrap();


    let mut ldr = peb_addr.byte_add(0x18) as PVOID;

    let pvoid_len = size_of::<PVOID>();
    println!("read lsass peb ldr{:?}",peb_addr);
    let mut ldr_entry_address: PVOID = null_mut();
    let mut NumberOfBytesRead: PVOID = null_mut();

    let success = syscall!("NtReadVirtualMemory",hProcess,ldr,&mut ldr_entry_address as *mut PVOID,pvoid_len,0);
    if success!=0 {
        println!("{:x}",success);

        panic!()
    }

    let module_list_pointer = ldr_entry_address as *mut LdrData;
    let inmemorymodulelist  = ldr_entry_address.offset(0x20) as PVOID;
    let mut  module_list_addres: PVOID = null_mut();
    let success=  syscall!("NtReadVirtualMemory",hProcess,inmemorymodulelist,&mut module_list_addres as *mut PVOID,pvoid_len,0);
    if success!=0 {
        println!("{:x}",success);

        panic!()
    }

    return module_list_addres;
}

get_peb

pub unsafe fn get_peb(hPorcess:HANDLE) -> Option<*mut PEB> {
    let peb:*const u8;

    if hPorcess.0 ==0 {
        unsafe {
            asm!(
            "mov {0}, gs:0x60",
            out(reg) peb,
            options(nostack, nomem, preserves_flags),
            );
        }
        println!("self peb");
        return Some(peb as *mut  PEB);
    }

    let p = PROCESS_BASIC_INFORMATION::default();
    let process_information: PVOID = std::mem::transmute(&p);

    let success = syscall!("NtQueryInformationProcess",hPorcess,0,process_information,size_of::<PROCESS_BASIC_INFORMATION>() as u32,0 as *mut  u32);
    if success!=0 {
        println!("1 {}",success);

    }
    let pbi:*mut PROCESS_BASIC_INFORMATION;
    pbi = std::mem::transmute(process_information);
    let pbi = *pbi;
    return Some(pbi.PebBaseAddress as *mut PEB);



Issue with ntapi module imports

When trying to import the project there is an issue with the ntapi dependency where the modules being called could not be found despite existing in the source file.

`error[E0432]: unresolved import `ntapi::ntldr`
 --> rust_syscalls/src/syscall_resolve.rs:6:12
  |
6 | use ntapi::ntldr::PLDR_DATA_TABLE_ENTRY;
  |            ^^^^^ could not find `ntldr` in `ntapi`

error[E0432]: unresolved import `ntapi::ntpebteb`
 --> rust_syscalls/src/syscall_resolve.rs:7:12
  |
7 | use ntapi::ntpebteb::{PPEB, TEB};
  |            ^^^^^^^^ could not find `ntpebteb` in `ntapi`

error[E0432]: unresolved import `ntapi::ntpsapi`
 --> rust_syscalls/src/syscall_resolve.rs:8:12
  |
8 | use ntapi::ntpsapi::PPEB_LDR_DATA;
  |            ^^^^^^^ could not find `ntpsapi` in `ntapi`

error[E0433]: failed to resolve: could not find `shared` in `winapi`
  --> rust_syscalls/src/syscall_resolve.rs:11:13
   |
11 | use winapi::shared::minwindef::{PUSHORT, PWORD};
   |             ^^^^^^ could not find `shared` in `winapi`

error[E0433]: failed to resolve: could not find `shared` in `winapi`
  --> rust_syscalls/src/syscall_resolve.rs:12:13
   |
12 | use winapi::shared::ntdef::{NULL, PLIST_ENTRY, PUCHAR, PVOID, ULONG};
   |             ^^^^^^ could not find `shared` in `winapi`

error[E0433]: failed to resolve: could not find `um` in `winapi`
  --> rust_syscalls/src/syscall_resolve.rs:13:13
   |
13 | use winapi::um::winnt::{
   |             ^^ could not find `um` in `winapi`

error[E0433]: failed to resolve: could not find `um` in `winapi`
  --> rust_syscalls/src/syscall_resolve.rs:53:17
   |
53 |     use winapi::um::winnt::NT_TIB;
   |                 ^^ could not find `um` in `winapi`

error[E0432]: unresolved import `ntapi::FIELD_OFFSET`
 --> rust_syscalls/src/syscall_resolve.rs:9:5
  |
9 | use ntapi::FIELD_OFFSET;
  |     ^^^^^^^^^^^^^^^^^^^ no `FIELD_OFFSET` in the root

error: cannot determine resolution for the macro `FIELD_OFFSET`
  --> rust_syscalls/src/syscall_resolve.rs:54:22
   |
54 |     let teb_offset = FIELD_OFFSET!(NT_TIB, _Self) as u32;
   |                      ^^^^^^^^^^^^
   |
   = note: import resolution is stuck, try simplifying macro imports

Help request : syscall with NtCreateThreadEx

Hello mate,

I am using your repo for different projects. In my RustPacker, I am writing a template that uses rust_syscalls for shellcode injection. I successfully ported all my NTAPI calls, except NtCreateThreadEx.
I tried the following:

let mut thread_handle : *mut c_void = null_mut();
let handle = process_handle as *mut c_void;
let write_thread = syscall!("NtCreateThreadEx", &mut thread_handle, GENERIC_ALL, null_mut(), handle, allocstart, null_mut(), 0, 0, 0, 0, null_mut());

but this, gives the folllowing error:
image

However, the normal NTAPI call with the same arguments compiles and works when executed:

let write_thread = NtCreateThreadEx(&mut thread_handle, GENERIC_ALL, null_mut(), handle, allocstart, null_mut(), 0, 0, 0, 0, null_mut());

Did you try to use rust_syscalls with the NtCreateThreadEx NTAPI call? More generally, how do you convert the NTAPI call arguments to be compatible with your project ?

All the best !
Nariod

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.