Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2c65cc3

Browse files
committedDec 13, 2024
Indirect Syscall
Indirect system calls using Single stub with runtime SSN resolving for windows.
1 parent 079b8c2 commit 2c65cc3

File tree

16 files changed

+2312
-0
lines changed

16 files changed

+2312
-0
lines changed
 

‎syscalls/indirect_syscalls/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "indirect_syscalls"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
winapi = { version = "0.3.9", features = ["wtsapi32","winuser","setupapi","dbghelp","wlanapi","winnls","wincon","fileapi","sysinfoapi", "fibersapi","debugapi","winerror", "wininet" , "winhttp" ,"synchapi","securitybaseapi","wincrypt","psapi", "tlhelp32", "heapapi","shellapi", "memoryapi", "processthreadsapi", "errhandlingapi", "winbase", "handleapi", "synchapi"] }
8+
ntapi = "0.4.1"
9+
# Add the following for systemcall stub !
10+
# rust_syscalls = {path = "..\rust_syscalls\\src", features = ["_INDIRECT_"]}
11+
12+
rust_syscalls = {path = "./rust_syscalls/", features = ["_INDIRECT_"]}

‎syscalls/indirect_syscalls/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## Indirect Syscall
2+
3+
Implementing indirect system calls using Single stub with runtime SSN resolving for windows.
4+
5+
![indiect_syscall](./indirect_syscall.png)
6+
7+
8+
## Credits
9+
* https://github.com/janoglezcampos/rust_syscalls.git
10+
* https://redops.at/en/blog/direct-syscalls-vs-indirect-syscalls
11+
* https://www.ired.team/offensive-security/code-injection-process-injection/ntcreatesection-+-ntmapviewofsection-code-injection
12+
13+
by @5mukx
Loading
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "rust_syscalls"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Yxel <https://github.com/janoglezcampos>"]
6+
repository = "https://github.com/janoglezcampos/rust_syscalls"
7+
8+
[features]
9+
_INDIRECT_ = []
10+
_DIRECT_ = []
11+
12+
[dependencies]
13+
winapi = {version = "0.3.9", features = ["ntdef", "winnt"]}
14+
ntapi = "0.4.0"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[cfg(all(feature = "_DIRECT_", feature = "_INDIRECT_"))]
2+
compile_error!("\t [!] RUST_SYSCALLS ERROR: feature \"_DIRECT_\" and feature \"_INDIRECT_\" cannot be enabled at the same time");
3+
4+
#[cfg(not(any(feature = "_DIRECT_", feature = "_INDIRECT_")))]
5+
compile_error!("\t [!] RUST_SYSCALLS ERROR: feature \"_DIRECT_\" or feature \"_INDIRECT_\" must be enabled");
6+
7+
pub mod syscall;
8+
pub mod syscall_resolve;
9+
pub mod obf;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#[macro_export]
2+
macro_rules! obf {
3+
($s:expr) => {{
4+
static HASH: u32 = $crate::obf::dbj2_hash_str($s);
5+
HASH
6+
}
7+
};
8+
}
9+
10+
pub const fn dbj2_hash_str(arg : &str) -> u32
11+
{
12+
dbj2_hash(arg.as_bytes())
13+
}
14+
15+
pub const fn dbj2_hash(buffer : &[u8]) -> u32
16+
{
17+
let mut hsh : u32 = 5381;
18+
let mut iter: usize = 0;
19+
let mut cur : u8;
20+
21+
while iter < buffer.len()
22+
{
23+
cur = buffer[iter];
24+
if cur == 0 {
25+
iter += 1;
26+
continue;
27+
}
28+
if cur >= ('a' as u8) {
29+
cur -= 0x20;
30+
}
31+
hsh = ((hsh << 5).wrapping_add(hsh)) + cur as u32;
32+
iter += 1;
33+
};
34+
return hsh;
35+
}
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
#[allow(unused_imports)]
2+
use std::arch::global_asm;
3+
4+
#[cfg(all(feature = "_DIRECT_", not(feature = "_INDIRECT_")))]
5+
#[macro_export]
6+
macro_rules! syscall {
7+
($function_name:expr, $($y:expr), +) => {
8+
{
9+
let ssn = $crate::syscall_resolve::get_ssn($crate::obf!($function_name));
10+
let mut cnt:u32 = 0;
11+
$(
12+
let _ = $y;
13+
cnt += 1;
14+
)+
15+
$crate::syscall::do_syscall(ssn, cnt, $($y), +)
16+
}}
17+
}
18+
19+
#[cfg(all(feature = "_INDIRECT_", not(feature = "_DIRECT_")))]
20+
#[macro_export]
21+
macro_rules! syscall {
22+
($function_name:expr, $($y:expr), +) => {
23+
{
24+
let (ssn, addr) = $crate::syscall_resolve::get_ssn($crate::obf!($function_name));
25+
let mut cnt:u32 = 0;
26+
$(
27+
let _ = $y;
28+
cnt += 1;
29+
)+
30+
$crate::syscall::do_syscall(ssn, addr, cnt, $($y), +)
31+
}}
32+
}
33+
34+
#[cfg(target_arch = "x86_64")]
35+
#[cfg(all(feature = "_DIRECT_", not(feature = "_INDIRECT_")))]
36+
global_asm!("
37+
.global do_syscall
38+
39+
.section .text
40+
41+
do_syscall:
42+
43+
mov [rsp - 0x8], rsi
44+
mov [rsp - 0x10], rdi
45+
46+
mov eax, ecx
47+
mov rcx, rdx
48+
49+
mov r10, r8
50+
mov rdx, r9
51+
52+
mov r8, [rsp + 0x28]
53+
mov r9, [rsp + 0x30]
54+
55+
sub rcx, 0x4
56+
jle skip
57+
58+
lea rsi, [rsp + 0x38]
59+
lea rdi, [rsp + 0x28]
60+
61+
rep movsq
62+
skip:
63+
syscall
64+
65+
mov rsi, [rsp - 0x8]
66+
mov rdi, [rsp - 0x10]
67+
68+
ret
69+
");
70+
71+
#[cfg(target_arch = "x86_64")]
72+
#[cfg(all(feature = "_INDIRECT_", not(feature = "_DIRECT_")))]
73+
global_asm!("
74+
.global do_syscall
75+
76+
.section .text
77+
78+
do_syscall:
79+
mov [rsp - 0x8], rsi
80+
mov [rsp - 0x10], rdi
81+
mov [rsp - 0x18], r12
82+
83+
mov eax, ecx
84+
mov r12, rdx
85+
mov rcx, r8
86+
87+
mov r10, r9
88+
mov rdx, [rsp + 0x28]
89+
mov r8, [rsp + 0x30]
90+
mov r9, [rsp + 0x38]
91+
92+
sub rcx, 0x4
93+
jle skip
94+
95+
lea rsi, [rsp + 0x40]
96+
lea rdi, [rsp + 0x28]
97+
98+
rep movsq
99+
skip:
100+
101+
mov rcx, r12
102+
103+
mov rsi, [rsp - 0x8]
104+
mov rdi, [rsp - 0x10]
105+
mov r12, [rsp - 0x18]
106+
107+
jmp rcx
108+
");
109+
110+
#[cfg(target_arch = "x86")]
111+
#[cfg(all(feature = "_DIRECT_", not(feature = "_INDIRECT_")))]
112+
global_asm!("
113+
.global _do_syscall
114+
115+
.section .text
116+
117+
_do_syscall:
118+
mov [esp - 0x04], esi
119+
mov [esp - 0x08], edi
120+
121+
mov eax, [esp + 0x04]
122+
mov ecx, [esp + 0x08]
123+
124+
lea esi, [esp + 0x0C]
125+
lea edi, [esp + 0x04]
126+
127+
rep movsd
128+
129+
mov esi, [esp - 0x04]
130+
mov edi, [esp - 0x08]
131+
132+
mov edx, fs:[0xc0]
133+
test edx, edx
134+
je native
135+
136+
call edx
137+
ret
138+
139+
native:
140+
call sysenter
141+
ret
142+
143+
sysenter:
144+
mov edx,esp
145+
sysenter
146+
147+
");
148+
149+
#[cfg(target_arch = "x86")]
150+
#[cfg(all(feature = "_INDIRECT_", not(feature = "_DIRECT_")))]
151+
global_asm!("
152+
.global _do_syscall
153+
154+
.section .text
155+
156+
_do_syscall:
157+
mov ecx, [esp + 0x0C]
158+
not ecx
159+
add ecx, 1
160+
lea edx, [esp + ecx * 4]
161+
162+
mov ecx, [esp]
163+
mov [edx], ecx
164+
165+
mov [edx - 0x04], esi
166+
mov [edx - 0x08], edi
167+
168+
mov eax, [esp + 0x04]
169+
mov ecx, [esp + 0x0C]
170+
171+
lea esi, [esp + 0x10]
172+
lea edi, [edx + 0x04]
173+
174+
rep movsd
175+
176+
mov esi, [edx - 0x04]
177+
mov edi, [edx - 0x08]
178+
mov ecx, [esp + 0x08]
179+
180+
mov esp, edx
181+
182+
mov edx, fs:[0xC0]
183+
test edx, edx
184+
je native
185+
186+
mov edx, fs:[0xC0]
187+
jmp ecx
188+
189+
native:
190+
mov edx, ecx
191+
sub edx, 0x05
192+
push edx
193+
mov edx, esp
194+
jmp ecx
195+
ret
196+
197+
is_wow64:
198+
");
199+
200+
201+
202+
#[cfg(target_arch = "x86_64")]
203+
#[cfg(all(feature = "_DIRECT_", not(feature = "_INDIRECT_")))]
204+
extern "C" {
205+
pub fn do_syscall(
206+
ssn: u16,
207+
n_args: u32,
208+
...
209+
) -> i32;
210+
}
211+
212+
#[cfg(target_arch = "x86_64")]
213+
#[cfg(all(feature = "_INDIRECT_", not(feature = "_DIRECT_")))]
214+
extern "C" {
215+
pub fn do_syscall(
216+
ssn: u16,
217+
syscall_addr: u64,
218+
n_args: u32,
219+
...
220+
) -> i32;
221+
}
222+
223+
#[cfg(target_arch = "x86")]
224+
#[cfg(all(feature = "_DIRECT_", not(feature = "_INDIRECT_")))]
225+
extern "C" {
226+
pub fn do_syscall(
227+
ssn: u16,
228+
n_args: u32,
229+
...
230+
) -> i32;
231+
}
232+
233+
#[cfg(target_arch = "x86")]
234+
#[cfg(all(feature = "_INDIRECT_", not(feature = "_DIRECT_")))]
235+
extern "C" {
236+
pub fn do_syscall(
237+
ssn: u16,
238+
n_args: u32,
239+
syscall_addr: u32,
240+
...
241+
) -> i32;
242+
}

0 commit comments

Comments
 (0)