Merge pull request #2 from vyvojar/master
[WindowsD.git] / wind.h
blob9f1f7de985ad5df66b1db9a3b9b90bc2fca34ab6
1 // Public API, standalone header.
2 // Parent includes: windows.h, winternl.h
3 // Links against ntdll.
5 // Open \\Device\\WinD
6 #define WIND_DEVNAME "WinD"
8 // Used to pass initialization.
9 typedef struct {
10 UCHAR *ci_opt;
11 UCHAR *ci_orig;
12 UCHAR ci_guess; // If ciorigptr is 0, use this guess instead.
13 int protofs; // _EPROCESS->Flags2 offset on Win7, PS_PROTECTION Win8.
14 int protbit; // Flags2->ProtectedProcess bit on Win7, -1 otherwise.
15 int bootreg; // process registry entries at boot
16 LIST_ENTRY *cblist;
17 NTSTATUS NTAPI (*pExUpdateLicenseData)(ULONG,PVOID);
18 NTSTATUS __fastcall (*pExUpdateLicenseData2)(ULONG,PVOID);
19 } wind_config_t;
20 #define WIND_POL_MAX 512
22 #define WIND_IOCTL_REGCBOFF CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
23 #define WIND_IOCTL_REGCBON CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
25 // Load a driver. Argument is simply the unicode string.
26 #define WIND_IOCTL_INSMOD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
28 // Lock/Unlock registry key. Odd ones are the 'on' command.
29 #define WIND_IOCTL_REGLOCKON CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811, METHOD_BUFFERED, FILE_ANY_ACCESS)
30 #define WIND_IOCTL_REGLOCKOFF CTL_CODE(FILE_DEVICE_UNKNOWN, 0x812, METHOD_BUFFERED, FILE_ANY_ACCESS)
31 #define WIND_IOCTL_REGNON CTL_CODE(FILE_DEVICE_UNKNOWN, 0x813, METHOD_BUFFERED, FILE_ANY_ACCESS)
32 #define WIND_IOCTL_REGNOFF CTL_CODE(FILE_DEVICE_UNKNOWN, 0x814, METHOD_BUFFERED, FILE_ANY_ACCESS)
35 // Get/set WinTcb process protection.
36 #define WIND_IOCTL_PROT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
37 typedef struct {
38 char SignatureLevel;
39 char SectionSignatureLevel;
40 char Level;
41 UCHAR Type:3;
42 UCHAR Audit:1;
43 UCHAR Signer:4;
44 } WIND_PS_PROTECTION;
45 typedef struct {
46 LONG_PTR pid; // Pid this is for. Negative = get flags only.
47 WIND_PS_PROTECTION prot;// New protection flags. Old flags stored in there.
48 } wind_prot_t;
50 // Policy header
51 typedef struct {
52 ULONG sz; // Size of everything.
53 ULONG data_sz; // Always sz-0x18.
54 ULONG endpad; // End padding. Usually 4.
55 ULONG tainted; // 1 if tainted.
56 ULONG pad1; // Always 1
57 } __attribute((packed)) wind_pol_hdr;
59 // Policy entry
60 typedef struct {
61 USHORT sz; // Size of whole entry.
62 USHORT name_sz; // Size of the following field, in bytes.
63 USHORT type; // Field type
64 USHORT data_sz; // Field size
65 ULONG flags; // Field flags
66 ULONG pad0; // Always 0
67 UCHAR name[0]; // WCHAR name, NOT zero terminated!
68 } __attribute__((packed)) wind_pol_ent;
70 static int wind_pol_unpack(UCHAR *blob, wind_pol_ent **array)
72 wind_pol_hdr *h = (void*)blob;
73 wind_pol_ent *e = (void*)blob + sizeof(*h);
74 void *endptr = ((void*)e) + h->data_sz;
75 int n = 0;
76 // Unusual.
77 if (h->sz >= 65536)
78 return -1;
79 if (h->endpad != 4)
80 return -2;
81 if (h->data_sz+0x18 != h->sz)
82 return -3;
83 if (blob[h->sz-4] != 0x45)
84 return -4;
85 while (((void*)e) < endptr) {
86 array[n++] = e;
87 e = ((void*)e) + e->sz;
88 if (n == WIND_POL_MAX)
89 return -1;
91 return n;
94 static int wind_pol_pack(UCHAR *dst, wind_pol_ent **array, int n)
96 wind_pol_hdr *h = (void*)dst;
97 wind_pol_ent *e = (void*)dst + sizeof(*h);
98 int i = 0;
99 memset(dst, 0, 65536);
100 for (i = 0; i < n; i++) {
101 int total = sizeof(*e) + array[i]->name_sz + array[i]->data_sz;
102 memcpy(e, array[i], total);
103 total = (total + 4) & (~3);
104 e->sz = total;
105 e = ((void*)e) + total;
106 h->data_sz += total;
108 h->sz = h->data_sz + 0x18;
109 h->endpad = 4;
110 h->pad1 = 1;
111 dst[h->sz-4] = 0x45;
112 return h->sz;
115 // Open the kernel driver
116 #ifndef _WIND_DRIVER
117 #define WIND_RTL_STRING(s) ((UNICODE_STRING){sizeof(s)-sizeof((s)[0]),sizeof(s),(s)})
118 static HANDLE wind_open()
120 OBJECT_ATTRIBUTES attr = {
121 .Length = sizeof(attr),
122 .Attributes = OBJ_CASE_INSENSITIVE,
123 .ObjectName = &WIND_RTL_STRING(L"\\Device\\" WIND_DEVNAME),
125 IO_STATUS_BLOCK io;
126 HANDLE dev;
127 BOOLEAN old;
128 extern NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN);
129 RtlAdjustPrivilege(10, 1, 0, &old);
130 NTSTATUS status = NtOpenFile(&dev, FILE_GENERIC_READ, &attr, &io,
131 FILE_SHARE_READ,FILE_NON_DIRECTORY_FILE| FILE_SYNCHRONOUS_IO_NONALERT);
132 if (status == STATUS_NOT_FOUND)
133 return NULL;
134 if (!NT_SUCCESS(status))
135 return NULL;
136 return dev;
139 // Pass an ioctl. IOCTLs with 9th bit set are read-write, others are write-only.
140 static NTSTATUS wind_ioctl(HANDLE dev, ULONG num, void *buf, int len)
142 IO_STATUS_BLOCK io;
143 if (num & (0x100<<2)) {
144 return NtDeviceIoControlFile(dev, NULL, NULL, NULL, &io,
145 num, buf, len, buf, len);
146 } else {
147 return NtDeviceIoControlFile(dev, NULL, NULL, NULL, &io,
148 num, buf, len, NULL, 0);
151 static NTSTATUS wind_ioctl_string(HANDLE dev, ULONG num, WCHAR *s)
153 return wind_ioctl(dev, num, s, wcslen(s)*2+2);
156 // Close driver.
157 static NTSTATUS wind_close(HANDLE dev)
159 extern NTSTATUS NTAPI NtClose(HANDLE);
160 if (dev)
161 return NtClose(dev);
162 return 0;
165 #ifndef STATUS_IMAGE_CERT_EXPIRED
166 #define STATUS_IMAGE_CERT_EXPIRED 0xc0000605
167 #endif
169 // Utility: Load a driver with DSE bypass.
170 static NTSTATUS wind_insmod(WCHAR *svc)
172 UNICODE_STRING svcu;
173 NTSTATUS status;
175 RtlInitUnicodeString(&svcu, svc);
176 status = NtLoadDriver(&svcu);
177 // TBD: are these all the evil ones?
178 if (status == STATUS_IMAGE_CERT_REVOKED
179 || status == STATUS_INVALID_SIGNATURE
180 || status == STATUS_INVALID_IMAGE_HASH
181 || status == STATUS_INVALID_SID
182 || status == STATUS_IMAGE_CERT_EXPIRED
183 || status == STATUS_HASH_NOT_PRESENT
184 || status == STATUS_HASH_NOT_SUPPORTED) {
186 HANDLE h = wind_open();
187 if (!h) return status;
188 status = wind_ioctl_string(h, WIND_IOCTL_INSMOD, svc);
189 wind_close(h);
191 return status;
194 #endif