1#![no_std]
2#![no_main]
3
4extern crate alloc;
5
6#[macro_use]
7extern crate litcrypt2;
8use_litcrypt!();
9
10use alloc::vec::Vec;
11use data_nostd::{CloseHandle, CreateFileW, GetProcessHeap, GetStdHandle, HeapAlloc, HeapFree, ReadFile, WriteConsoleW, FILE_ATTRIBUTE_NORMAL, FILE_GENERIC_READ, HANDLE, HEAP_ZERO_MEMORY, OPEN_EXISTING, STD_OUTPUT_HANDLE};
12use core::ptr::{self, copy_nonoverlapping, null_mut};
13use core::ffi::c_void;
14use alloc::string::String;
15
16
17pub fn read_file(file_path: &str) -> Result<Vec<u8>, String>
25{
26 unsafe
27 {
28 let mut file_path: Vec<u16> = file_path.encode_utf16().collect();
29 file_path.push(0);
30
31 let handle: HANDLE = CreateFileW(
32 file_path.as_mut_ptr(),
33 FILE_GENERIC_READ,
34 0,
35 null_mut(),
36 OPEN_EXISTING,
37 FILE_ATTRIBUTE_NORMAL,
38 HANDLE::default(),
39 );
40
41 if handle.id == -1 {
42 return Err(lc!("[x] Error opening the file."));
43 }
44
45 let mut buffer_size: usize = 4096;
46 let process_heap = GetProcessHeap();
47 let mut file_buffer = HeapAlloc(process_heap, HEAP_ZERO_MEMORY, buffer_size);
48
49 if file_buffer.is_null()
50 {
51 CloseHandle(handle);
52 return Err(lc!("[x] Heap allocation failed"));
53 }
54
55 let mut bytes_read: u32 = 0;
56 let mut total_bytes_read: usize = 0;
57
58 loop
59 {
60 let result = ReadFile(
61 handle,
62 file_buffer.add(total_bytes_read),
63 4096,
64 &mut bytes_read,
65 null_mut(),
66 );
67
68 if result && bytes_read > 0
69 {
70 total_bytes_read += bytes_read as usize;
71
72 if total_bytes_read + 4096 > buffer_size
73 {
74 let new_buffer_size = buffer_size * 2;
75 let new_file_buffer = HeapAlloc(process_heap, HEAP_ZERO_MEMORY, new_buffer_size);
76
77 if new_file_buffer.is_null()
78 {
79 HeapFree(process_heap, 0, file_buffer as *mut c_void);
80 CloseHandle(handle);
81 return Err(lc!("[x] Heap allocation failed"));
82 }
83
84 copy_nonoverlapping(file_buffer as *mut u8, new_file_buffer as *mut u8, total_bytes_read);
85
86 HeapFree(process_heap, 0, file_buffer);
87 file_buffer = new_file_buffer;
88 buffer_size = new_buffer_size;
89 }
90
91 } else {
92 break;
93 }
94 }
95
96 CloseHandle(handle);
97
98 if total_bytes_read == 0 {
99 return Err(lc!("[x] Error reading the file."));
100 }
101
102 let new_file_buffer = HeapAlloc(process_heap, HEAP_ZERO_MEMORY, total_bytes_read);
103
104 if new_file_buffer.is_null() {
105 return Ok(Vec::from_raw_parts(file_buffer as *mut u8, total_bytes_read, total_bytes_read));
106 }
107
108 copy_nonoverlapping(file_buffer as *mut u8, new_file_buffer as *mut u8, total_bytes_read);
109 HeapFree(process_heap, 0, file_buffer);
110
111 Ok(Vec::from_raw_parts(new_file_buffer as *mut u8, total_bytes_read, total_bytes_read))
112 }
113}
114
115
116#[macro_export]
134macro_rules!println {
135 ($($arg:tt)*) => {
136 let mut string = String::new();
137 let _ = write!(string, $($arg)*);
138 let _ = write!(string, "\n");
139 let mut utf16: alloc::vec::Vec<u16> = string.encode_utf16().collect();
140 utf16.push(0);
141
142 $crate::print_string(utf16);
143 };
144}
145
146pub fn print_string(utf16_str: Vec<u16>) {
148 unsafe {
149 let h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
150 if !h_stdout.is_null() {
151 WriteConsoleW(
152 h_stdout,
153 utf16_str.as_ptr(),
154 utf16_str.len() as u32,
155 ptr::null_mut(),
156 ptr::null_mut(),
157 );
158 }
159 }
160}