WRK Compatibility With Windows Server 2003 SP2
Windows Research Kernel @ HPIThe deployment of Windows Server 2008 R2 Hyper-V based virtual machines to facilitate our operating system course assignments has brought up the issue that virtual machines have to run at least Windows Server 2003 SP2. Since the WRK documentation says that Windows Server 2003 SP1 is needed to run the kernel, the question remains whether the application binary interface (ABI) of those two versions are compatible. As others indicated (thanks for your comments 🙂) and evaluated on our server, the WRK appears to be able to run on Windows Server 2003 SP2. Nevertheless, I wanted to examine if at least the user-kernel mode ABI is compatible, for which I will give an answer in this post.
The Application Binary Interface for the WRK is determined
through the system call table and its calling conventions (system
call number in EAX
, parameters on the stack). Since I
don't assume that the calling conventions have changed, I
concentrated on the system call table. If any of the system call
numbers would differ, both versions are incompatible. On the
Metasploit
web site, you can find a comparison of system calls from various
Windows versions. Unfortunately, system calls of Server 2003 SP2 are
not listed in their table. It also appears that the site is not
active anymore since the comparison ends with Windows Vista.
So, I had to find out the system call table myself. Fortunately, WinDbg is your friend in such a case. The user mode portion of a Windows system call is implemented in ntdll.dll and looks like this:
mov eax,<system_call_number> mov edx,offset SharedUserData!SystemCallStub (<resolved_address>) call dword ptr [edx] ret 8
Since system calls are exported by ntdll.dll, we can scan through
all the exported symbols starting with Nt
. Then we can
disassemble the instructions for each function. As shown in the
snippet above, the first two instructions are enough to figure out,
whether the symbol we found is actually a system call. To retrieve a
disassembly of all exported symbols starting with Nt
, I
used the following WinDbg command:
.foreach /ps 5 (syscall {x ntdll!Nt*}) {u syscall L2}
The command x ntdll!Nt*
examines all symbols from
ntdll.dll that start with Nt
. Each line is passed to a
variable named syscall
, for which we disassemble
(u
) the first two instructions (L2
).
Unfortunately, the .foreach
command does not iterate
line wise over an input stream but rather word wise. Since the
x
command delivers multiple words of information per
symbol, the /ps
switch tells .foreach
to
skip 5 of those (unnecessary) parameters. Finally, I wrote a small
Python script to search through the generated output to identify all
the included system calls and extract the system call number.
I performed this experiment twice: once on an SP1 and once on a SP2 machine. Here are the system call tables of these two versions:
Number | Service Pack 1 | Service Pack 2 |
---|---|---|
0 | NtAcceptConnectPort | NtAcceptConnectPort |
1 | NtAccessCheck | NtAccessCheck |
2 | NtAccessCheckAndAuditAlarm | NtAccessCheckAndAuditAlarm |
3 | NtAccessCheckByType | NtAccessCheckByType |
4 | NtAccessCheckByTypeAndAuditAlarm | NtAccessCheckByTypeAndAuditAlarm |
5 | NtAccessCheckByTypeResultList | NtAccessCheckByTypeResultList |
6 | NtAccessCheckByTypeResultListAnd-AuditAlarm | NtAccessCheckByTypeResultListAnd-AuditAlarm |
7 | NtAccessCheckByTypeResultListAnd-AuditAlarmByHandle | NtAccessCheckByTypeResultListAnd-AuditAlarmByHandle |
8 | NtAddAtom | NtAddAtom |
9 | NtAddBootEntry | NtAddBootEntry |
10 | NtAddDriverEntry | NtAddDriverEntry |
11 | NtAdjustGroupsToken | NtAdjustGroupsToken |
12 | NtAdjustPrivilegesToken | NtAdjustPrivilegesToken |
13 | NtAlertResumeThread | NtAlertResumeThread |
14 | NtAlertThread | NtAlertThread |
15 | NtAllocateLocallyUniqueId | NtAllocateLocallyUniqueId |
16 | NtAllocateUserPhysicalPages | NtAllocateUserPhysicalPages |
17 | NtAllocateUuids | NtAllocateUuids |
18 | NtAllocateVirtualMemory | NtAllocateVirtualMemory |
19 | NtApphelpCacheControl | NtApphelpCacheControl |
20 | NtAreMappedFilesTheSame | NtAreMappedFilesTheSame |
21 | NtAssignProcessToJobObject | NtAssignProcessToJobObject |
22 | NtCallbackReturn | NtCallbackReturn |
23 | NtCancelDeviceWakeupRequest | NtCancelDeviceWakeupRequest |
24 | NtCancelIoFile | NtCancelIoFile |
25 | NtCancelTimer | NtCancelTimer |
26 | NtClearEvent | NtClearEvent |
27 | NtClose | NtClose |
28 | NtCloseObjectAuditAlarm | NtCloseObjectAuditAlarm |
29 | NtCompactKeys | NtCompactKeys |
30 | NtCompareTokens | NtCompareTokens |
31 | NtCompleteConnectPort | NtCompleteConnectPort |
32 | NtCompressKey | NtCompressKey |
33 | NtConnectPort | NtConnectPort |
34 | NtContinue | NtContinue |
35 | NtCreateDebugObject | NtCreateDebugObject |
36 | NtCreateDirectoryObject | NtCreateDirectoryObject |
37 | NtCreateEvent | NtCreateEvent |
38 | NtCreateEventPair | NtCreateEventPair |
39 | NtCreateFile | NtCreateFile |
40 | NtCreateIoCompletion | NtCreateIoCompletion |
41 | NtCreateJobObject | NtCreateJobObject |
42 | NtCreateJobSet | NtCreateJobSet |
43 | NtCreateKey | NtCreateKey |
44 | NtCreateMailslotFile | NtCreateMailslotFile |
45 | NtCreateMutant | NtCreateMutant |
46 | NtCreateNamedPipeFile | NtCreateNamedPipeFile |
47 | NtCreatePagingFile | NtCreatePagingFile |
48 | NtCreatePort | NtCreatePort |
49 | NtCreateProcess | NtCreateProcess |
50 | NtCreateProcessEx | NtCreateProcessEx |
51 | NtCreateProfile | NtCreateProfile |
52 | NtCreateSection | NtCreateSection |
53 | NtCreateSemaphore | NtCreateSemaphore |
54 | NtCreateSymbolicLinkObject | NtCreateSymbolicLinkObject |
55 | NtCreateThread | NtCreateThread |
56 | NtCreateTimer | NtCreateTimer |
57 | NtCreateToken | NtCreateToken |
58 | NtCreateWaitablePort | NtCreateWaitablePort |
59 | NtDebugActiveProcess | NtDebugActiveProcess |
60 | NtDebugContinue | NtDebugContinue |
61 | NtDelayExecution | NtDelayExecution |
62 | NtDeleteAtom | NtDeleteAtom |
63 | NtDeleteBootEntry | NtDeleteBootEntry |
64 | NtDeleteDriverEntry | NtDeleteDriverEntry |
65 | NtDeleteFile | NtDeleteFile |
66 | NtDeleteKey | NtDeleteKey |
67 | NtDeleteObjectAuditAlarm | NtDeleteObjectAuditAlarm |
68 | NtDeleteValueKey | NtDeleteValueKey |
69 | NtDeviceIoControlFile | NtDeviceIoControlFile |
70 | NtDisplayString | NtDisplayString |
71 | NtDuplicateObject | NtDuplicateObject |
72 | NtDuplicateToken | NtDuplicateToken |
73 | NtEnumerateBootEntries | NtEnumerateBootEntries |
74 | NtEnumerateDriverEntries | NtEnumerateDriverEntries |
75 | NtEnumerateKey | NtEnumerateKey |
76 | NtEnumerateSystemEnvironment-ValuesEx | NtEnumerateSystemEnvironment-ValuesEx |
77 | NtEnumerateValueKey | NtEnumerateValueKey |
78 | NtExtendSection | NtExtendSection |
79 | NtFilterToken | NtFilterToken |
80 | NtFindAtom | NtFindAtom |
81 | NtFlushBuffersFile | NtFlushBuffersFile |
82 | NtFlushInstructionCache | NtFlushInstructionCache |
83 | NtFlushKey | NtFlushKey |
84 | NtFlushVirtualMemory | NtFlushVirtualMemory |
85 | NtFlushWriteBuffer | NtFlushWriteBuffer |
86 | NtFreeUserPhysicalPages | NtFreeUserPhysicalPages |
87 | NtFreeVirtualMemory | NtFreeVirtualMemory |
88 | NtFsControlFile | NtFsControlFile |
89 | NtGetContextThread | NtGetContextThread |
90 | NtGetDevicePowerState | NtGetDevicePowerState |
91 | NtGetPlugPlayEvent | NtGetPlugPlayEvent |
92 | NtGetWriteWatch | NtGetWriteWatch |
93 | NtImpersonateAnonymousToken | NtImpersonateAnonymousToken |
94 | NtImpersonateClientOfPort | NtImpersonateClientOfPort |
95 | NtImpersonateThread | NtImpersonateThread |
96 | NtInitializeRegistry | NtInitializeRegistry |
97 | NtInitiatePowerAction | NtInitiatePowerAction |
98 | NtIsProcessInJob | NtIsProcessInJob |
99 | NtIsSystemResumeAutomatic | NtIsSystemResumeAutomatic |
100 | NtListenPort | NtListenPort |
101 | NtLoadDriver | NtLoadDriver |
102 | NtLoadKey | NtLoadKey |
103 | NtLoadKey2 | NtLoadKey2 |
104 | NtLoadKeyEx | NtLoadKeyEx |
105 | NtLockFile | NtLockFile |
106 | NtLockProductActivationKeys | NtLockProductActivationKeys |
107 | NtLockRegistryKey | NtLockRegistryKey |
108 | NtLockVirtualMemory | NtLockVirtualMemory |
109 | NtMakePermanentObject | NtMakePermanentObject |
110 | NtMakeTemporaryObject | NtMakeTemporaryObject |
111 | NtMapUserPhysicalPages | NtMapUserPhysicalPages |
112 | NtMapUserPhysicalPagesScatter | NtMapUserPhysicalPagesScatter |
113 | NtMapViewOfSection | NtMapViewOfSection |
114 | NtModifyBootEntry | NtModifyBootEntry |
115 | NtModifyDriverEntry | NtModifyDriverEntry |
116 | NtNotifyChangeDirectoryFile | NtNotifyChangeDirectoryFile |
117 | NtNotifyChangeKey | NtNotifyChangeKey |
118 | NtNotifyChangeMultipleKeys | NtNotifyChangeMultipleKeys |
119 | NtOpenDirectoryObject | NtOpenDirectoryObject |
120 | NtOpenEvent | NtOpenEvent |
121 | NtOpenEventPair | NtOpenEventPair |
122 | NtOpenFile | NtOpenFile |
123 | NtOpenIoCompletion | NtOpenIoCompletion |
124 | NtOpenJobObject | NtOpenJobObject |
125 | NtOpenKey | NtOpenKey |
126 | NtOpenMutant | NtOpenMutant |
127 | NtOpenObjectAuditAlarm | NtOpenObjectAuditAlarm |
128 | NtOpenProcess | NtOpenProcess |
129 | NtOpenProcessToken | NtOpenProcessToken |
130 | NtOpenProcessTokenEx | NtOpenProcessTokenEx |
131 | NtOpenSection | NtOpenSection |
132 | NtOpenSemaphore | NtOpenSemaphore |
133 | NtOpenSymbolicLinkObject | NtOpenSymbolicLinkObject |
134 | NtOpenThread | NtOpenThread |
135 | NtOpenThreadToken | NtOpenThreadToken |
136 | NtOpenThreadTokenEx | NtOpenThreadTokenEx |
137 | NtOpenTimer | NtOpenTimer |
138 | NtPlugPlayControl | NtPlugPlayControl |
139 | NtPowerInformation | NtPowerInformation |
140 | NtPrivilegeCheck | NtPrivilegeCheck |
141 | NtPrivilegeObjectAuditAlarm | NtPrivilegeObjectAuditAlarm |
142 | NtPrivilegedServiceAuditAlarm | NtPrivilegedServiceAuditAlarm |
143 | NtProtectVirtualMemory | NtProtectVirtualMemory |
144 | NtPulseEvent | NtPulseEvent |
145 | NtQueryAttributesFile | NtQueryAttributesFile |
146 | NtQueryBootEntryOrder | NtQueryBootEntryOrder |
147 | NtQueryBootOptions | NtQueryBootOptions |
148 | NtQueryDebugFilterState | NtQueryDebugFilterState |
149 | NtQueryDefaultLocale | NtQueryDefaultLocale |
150 | NtQueryDefaultUILanguage | NtQueryDefaultUILanguage |
151 | NtQueryDirectoryFile | NtQueryDirectoryFile |
152 | NtQueryDirectoryObject | NtQueryDirectoryObject |
153 | NtQueryDriverEntryOrder | NtQueryDriverEntryOrder |
154 | NtQueryEaFile | NtQueryEaFile |
155 | NtQueryEvent | NtQueryEvent |
156 | NtQueryFullAttributesFile | NtQueryFullAttributesFile |
157 | NtQueryInformationAtom | NtQueryInformationAtom |
158 | NtQueryInformationFile | NtQueryInformationFile |
159 | NtQueryInformationJobObject | NtQueryInformationJobObject |
160 | NtQueryInformationPort | NtQueryInformationPort |
161 | NtQueryInformationProcess | NtQueryInformationProcess |
162 | NtQueryInformationThread | NtQueryInformationThread |
163 | NtQueryInformationToken | NtQueryInformationToken |
164 | NtQueryInstallUILanguage | NtQueryInstallUILanguage |
165 | NtQueryIntervalProfile | NtQueryIntervalProfile |
166 | NtQueryIoCompletion | NtQueryIoCompletion |
167 | NtQueryKey | NtQueryKey |
168 | NtQueryMultipleValueKey | NtQueryMultipleValueKey |
169 | NtQueryMutant | NtQueryMutant |
170 | NtQueryObject | NtQueryObject |
171 | NtQueryOpenSubKeys | NtQueryOpenSubKeys |
172 | NtQueryOpenSubKeysEx | NtQueryOpenSubKeysEx |
173 | NtQueryPerformanceCounter | NtQueryPerformanceCounter |
174 | NtQueryQuotaInformationFile | NtQueryQuotaInformationFile |
175 | NtQuerySection | NtQuerySection |
176 | NtQuerySecurityObject | NtQuerySecurityObject |
177 | NtQuerySemaphore | NtQuerySemaphore |
178 | NtQuerySymbolicLinkObject | NtQuerySymbolicLinkObject |
179 | NtQuerySystemEnvironmentValue | NtQuerySystemEnvironmentValue |
180 | NtQuerySystemEnvironmentValueEx | NtQuerySystemEnvironmentValueEx |
181 | NtQuerySystemInformation | NtQuerySystemInformation |
182 | NtQuerySystemTime | NtQuerySystemTime |
183 | NtQueryTimer | NtQueryTimer |
184 | NtQueryTimerResolution | NtQueryTimerResolution |
185 | NtQueryValueKey | NtQueryValueKey |
186 | NtQueryVirtualMemory | NtQueryVirtualMemory |
187 | NtQueryVolumeInformationFile | NtQueryVolumeInformationFile |
188 | NtQueueApcThread | NtQueueApcThread |
189 | NtRaiseException | NtRaiseException |
190 | NtRaiseHardError | NtRaiseHardError |
191 | NtReadFile | NtReadFile |
192 | NtReadFileScatter | NtReadFileScatter |
193 | NtReadRequestData | NtReadRequestData |
194 | NtReadVirtualMemory | NtReadVirtualMemory |
195 | NtRegisterThreadTerminatePort | NtRegisterThreadTerminatePort |
196 | NtReleaseMutant | NtReleaseMutant |
197 | NtReleaseSemaphore | NtReleaseSemaphore |
198 | NtRemoveIoCompletion | NtRemoveIoCompletion |
199 | NtRemoveProcessDebug | NtRemoveProcessDebug |
200 | NtRenameKey | NtRenameKey |
201 | NtReplaceKey | NtReplaceKey |
202 | NtReplyPort | NtReplyPort |
203 | NtReplyWaitReceivePort | NtReplyWaitReceivePort |
204 | NtReplyWaitReceivePortEx | NtReplyWaitReceivePortEx |
205 | NtReplyWaitReplyPort | NtReplyWaitReplyPort |
206 | NtRequestDeviceWakeup | NtRequestDeviceWakeup |
207 | NtRequestPort | NtRequestPort |
208 | NtRequestWaitReplyPort | NtRequestWaitReplyPort |
209 | NtRequestWakeupLatency | NtRequestWakeupLatency |
210 | NtResetEvent | NtResetEvent |
211 | NtResetWriteWatch | NtResetWriteWatch |
212 | NtRestoreKey | NtRestoreKey |
213 | NtResumeProcess | NtResumeProcess |
214 | NtResumeThread | NtResumeThread |
215 | NtSaveKey | NtSaveKey |
216 | NtSaveKeyEx | NtSaveKeyEx |
217 | NtSaveMergedKeys | NtSaveMergedKeys |
218 | NtSecureConnectPort | NtSecureConnectPort |
219 | NtSetBootEntryOrder | NtSetBootEntryOrder |
220 | NtSetBootOptions | NtSetBootOptions |
221 | NtSetContextThread | NtSetContextThread |
222 | NtSetDebugFilterState | NtSetDebugFilterState |
223 | NtSetDefaultHardErrorPort | NtSetDefaultHardErrorPort |
224 | NtSetDefaultLocale | NtSetDefaultLocale |
225 | NtSetDefaultUILanguage | NtSetDefaultUILanguage |
226 | NtSetDriverEntryOrder | NtSetDriverEntryOrder |
227 | NtSetEaFile | NtSetEaFile |
228 | NtSetEvent | NtSetEvent |
229 | NtSetEventBoostPriority | NtSetEventBoostPriority |
230 | NtSetHighEventPair | NtSetHighEventPair |
231 | NtSetHighWaitLowEventPair | NtSetHighWaitLowEventPair |
232 | NtSetInformationDebugObject | NtSetInformationDebugObject |
233 | NtSetInformationFile | NtSetInformationFile |
234 | NtSetInformationJobObject | NtSetInformationJobObject |
235 | NtSetInformationKey | NtSetInformationKey |
236 | NtSetInformationObject | NtSetInformationObject |
237 | NtSetInformationProcess | NtSetInformationProcess |
238 | NtSetInformationThread | NtSetInformationThread |
239 | NtSetInformationToken | NtSetInformationToken |
240 | NtSetIntervalProfile | NtSetIntervalProfile |
241 | NtSetIoCompletion | NtSetIoCompletion |
242 | NtSetLdtEntries | NtSetLdtEntries |
243 | NtSetLowEventPair | NtSetLowEventPair |
244 | NtSetLowWaitHighEventPair | NtSetLowWaitHighEventPair |
245 | NtSetQuotaInformationFile | NtSetQuotaInformationFile |
246 | NtSetSecurityObject | NtSetSecurityObject |
247 | NtSetSystemEnvironmentValue | NtSetSystemEnvironmentValue |
248 | NtSetSystemEnvironmentValueEx | NtSetSystemEnvironmentValueEx |
249 | NtSetSystemInformation | NtSetSystemInformation |
250 | NtSetSystemPowerState | NtSetSystemPowerState |
251 | NtSetSystemTime | NtSetSystemTime |
252 | NtSetThreadExecutionState | NtSetThreadExecutionState |
253 | NtSetTimer | NtSetTimer |
254 | NtSetTimerResolution | NtSetTimerResolution |
255 | NtSetUuidSeed | NtSetUuidSeed |
256 | NtSetValueKey | NtSetValueKey |
257 | NtSetVolumeInformationFile | NtSetVolumeInformationFile |
258 | NtShutdownSystem | NtShutdownSystem |
259 | NtSignalAndWaitForSingleObject | NtSignalAndWaitForSingleObject |
260 | NtStartProfile | NtStartProfile |
261 | NtStopProfile | NtStopProfile |
262 | NtSuspendProcess | NtSuspendProcess |
263 | NtSuspendThread | NtSuspendThread |
264 | NtSystemDebugControl | NtSystemDebugControl |
265 | NtTerminateJobObject | NtTerminateJobObject |
266 | NtTerminateProcess | NtTerminateProcess |
267 | NtTerminateThread | NtTerminateThread |
268 | NtTestAlert | NtTestAlert |
269 | NtTraceEvent | NtTraceEvent |
270 | NtTranslateFilePath | NtTranslateFilePath |
271 | NtUnloadDriver | NtUnloadDriver |
272 | NtUnloadKey | NtUnloadKey |
273 | NtUnloadKey2 | NtUnloadKey2 |
274 | NtUnloadKeyEx | NtUnloadKeyEx |
275 | NtUnlockFile | NtUnlockFile |
276 | NtUnlockVirtualMemory | NtUnlockVirtualMemory |
277 | NtUnmapViewOfSection | NtUnmapViewOfSection |
278 | NtVdmControl | NtVdmControl |
279 | NtWaitForDebugEvent | NtWaitForDebugEvent |
280 | NtWaitForMultipleObjects | NtWaitForMultipleObjects |
281 | NtWaitForSingleObject | NtWaitForSingleObject |
282 | NtWaitHighEventPair | NtWaitHighEventPair |
283 | NtWaitLowEventPair | NtWaitLowEventPair |
284 | NtWriteFile | NtWriteFile |
285 | NtWriteFileGather | NtWriteFileGather |
286 | NtWriteRequestData | NtWriteRequestData |
287 | NtWriteVirtualMemory | NtWriteVirtualMemory |
288 | NtYieldExecution | NtYieldExecution |
289 | NtCreateKeyedEvent | NtCreateKeyedEvent |
290 | NtOpenKeyedEvent | NtOpenKeyedEvent |
291 | NtReleaseKeyedEvent | NtReleaseKeyedEvent |
292 | NtWaitForKeyedEvent | NtWaitForKeyedEvent |
293 | NtQueryPortInformationProcess | NtQueryPortInformationProcess |
294 | NtGetCurrentProcessorNumber | NtGetCurrentProcessorNumber |
295 | NtWaitForMultipleObjects32 | NtWaitForMultipleObjects32 |
As you can see in the table above, both versions offer the same amount of system calls, which is why, from an ABI perspective, the WRK can run on both operating system versions. Unfortunately, there is one uncertainty left: the WRK links against modules such as the HAL. If there are any dependencies broken, which I think is pretty unlikely, you may encounter unexpected crashes or unpredictable behavior.
If you have any comments or hints about how to resolve the issue, please let us know.
Comments
2 Responses to "WRK Compatibility With Windows Server 2003 SP2"
Have you tried copying the correct HAL (included in the WRK) to %windir%\system32 in the VM ?
Yes we did. However, the HAL provided is the HAL of Windows Server 2003 SP1. Still we don't know if there are any broken dependencies between the old HAL and newer components of SP2.