File size: 9,799 Bytes
9425aed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | /* Zero-libc Windows power event handler
* Manual PEB walk for user32/powrprof, no windows.h
* Suspend -> sov_worm_checkpoint, Resume -> sov_worm_restore
* Battery < 20% -> reduce batch via sov_janet_set
*/
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned long ULONG;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;
typedef HANDLE HINSTANCE;
typedef HANDLE HDEVNOTIFY;
typedef uint32_t DWORD;
typedef uint64_t ULONG_PTR;
typedef ULONG_PTR WPARAM;
typedef int64_t LPARAM;
typedef int32_t LRESULT;
typedef uint32_t UINT;
typedef uint16_t WORD;
typedef int32_t INT;
typedef long LONG;
typedef int BOOL;
typedef const char* LPCSTR;
typedef PVOID HMENU;
typedef PVOID LPMSG;
typedef PVOID LPVOID;
typedef PVOID LPDWORD;
typedef int (*LPTHREAD_START_ROUTINE)(PVOID);
typedef ULONG_PTR SIZE_T;
typedef struct { DWORD Data1; WORD Data2; WORD Data3; uint8_t Data4[8]; } GUID, *LPCGUID;
typedef struct { struct _LE* Flink; struct _LE* Blink; } LIST_ENTRY, *PLIST_ENTRY;
typedef struct { uint16_t Length; uint16_t MaximumLength; wchar_t* Buffer; } UNICODE_STRING;
typedef struct {
LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitOrderLinks;
PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage;
UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct { ULONG Length; BOOL Initialized; HANDLE SsHandle;
LIST_ENTRY InLoadOrder; LIST_ENTRY InMemoryOrder; } PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct { uint8_t r1[2]; uint8_t BeingDebugged; uint8_t r2[1]; PVOID r3[2]; PPEB_LDR_DATA Ldr; } PEB, *PPEB;
typedef struct { WORD e_magic; WORD r[28]; LONG e_lfanew; } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct { WORD Machine; WORD NumberOfSections; DWORD r[3]; WORD SizeOfOptionalHeader; WORD Chars; } IMAGE_FILE_HEADER;
typedef struct { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY;
typedef struct { WORD Magic; uint8_t r1[6]; DWORD r2[7]; ULONG_PTR r3; DWORD r4[4];
WORD r5[6]; DWORD r6[4]; ULONG_PTR r7[4]; DWORD r8[2]; IMAGE_DATA_DIRECTORY DataDir[16]; } IMAGE_OPTIONAL_HEADER64;
typedef struct { DWORD Signature; IMAGE_FILE_HEADER FileHdr; IMAGE_OPTIONAL_HEADER64 OptHdr; } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
typedef struct { DWORD r[4]; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames;
DWORD AddressOfFunctions; DWORD AddressOfNames; DWORD AddressOfNameOrdinals; } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
typedef struct { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; LONG ptx; LONG pty; } MSG;
typedef struct { UINT cbSize; UINT style; LRESULT (*lpfnWndProc)(HWND,UINT,WPARAM,LPARAM);
INT cbClsExtra; INT cbWndExtra; HINSTANCE hInstance; HANDLE hIcon; HANDLE hCursor;
HANDLE hBrush; LPCSTR lpszMenuName; LPCSTR lpszClassName; HANDLE hIconSm; } WNDCLASSEXA;
typedef struct { GUID PowerSetting; DWORD DataLength; uint8_t Data[1]; } POWERBROADCAST_SETTING;
#define WM_POWERBROADCAST 0x0218
#define PBT_APMSUSPEND 0x0004
#define PBT_APMRESUMESUSPEND 0x0007
#define PBT_APMPOWERSTATUSCHANGE 0x000A
#define WS_POPUP 0x80000000
#define THREAD_PRIORITY_TIME_CRITICAL 15
const GUID GUID_MONITOR_POWER_ON = {0x02731015,0x4510,0x4526,{0x99,0xE6,0xE5,0xA1,0x7E,0xBD,0x1A,0xEA}};
const GUID GUID_LIDSWITCH_STATE_CHANGE = {0xBA3E0F4D,0xB817,0x4094,{0xA2,0xD1,0xD5,0x63,0x79,0xE6,0xA0,0xF3}};
const GUID GUID_BATTERY_PERCENTAGE_REMAINING = {0xA7AD8041,0xB45A,0x4CAE,{0x87,0xA3,0xEE,0x1B,0x4C,0x4E,0xB3,0xD5}};
const GUID GUID_CONSOLE_DISPLAY_STATE = {0x6FE69556,0x704A,0x47A0,{0x8F,0x24,0xC2,0x8D,0x93,0x6F,0xDA,0x47}};
typedef HDEVNOTIFY (*RegisterPowerSettingNotification_t)(HANDLE,const GUID*,DWORD);
typedef HWND (*CreateWindowExA_t)(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
typedef UINT (*RegisterClassExA_t)(const WNDCLASSEXA*);
typedef BOOL (*GetMessageA_t)(MSG*,HWND,UINT,UINT);
typedef LRESULT (*DispatchMessageA_t)(const MSG*);
typedef void (*PostQuitMessage_t)(INT);
typedef HANDLE (*CreateThread_t)(PVOID,SIZE_T,LPTHREAD_START_ROUTINE,PVOID,DWORD,LPDWORD);
typedef LRESULT (*DefWindowProcA_t)(HWND,UINT,WPARAM,LPARAM);
static RegisterPowerSettingNotification_t g_RegisterPwrNotif;
static CreateWindowExA_t g_CreateWindowExA;
static RegisterClassExA_t g_RegisterClassExA;
static GetMessageA_t g_GetMessageA;
static DispatchMessageA_t g_DispatchMessageA;
static PostQuitMessage_t g_PostQuitMessage;
static CreateThread_t g_CreateThread;
static DefWindowProcA_t g_DefWindowProcA;
extern int sov_worm_checkpoint(void*);
extern int sov_worm_restore(void*);
extern void sov_janet_set(int, float);
static PVOID peb_find_module(const wchar_t* tgt) {
PVOID peb; __asm__ volatile("mov %%gs:0x60,%0":"=r"(peb));
PPEB_LDR_DATA ldr = ((PPEB)peb)->Ldr; if (!ldr) return 0;
PLIST_ENTRY h = &ldr->InMemoryOrder, c = h->Flink;
while (c != h) {
PLDR_DATA_TABLE_ENTRY e = (PLDR_DATA_TABLE_ENTRY)((uint8_t*)c - 16);
if (e->BaseDllName.Buffer) {
int ok=1; const wchar_t* n=e->BaseDllName.Buffer;
for (int i=0;i<e->BaseDllName.Length/2;i++){
wchar_t a=n[i],b=tgt[i];
if(a>='A'&&a<='Z')a+=32; if(b>='A'&&b<='Z')b+=32;
if(a!=b){ok=0;break;}
}
if(ok&&tgt[e->BaseDllName.Length/2]==0) return e->DllBase;
}
c=c->Flink;
}
return 0;
}
static PVOID pe_export(PVOID base, const char* name) {
if (!base) return 0;
PIMAGE_DOS_HEADER dos=(PIMAGE_DOS_HEADER)base;
if(dos->e_magic!=0x5A4D) return 0;
PIMAGE_NT_HEADERS64 nt=(PIMAGE_NT_HEADERS64)((uint8_t*)base+dos->e_lfanew);
if(nt->Signature!=0x4550) return 0;
DWORD erva=nt->OptHdr.DataDir[0].VirtualAddress; if(!erva) return 0;
PIMAGE_EXPORT_DIRECTORY exp=(PIMAGE_EXPORT_DIRECTORY)((uint8_t*)base+erva);
DWORD*nms=(DWORD*)((uint8_t*)base+exp->AddressOfNames);
DWORD*fns=(DWORD*)((uint8_t*)base+exp->AddressOfFunctions);
WORD* ords=(WORD*)((uint8_t*)base+exp->AddressOfNameOrdinals);
int lo=0,hi=(int)exp->NumberOfNames-1;
while(lo<=hi){
int mid=(lo+hi)>>1; const char*mn=(const char*)((uint8_t*)base+nms[mid]);
int cmp=0; for(int i=0;;i++){if(!mn[i]&&!name[i])break;if(mn[i]!=name[i]){cmp=(mn[i]<name[i])?-1:1;break;}}
if(!cmp) return (PVOID)((uint8_t*)base+fns[ords[mid]]);
else if(cmp<0) lo=mid+1; else hi=mid-1;
}
return 0;
}
static void resolve_power_apis(void) {
PVOID u32 = peb_find_module(L"user32.dll");
PVOID pwr = peb_find_module(L"powrprof.dll");
PVOID k32 = peb_find_module(L"kernel32.dll");
if(u32){
g_CreateWindowExA = (CreateWindowExA_t)pe_export(u32,"CreateWindowExA");
g_RegisterClassExA = (RegisterClassExA_t)pe_export(u32,"RegisterClassExA");
g_GetMessageA = (GetMessageA_t)pe_export(u32,"GetMessageA");
g_DispatchMessageA = (DispatchMessageA_t)pe_export(u32,"DispatchMessageA");
g_PostQuitMessage = (PostQuitMessage_t)pe_export(u32,"PostQuitMessage");
g_DefWindowProcA = (DefWindowProcA_t)pe_export(u32,"DefWindowProcA");
}
if(pwr) g_RegisterPwrNotif = (RegisterPowerSettingNotification_t)pe_export(pwr,"RegisterPowerSettingNotification");
if(k32) g_CreateThread = (CreateThread_t)pe_export(k32,"CreateThread");
}
static HWND g_hwnd;
static LRESULT window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_POWERBROADCAST) {
switch ((UINT)wParam) {
case PBT_APMSUSPEND:
sov_worm_checkpoint(0);
return 1;
case PBT_APMRESUMESUSPEND:
sov_worm_restore(0);
return 1;
case PBT_APMPOWERSTATUSCHANGE: {
POWERBROADCAST_SETTING* ps = (POWERBROADCAST_SETTING*)lParam;
if (ps && ps->DataLength >= 4) {
uint32_t pct = *(uint32_t*)ps->Data;
if (pct < 20) sov_janet_set(1, 2.0f); /* reduce batch_size to 2 */
}
return 1;
}
}
}
return g_DefWindowProcA ? g_DefWindowProcA(hwnd, msg, wParam, lParam) : 0;
}
static int power_thread(PVOID arg) {
if (!g_CreateWindowExA || !g_RegisterClassExA || !g_GetMessageA) return 1;
WNDCLASSEXA wc = {0};
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = window_proc;
wc.lpszClassName = "SovPower";
g_RegisterClassExA(&wc);
g_hwnd = g_CreateWindowExA(0,"SovPower","",WS_POPUP,0,0,0,0,0,0,0,0);
if (!g_hwnd) return 2;
if (g_RegisterPwrNotif) {
g_RegisterPwrNotif(g_hwnd, &GUID_MONITOR_POWER_ON, 0);
g_RegisterPwrNotif(g_hwnd, &GUID_LIDSWITCH_STATE_CHANGE, 0);
g_RegisterPwrNotif(g_hwnd, &GUID_BATTERY_PERCENTAGE_REMAINING, 0);
g_RegisterPwrNotif(g_hwnd, &GUID_CONSOLE_DISPLAY_STATE, 0);
}
MSG msg;
while (g_GetMessageA(&msg, 0, 0, 0))
g_DispatchMessageA(&msg);
return 0;
}
void sov_power_handler_init(void) {
resolve_power_apis();
if (g_CreateThread)
g_CreateThread(0, 0, power_thread, 0, 0, 0);
}
|