Skip to content

Commit f883144

Browse files
committed
dll-injection
1 parent 9e92db9 commit f883144

19 files changed

+478
-0
lines changed

dll_injection/README.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
## DLL INJECTION USING RUST
2+
3+
Hello nerds. So today we are going to see How you can write your own dll on various methods and perform dll injection using Rust.
4+
5+
**Note :> This is not an complete tutorial of teching how they works underneath but an actual implemeting methods to write your own custom dll's and perform DLL injection. Feel Free to google if you got stuck**
6+
7+
### Creating DLL Files.
8+
9+
create an new --lib crate and add the following [lib] to your cargo.toml file to compile the following code into dll's.
10+
11+
```
12+
[lib]
13+
crate-type = ["cdylib"]
14+
```
15+
16+
Lets write this following sample program and compile it !
17+
18+
```
19+
20+
use std::{ffi::CString, ptr::null_mut};
21+
use winapi::um::winuser::{MessageBoxA, MB_OK};
22+
23+
#[no_mangle]
24+
pub extern "stdcall" fn msg_frm_vx(){
25+
let msg = CString::new("Malware resources needs to be free and wide").expect("Failed");
26+
let cap = CString::new("Message From Vx-Underground").expect("Error cap");
27+
unsafe{
28+
MessageBoxA(null_mut(), msg.as_ptr(), cap.as_ptr(), MB_OK);
29+
}
30+
}
31+
32+
// stdcall in C
33+
#[no_mangle]
34+
pub extern "system" fn msg_frm_smukx(){
35+
let msg = CString::new("Custom DLL's are always Cool. Bye").expect("Failed");
36+
let cap = CString::new("Message From SMukx").expect("Error cap");
37+
unsafe{
38+
MessageBoxA(null_mut(), msg.as_ptr(), cap.as_ptr(), MB_OK);
39+
}
40+
}
41+
```
42+
43+
The raw code are posted in this repo. Feel free to check them out !
44+
45+
Ok . So This is just an simple dll that opens calc.exe using [CreateProcessA](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa) API. lets compile it .
46+
47+
Short Basics:
48+
49+
**Why we use no_mangle on functions**
50+
51+
- In Rust, the no_mangle is used to instruct the compiler to not [mangle](https://www.google.com/search?q=mangle&sourceid=chrome&ie=UTF-8) the symbol name of a function or item
52+
53+
Ok but for what shit do i need to use it ?
54+
55+
- When you create an rust library intended to be used as a DLL, you want other languages (like C or C++) to be able to call your rust functions. However, by default, rust applies its own mangling scheme, which would make the function names unrecognizable to the external language.
56+
57+
- so when you use no_mangle the symbol name of the function or item remains exactly as you wrote it in your rust code.
58+
59+
<br>
60+
61+
![alt text](images/image-2.png)
62+
63+
hook.dll file compiled in release folder.
64+
65+
lets go there and call the function using `rundll32.exe dllpath,func_name`
66+
67+
![alt text](images/image-3.png)
68+
69+
Woah... it works. so this is how dll works haa ..
70+
71+
ok so lets get into action and write an injector to inject dll into processes .
72+
73+
### Creating DLL Injector.
74+
75+
Many Hours Later...
76+
77+
<img src="images/image-5.png" width="350" height="200"> <br>
78+
79+
After Hours of solving bugs and erros, implementing new methods. I finally wrote an Proper Injector with ErrorHandling Capabilities.
80+
81+
![alt text](images/image-11.png)
82+
83+
<h4> The Injection code can be found Here :<a href="codelink"> Code </a></h3>
84+
85+
**Lets try to inject it !!**
86+
87+
![alt text](images/image-13.png)
88+
89+
![alt text](images/image-14.png)
90+
91+
Yes we have successfully injected our DLL .. But wait till now we saw how we can implement multiple functions and MessageBoxes. So what about some Program executions !!
92+
93+
### lets wrtie something interesing. Lets write an dll that opens actual Applications !
94+
95+
The game begins ...
96+
97+
Lets write an Simple dll that opens calc.exe using CreateProcessA WinAPI func.
98+
99+
```
100+
use std::ptr;
101+
use std::ffi::CString;
102+
use winapi::um::processthreadsapi::{STARTUPINFOA, PROCESS_INFORMATION, CreateProcessA};
103+
use winapi::um::winbase::CREATE_NEW_CONSOLE;
104+
105+
#[no_mangle]
106+
pub extern "stdcall" fn DllMain() {
107+
unsafe {
108+
let mut startup_info: STARTUPINFOA = std::mem::zeroed();
109+
startup_info.cb = std::mem::size_of::<STARTUPINFOA>() as u32;
110+
111+
let mut process_info: PROCESS_INFORMATION = std::mem::zeroed();
112+
113+
let application_name = CString::new("C:\\Windows\\System32\\calc.exe").expect("CString::new failed");
114+
115+
// Create process
116+
let success = CreateProcessA(
117+
ptr::null(),
118+
application_name.as_ptr() as *mut i8,
119+
ptr::null_mut(),
120+
ptr::null_mut(),
121+
false as i32,
122+
CREATE_NEW_CONSOLE,
123+
ptr::null_mut(),
124+
ptr::null(),
125+
&mut startup_info,
126+
&mut process_info,
127+
);
128+
129+
if success.is_null() {
130+
println!("Failed to open Calculator !");
131+
return
132+
}
133+
}
134+
}
135+
```
136+
137+
Calc.exe code can be found Here : [Code]()
138+
139+
Lets compile and see if its works !
140+
141+
![alt text](images/image-6.png)
142+
143+
It works but i made a mistakes. when you run this dll . the calculator opens up multiple times becasue i didnt close handle for the Process . so lets rewrite the hook.dll that opens the calc.exe
144+
145+
When i tried to fix it guess what! i fuc*ed it up :()
146+
147+
Insted of fixing it , I buffed that error . It executes 2 calc at the time : | .
148+
149+
![alt text](images/image-7.png)
150+
151+
152+
And some hours later ...
153+
154+
<img src="images/image-12.png" height="200" width="350"/> <br>
155+
156+
157+
![alt text](images/image-8.png)
158+
159+
**Yayy.. I Fixed it !! + Found one Golden Gem**
160+
161+
<img src="images/image-9.png" height="200" width="250" /> <br>
162+
163+
164+
**How i Fixed it ?**
165+
166+
First i Closed the handle using CloseHandle and WaitForSignalObject API's But i dont know why it does'nt works!
167+
168+
So to properly handle the dll's. I used some events such as ATTACH and DETACH and by the process i Closed its threads and processes.
169+
170+
**The Golden Gem or Bug ?**
171+
172+
So when i execute my dll. i closed my notepad but noticed that still my notepad is running on the same PID !
173+
174+
I Tried to restart my Process Hacker but the notepad.exe is showing buy i already closed it .
175+
176+
when i detach my calc.exe manually , the process automatically closes it . Hmm thats interesting .. let me research more about it ;)
177+
178+
**Fixed calc.exe code can be found here [fixed_calc_dll.rs]()**
179+
180+
Thats it nerds .. now you can create and rock your own custom dll using Rust !
181+
182+
## Reflective DLL soon ...
183+
184+
Follow me at Twitter: [5mukx](https://twitter.com/5mukx)
185+
186+
187+
Credits and Resources :
188+
189+
https://doc.rust-lang.org/reference/linkage.html#:~:text=Static%20and%20dynamic%20C%20runtimes,runtimes%20for%20targets%20as%20appropriate
190+
191+
https://github.com/rust-lang/rfcs/blob/master/text/1510-cdylib.md#detailed-design
192+
193+
https://docs.rs/winapi/latest/winapi/
194+
195+
https://learn.microsoft.com/en-us/windows/win32/dlls/about-dynamic-link-libraries
196+
197+
https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll?view=msvc-170
198+
199+
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/mscs/implementing-dllmain
200+
201+

dll_injection/fixed_calc_dll.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use std::ffi::CString;
2+
use std::ptr::{null,null_mut};
3+
use winapi::shared::minwindef::DWORD;
4+
use winapi::um::handleapi::CloseHandle;
5+
use winapi::um::processthreadsapi::{STARTUPINFOA, PROCESS_INFORMATION, CreateProcessA};
6+
use winapi::um::synchapi::WaitForSingleObject;
7+
use winapi::um::winbase::{CREATE_NEW_CONSOLE, INFINITE};
8+
use winapi::um::libloaderapi::{FreeLibraryAndExitThread, GetModuleHandleA};
9+
10+
11+
#[no_mangle]
12+
13+
pub extern "stdcall" fn DllMain(_module: *mut u8, reason: DWORD, _reserved: *mut u8) -> bool {
14+
match reason {
15+
1 => {
16+
unsafe {
17+
let mut startup_info: STARTUPINFOA = std::mem::zeroed();
18+
startup_info.cb = std::mem::size_of::<STARTUPINFOA>() as u32;
19+
20+
let mut process_info: PROCESS_INFORMATION = std::mem::zeroed();
21+
22+
let application_name = CString::new("C:\\Windows\\System32\\calc.exe").expect("CString::new failed");
23+
24+
let success = CreateProcessA(
25+
null(),
26+
application_name.as_ptr() as *mut i8,
27+
null_mut(),
28+
null_mut(),
29+
false as i32,
30+
CREATE_NEW_CONSOLE,
31+
null_mut(),
32+
null(),
33+
&mut startup_info,
34+
&mut process_info,
35+
);
36+
37+
if success == 0 {
38+
println!("Failed to open Calculator !");
39+
return false;
40+
}
41+
42+
WaitForSingleObject(process_info.hProcess, INFINITE);
43+
44+
CloseHandle(process_info.hProcess);
45+
CloseHandle(process_info.hThread);
46+
47+
let module_handle = GetModuleHandleA(null());
48+
FreeLibraryAndExitThread(module_handle, 0);
49+
50+
}
51+
},
52+
0 => {
53+
return false;
54+
},
55+
_ => {},
56+
}
57+
true
58+
}

dll_injection/images/image-1.png

145 KB
Loading

dll_injection/images/image-10.png

227 KB
Loading

dll_injection/images/image-11.png

151 KB
Loading

dll_injection/images/image-12.png

2.07 MB
Loading

dll_injection/images/image-13.png

197 KB
Loading

dll_injection/images/image-14.png

169 KB
Loading

dll_injection/images/image-2.png

98.5 KB
Loading

dll_injection/images/image-3.png

130 KB
Loading

dll_injection/images/image-4.png

611 KB
Loading

dll_injection/images/image-5.png

384 KB
Loading

dll_injection/images/image-6.png

540 KB
Loading

dll_injection/images/image-7.png

529 KB
Loading

dll_injection/images/image-8.png

159 KB
Loading

dll_injection/images/image-9.png

69.5 KB
Loading

dll_injection/images/image.png

145 KB
Loading

0 commit comments

Comments
 (0)