Как известно ОСи на основе Windows NT (2000, XP, 2003, Vista) используют два
режима привилегий процессора: на привилегированном уровне исполняется ядро
(Kernel Mode), на непривилегированном - программы пользовательского режима
(User Mode). В режиме ядра доступен ввод-вывод через порты, вся память,
привилегированные команды. Драйверы, осуществляющие прямое управление
устройствами должны исполняться в режиме ядра. Архитектура системы позволяет
полностью контролировать код, исполняющийся в пользовательском режиме.
Обращение к функциям ядра и драйверов возможно только через специальные
шлюзы, предусмотренные разработчиками ОС.
Ядро содержит массу функций, которые могут быть вызваны из пользовательского
режима. Программа пользовательского режима вызывает какую-либо функцию, а та,
используя шлюз, передает управление ядру. Ядро проверяет параметры и выполняет
некоторый код, результаты исполнения передаются в пользовательский режим.
Например, документированная в Platform SDK функция
CreateFile вызывает
недокументированную
ZwCreateFile из ntdll.dll. А уже эта функция вызывает
одноименный сервис ядра через специальный шлюз.
На самом деле, почти все функции, имена которых можно найти в ntdll.dll и есть
функции ядра, а одноименные функции, доступные в пользовательском режиме - это
переходники, сразу передающие управление функциям ядра через шлюзы. Эти
функции иногда называют NT Native API.
При вызове NativeAPI функции из ntdll.dll в регистр eax записывается номер
системной функции ядра. Затем
вызывается прерывание 2Eh (в Windows XP - команда sysenter) и
происходит переход текущего потока в режим ядра. Ядро содержит обработчик
прерываний, в том числе и для прерывания 2Eh. Обработчиком является функция
KiSystemService. Эта функция копирует передаваемые системному сервису параметры
в память ядра, и производит вызов NativeAPI функции ядра согласно содержимому
ServiceDescriptorTable. Эта таблица находится в памяти ядра, и
представляет собой структуру содержащую 4 таблицы системных сервисов (SST).
Первая из этих таблиц описывает сервисы экспортируемые ядром (ntoskrnl.exe),
вторая - графической подсистемой (win32k.sys), а остальные две зарезервированы
на будующее и сейчас не используются.
ServiceDescriptorTable (SDT) содержит таблицы с указателями на функции. Usermode
функция и записывает при вызове индекс элемента в этой таблице (это и есть
номер функции в SDT).
typedef struct _SYSTEM_SERVICE_TABLE
{
PVOID* ServiceTable; // Адреса функций
ULONG* CounterTable; // Счетчик вызовов
ULONG ServiceLimit; // Количество сервисов
UCHAR* ArgumentTable; // Количество аргументов функций
} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
SYSTEM_SERVICE_TABLE ntoskrnl; //SST для ntoskrnl.exe
SYSTEM_SERVICE_TABLE win32k; //SST для win32k.sys
SYSTEM_SERVICE_TABLE Reserved1;
SYSTEM_SERVICE_TABLE Reserved2;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
Например, чтобы перехватить NativeAPI функцию в режиме ядра, можно просто
заменить ее адрес в SDT. Но чтобы перехватывать именно нужную функцию
нужно знать индексы элементов в этой таблице, т.е. какой функции какой
номер соответствует. Кстати, номер одной и той же функции в SDT разных ОС
(Windows 2000, Windows XP) обычно различается.
Действия перехвата функций и контроля передаваемых параметров функциям
системы выполняют средства проактивной защиты и некоторые антивирусы.
Следует заметить, что перехват системных функций значительно снижает
быстродействие системы, т.к. при каждом системном вызове (а они происходят
довольно часто), выполняется дополнительный код перехватчика.
Например, код функции
ZwCreateFile (и
NtCreateFile, что в
пользовательском режиме то же самое) в Windows XP выглядит следующим образом:
; __stdcall ZwCreateFile(x, x, x, x, x, x, x, x, x, x, x)
public _ZwCreateFile@44
_ZwCreateFile@44 proc near
mov eax, 25h ; Это номер в SDT
mov edx, 7FFE0300h ; Это адрес шлюза (KiFastSystemCall)
call dword ptr [edx] ; Вызов шлюза. Он получит
; адрес параметров и вызовет SYSENTER
retn 2Ch
_ZwCreateFile@44 endp
В Windows 2000:
public ZwCreateFile
ZwCreateFile proc near
arg_0= dword ptr 4
mov eax, 20h ; Это номер в SDT
lea edx, [esp+arg_0]; В edx записывается адрес параметров
int 2Eh ; Вызывается шлюз
retn 2Ch
ZwCreateFile endp
Если вызывать NativeAPI функцию подобным образом, можно обойти любой Usermode-
перехват (об этом будет рассказано в другой статье).
Для получения номеров функций в SDT системы мною была разработана утилита
sdt.exe, на вход которой следует подать ntdll.dll файлы от разных Microsoft
Windows. Программа построит таблицу с номерами функций в SDT указанных
систем.
В заключение, привожу таблицу с номерами функций в SDT разных ОС:
Номера системных функций в SDT
NativeAPI функция Номер в SDT
2000 XP 2003 Vista
NtAcceptConnectPort 0 0 0 0
NtAccessCheck 1 1 1 1
NtAccessCheckAndAuditAlarm 2 2 2 2
NtAccessCheckByType 3 3 3 3
NtAccessCheckByTypeAndAuditAlarm 4 4 4 4
NtAccessCheckByTypeResultList 5 5 5 5
NtAccessCheckByTypeResultListAndAuditAlarm
6 6 6 6
NtAccessCheckByTypeResultListAndAuditAlarmByHandle
7 7 7 7
NtAddAtom 8 8 8 8
NtAdjustGroupsToken 9 10 11 11
NtAdjustPrivilegesToken 10 11 12 12
NtAlertResumeThread 11 12 13 13
NtAlertThread 12 13 14 14
NtAllocateLocallyUniqueId 13 14 15 15
NtAllocateUserPhysicalPages 14 15 16 16
NtAllocateUuids 15 16 17 17
NtAllocateVirtualMemory 16 17 18 18
NtAreMappedFilesTheSame 17 18 20 41
NtAssignProcessToJobObject 18 19 21 42
NtCallbackReturn 19 20 22 43
NtCancelDeviceWakeupRequest 22 21 23 44
NtCancelIoFile 20 22 24 45
NtCancelTimer 21 23 25 46
NtClearEvent 23 24 26 47
NtClose 24 25 27 48
NtCloseObjectAuditAlarm 25 26 28 49
NtCompleteConnectPort 26 29 31 52
NtConnectPort 27 31 33 54
NtContinue 28 32 34 55
NtCreateChannel 241 - - -
NtCreateDirectoryObject 29 34 36 57
NtCreateEvent 30 35 37 58
NtCreateEventPair 31 36 38 59
NtCreateFile 32 37 39 60
NtCreateIoCompletion 33 38 40 61
NtCreateJobObject 34 39 41 62
NtCreateKey 35 41 43 64
NtCreateMailslotFile 36 42 44 66
NtCreateMutant 37 43 45 67
NtCreateNamedPipeFile 38 44 46 68
NtCreatePagingFile 39 45 47 70
NtCreatePort 40 46 48 71
NtCreateProcess 41 47 49 72
NtCreateProfile 42 49 51 74
NtCreateSection 43 50 52 75
NtCreateSemaphore 44 51 53 76
NtCreateSymbolicLinkObject 45 52 54 77
NtCreateThread 46 53 55 78
NtCreateTimer 47 54 56 79
NtCreateToken 48 55 57 80
NtCreateWaitablePort 49 56 58 115
NtDelayExecution 50 59 61 118
NtDeleteAtom 51 60 62 119
NtDeleteFile 52 62 65 122
NtDeleteKey 53 63 66 123
NtDeleteObjectAuditAlarm 54 64 67 125
NtDeleteValueKey 55 65 68 126
NtDeviceIoControlFile 56 66 69 127
NtDisplayString 57 67 70 128
NtDuplicateObject 58 68 71 129
NtDuplicateToken 59 69 72 130
NtEnumerateKey 60 71 75 133
NtEnumerateValueKey 61 73 77 136
NtExtendSection 62 74 78 137
NtFilterToken 63 75 79 138
NtFindAtom 64 76 80 139
NtFlushBuffersFile 65 77 81 140
NtFlushInstructionCache 66 78 82 141
NtFlushKey 67 79 83 142
NtFlushVirtualMemory 68 80 84 144
NtFlushWriteBuffer 69 81 85 145
NtFreeUserPhysicalPages 70 82 86 146
NtFreeVirtualMemory 71 83 87 147
NtFsControlFile 72 84 88 150
NtGetContextThread 73 85 89 151
NtGetDevicePowerState 74 86 90 152
NtGetPlugPlayEvent 75 87 91 154
NtGetTickCount 76 - - -
NtGetWriteWatch 77 88 92 155
NtImpersonateAnonymousToken 78 89 93 156
NtImpersonateClientOfPort 79 90 94 157
NtImpersonateThread 80 91 95 158
NtInitializeRegistry 81 92 96 160
NtInitiatePowerAction 82 93 97 161
NtIsSystemResumeAutomatic 83 95 99 163
NtListenChannel 242 - - -
NtListenPort 84 96 100 164
NtLoadDriver 85 97 101 165
NtLoadKey 86 98 102 166
NtLoadKey2 87 99 103 167
NtLockFile 88 100 105 169
NtLockVirtualMemory 89 103 108 172
NtMakeTemporaryObject 90 105 110 174
NtMapUserPhysicalPages 91 106 111 175
NtMapUserPhysicalPagesScatter 92 107 112 176
NtMapViewOfSection 93 108 113 177
NtNotifyChangeDirectoryFile 94 110 116 180
NtNotifyChangeKey 95 111 117 181
NtNotifyChangeMultipleKeys 96 112 118 182
NtOpenChannel 243 - - -
NtOpenDirectoryObject 97 113 119 183
NtOpenEvent 98 114 120 184
NtOpenEventPair 99 115 121 185
NtOpenFile 100 116 122 186
NtOpenIoCompletion 101 117 123 187
NtOpenJobObject 102 118 124 188
NtOpenKey 103 119 125 189
NtOpenMutant 104 120 126 191
NtOpenObjectAuditAlarm 105 121 127 193
NtOpenProcess 106 122 128 194
NtOpenProcessToken 107 123 129 195
NtOpenSection 108 125 131 197
NtOpenSemaphore 109 126 132 198
NtOpenSymbolicLinkObject 110 127 133 200
NtOpenThread 111 128 134 201
NtOpenThreadToken 112 129 135 202
NtOpenTimer 113 131 137 204
NtPlugPlayControl 114 132 138 205
NtPowerInformation 115 133 139 206
NtPrivilegeCheck 116 134 140 207
NtPrivilegeObjectAuditAlarm 118 135 141 208
NtPrivilegedServiceAuditAlarm 117 136 142 209
NtProtectVirtualMemory 119 137 143 210
NtPulseEvent 120 138 144 211
NtQueryAttributesFile 122 139 145 212
NtQueryDefaultLocale 123 143 149 216
NtQueryDefaultUILanguage 124 144 150 217
NtQueryDirectoryFile 125 145 151 218
NtQueryDirectoryObject 126 146 152 219
NtQueryEaFile 127 147 154 221
NtQueryEvent 128 148 155 222
NtQueryFullAttributesFile 129 149 156 223
NtQueryInformationAtom 121 150 157 224
NtQueryInformationFile 130 151 158 225
NtQueryInformationJobObject 131 152 159 226
NtQueryInformationPort 133 153 160 227
NtQueryInformationProcess 134 154 161 228
NtQueryInformationThread 135 155 162 229
NtQueryInformationToken 136 156 163 230
NtQueryInstallUILanguage 137 157 164 231
NtQueryIntervalProfile 138 158 165 232
NtQueryIoCompletion 132 159 166 233
NtQueryKey 139 160 167 234
NtQueryMultipleValueKey 140 161 168 235
NtQueryMutant 141 162 169 236
NtQueryObject 142 163 170 237
NtQueryOpenSubKeys 143 164 171 238
NtQueryPerformanceCounter 144 165 173 240
NtQueryQuotaInformationFile 145 166 174 241
NtQuerySection 146 167 175 242
NtQuerySecurityObject 147 168 176 243
NtQuerySemaphore 148 169 177 244
NtQuerySymbolicLinkObject 149 170 178 245
NtQuerySystemEnvironmentValue 150 171 179 246
NtQuerySystemInformation 151 173 181 248
NtQuerySystemTime 152 174 182 249
NtQueryTimer 153 175 183 250
NtQueryTimerResolution 154 176 184 251
NtQueryValueKey 155 177 185 252
NtQueryVirtualMemory 156 178 186 253
NtQueryVolumeInformationFile 157 179 187 254
NtQueueApcThread 158 180 188 255
NtRaiseException 159 181 189 256
NtRaiseHardError 160 182 190 257
NtReadFile 161 183 191 258
NtReadFileScatter 162 184 192 259
NtReadRequestData 163 185 193 260
NtReadVirtualMemory 164 186 194 261
NtRegisterThreadTerminatePort 165 187 195 262
NtReleaseMutant 166 188 196 263
NtReleaseSemaphore 167 189 197 264
NtRemoveIoCompletion 168 190 198 265
NtReplaceKey 169 193 201 268
NtReplyPort 170 194 202 269
NtReplyWaitReceivePort 171 195 203 270
NtReplyWaitReceivePortEx 172 196 204 271
NtReplyWaitReplyPort 173 197 205 272
NtReplyWaitSendChannel 244 - - -
NtRequestDeviceWakeup 174 198 206 273
NtRequestPort 175 199 207 274
NtRequestWaitReplyPort 176 200 208 275
NtRequestWakeupLatency 177 201 209 276
NtResetEvent 178 202 210 277
NtResetWriteWatch 179 203 211 278
NtRestoreKey 180 204 212 279
NtResumeThread 181 206 214 281
NtSaveKey 182 207 215 282
NtSaveMergedKeys 183 209 217 284
NtSecureConnectPort 184 210 218 290
NtSendWaitReplyChannel 245 - - -
NtSetContextChannel 246 - - -
NtSetContextThread 186 213 221 293
NtSetDefaultHardErrorPort 187 215 223 295
NtSetDefaultLocale 188 216 224 296
NtSetDefaultUILanguage 189 217 225 297
NtSetEaFile 190 218 227 299
NtSetEvent 191 219 228 300
NtSetHighEventPair 192 221 230 302
NtSetHighWaitLowEventPair 193 222 231 303
NtSetInformationFile 194 224 233 305
NtSetInformationJobObject 195 225 234 306
NtSetInformationKey 196 226 235 307
NtSetInformationObject 197 227 236 308
NtSetInformationProcess 198 228 237 309
NtSetInformationThread 199 229 238 310
NtSetInformationToken 200 230 239 311
NtSetIntervalProfile 201 231 240 312
NtSetIoCompletion 185 232 241 313
NtSetLdtEntries 202 233 242 314
NtSetLowEventPair 203 234 243 315
NtSetLowWaitHighEventPair 204 235 244 316
NtSetQuotaInformationFile 205 236 245 317
NtSetSecurityObject 206 237 246 318
NtSetSystemEnvironmentValue 207 238 247 319
NtSetSystemInformation 208 240 249 321
NtSetSystemPowerState 209 241 250 322
NtSetSystemTime 210 242 251 323
NtSetThreadExecutionState 211 243 252 324
NtSetTimer 212 244 253 325
NtSetTimerResolution 213 245 254 326
NtSetUuidSeed 214 246 255 327
NtSetValueKey 215 247 256 328
NtSetVolumeInformationFile 216 248 257 329
NtShutdownSystem 217 249 258 330
NtSignalAndWaitForSingleObject 218 250 259 331
NtStartProfile 219 251 260 332
NtStopProfile 220 252 261 333
NtSuspendThread 221 254 263 335
NtSystemDebugControl 222 255 264 336
NtTerminateJobObject 223 256 265 337
NtTerminateProcess 224 257 266 338
NtTerminateThread 225 258 267 339
NtTestAlert 226 259 268 340
NtUnloadDriver 227 262 271 346
NtUnloadKey 228 263 272 347
NtUnlockFile 229 265 275 350
NtUnlockVirtualMemory 230 266 276 351
NtUnmapViewOfSection 231 267 277 352
NtVdmControl 232 268 278 353
NtWaitForMultipleObjects 233 270 280 355
NtWaitForSingleObject 234 271 281 356
NtWaitHighEventPair 235 272 282 357
NtWaitLowEventPair 236 273 283 358
NtWriteFile 237 274 284 359
NtWriteFileGather 238 275 285 360
NtWriteRequestData 239 276 286 361
NtWriteVirtualMemory 240 277 287 362
NtYieldExecution 247 278 288 363
NtAddBootEntry - 9 9 9
NtCompactKeys - 27 29 50
NtCompareTokens - 28 30 51
NtCompressKey - 30 32 53
NtCreateDebugObject - 33 35 56
NtCreateJobSet - 40 42 63
NtCreateKeyedEvent - 279 289 364
NtCreateProcessEx - 48 50 73
NtDebugActiveProcess - 57 59 116
NtDebugContinue - 58 60 117
NtDeleteBootEntry - 61 63 120
NtEnumerateBootEntries - 70 73 131
NtEnumerateSystemEnvironmentValuesEx - 72 76 134
NtIsProcessInJob - 94 98 162
NtLockProductActivationKeys - 101 106 170
NtLockRegistryKey - 102 107 171
NtMakePermanentObject - 104 109 173
NtModifyBootEntry - 109 114 178
NtOpenKeyedEvent - 280 290 365
NtOpenProcessTokenEx - 124 130 196
NtOpenThreadTokenEx - 130 136 203
NtQueryBootEntryOrder - 140 146 213
NtQueryBootOptions - 141 147 214
NtQueryDebugFilterState - 142 148 215
NtQueryPortInformationProcess - 283 293 368
NtQuerySystemEnvironmentValueEx - 172 180 247
NtReleaseKeyedEvent - 281 291 366
NtRemoveProcessDebug - 191 199 266
NtRenameKey - 192 200 267
NtResumeProcess - 205 213 280
NtSaveKeyEx - 208 216 283
NtSetBootEntryOrder - 211 219 291
NtSetBootOptions - 212 220 292
NtSetDebugFilterState - 214 222 294
NtSetEventBoostPriority - 220 229 301
NtSetInformationDebugObject - 223 232 304
NtSetSystemEnvironmentValueEx - 239 248 320
NtSuspendProcess - 253 262 334
NtTraceEvent - 260 269 343
NtTranslateFilePath - 261 270 345
NtUnloadKeyEx - 264 274 349
NtWaitForDebugEvent - 269 279 354
NtWaitForKeyedEvent - 282 292 367
NtAddDriverEntry - - 10 10
NtApphelpCacheControl - - 19 40
NtDeleteDriverEntry - - 64 121
NtEnumerateDriverEntries - - 74 132
NtGetCurrentProcessorNumber - - 294 369
NtLoadKeyEx - - 104 168
NtModifyDriverEntry - - 115 179
NtQueryDriverEntryOrder - - 153 220
NtQueryOpenSubKeysEx - - 172 239
NtSetDriverEntryOrder - - 226 298
NtUnloadKey2 - - 273 348
NtWaitForMultipleObjects32 - - 295 370
NtAcquireCMFViewOwnership - - - 396
NtAlpcAcceptConnectPort - - - 19
NtAlpcCancelMessage - - - 20
NtAlpcConnectPort - - - 21
NtAlpcCreatePort - - - 22
NtAlpcCreatePortSection - - - 23
NtAlpcCreateResourceReserve - - - 24
NtAlpcCreateSectionView - - - 25
NtAlpcCreateSecurityContext - - - 26
NtAlpcDeletePortSection - - - 27
NtAlpcDeleteResourceReserve - - - 28
NtAlpcDeleteSectionView - - - 29
NtAlpcDeleteSecurityContext - - - 30
NtAlpcDisconnectPort - - - 31
NtAlpcImpersonateClientOfPort - - - 32
NtAlpcOpenSenderProcess - - - 33
NtAlpcOpenSenderThread - - - 34
NtAlpcQueryInformation - - - 35
NtAlpcQueryInformationMessage - - - 36
NtAlpcRevokeSecurityContext - - - 37
NtAlpcSendWaitReceivePort - - - 38
NtAlpcSetInformation - - - 39
NtCancelIoFileEx - - - 373
NtCancelSynchronousIoFile - - - 374
NtClearAllSavepointsTransaction - - - 286
NtClearSavepointTransaction - - - 285
NtCommitComplete - - - 95
NtCommitEnlistment - - - 87
NtCommitTransaction - - - 91
NtCreateEnlistment - - - 110
NtCreateKeyTransacted - - - 65
NtCreatePrivateNamespace - - - 69
NtCreateResourceManager - - - 106
NtCreateThreadEx - - - 388
NtCreateTransaction - - - 81
NtCreateTransactionManager - - - 100
NtCreateUserProcess - - - 389
NtCreateWorkerFactory - - - 381
NtDeletePrivateNamespace - - - 124
NtEnumerateTransactionObject - - - 135
NtFlushInstallUILanguage - - - 394
NtFlushProcessWriteBuffers - - - 143
NtFreezeRegistry - - - 148
NtFreezeTransactions - - - 149
NtGetMUIRegistryInfo - - - 395
NtGetNextProcess - - - 371
NtGetNextThread - - - 372
NtGetNlsSectionPtr - - - 153
NtGetNotificationResourceManager - - - 108
NtInitializeNlsFiles - - - 159
NtIsUILanguageComitted - - - 393
NtListTransactions - - - 392
NtMapCMFModule - - - 391
NtMarshallTransaction - - - 378
NtOpenEnlistment - - - 111
NtOpenKeyTransacted - - - 190
NtOpenPrivateNamespace - - - 192
NtOpenResourceManager - - - 107
NtOpenSession - - - 199
NtOpenTransaction - - - 82
NtOpenTransactionManager - - - 101
NtPrePrepareComplete - - - 93
NtPrePrepareEnlistment - - - 85
NtPrepareComplete - - - 94
NtPrepareEnlistment - - - 86
NtPropagationComplete - - - 379
NtPropagationFailed - - - 380
NtPullTransaction - - - 377
NtQueryInformationEnlistment - - - 113
NtQueryInformationResourceManager - - - 109
NtQueryInformationTransaction - - - 83
NtQueryInformationTransactionManager - - - 84
NtQueryInformationWorkerFactory - - - 385
NtQueryLicenseValue - - - 390
NtReadOnlyEnlistment - - - 88
NtRecoverEnlistment - - - 103
NtRecoverResourceManager - - - 104
NtRecoverTransactionManager - - - 105
NtRegisterProtocolAddressInformation - - - 376
NtReleaseCMFViewOwnership - - - 397
NtReleaseWorkerFactoryWorker - - - 382
NtRemoveIoCompletionEx - - - 375
NtRollbackComplete - - - 89
NtRollbackEnlistment - - - 90
NtRollbackSavepointTransaction - - - 287
NtRollbackTransaction - - - 92
NtRollforwardTransactionManager - - - 102
NtSavepointComplete - - - 289
NtSavepointTransaction - - - 288
NtSetInformationEnlistment - - - 112
NtSetInformationResourceManager - - - 99
NtSetInformationTransaction - - - 97
NtSetInformationTransactionManager - - - 98
NtSetInformationWorkerFactory - - - 384
NtShutdownWorkerFactory - - - 387
NtSinglePhaseReject - - - 96
NtStartTm - - - 114
NtThawRegistry - - - 341
NtThawTransactions - - - 342
NtTraceControl - - - 344
NtWaitForWorkViaWorkerFactory - - - 383
NtWorkerFactoryWorkerReady - - - 386
Заметьте, что Windows 2000 содержит меньше функций ядра, чем другие,
но поддерживает управление объектами Channel, поддержка которых убрана в
следующих ядрах ОС. Набор функций ядра в Windows XP практически совпадает
с Windows Server 2003. Windows Vista содержит много новых функций, которых
не было в предыдущих ОС.
Ссылки:
wasm.ru. Перехват функций в режиме ядра
Программы:
Консольная утилита, выводит таблицу с номерами системных функций в SDT
на основе ntdll.dll файлов от разных ОС (Windows 2000 / XP / 2003 / Vista).
Поддерживаются только x86-релизы файлов ntdll.dll
sdt
Доступен также исходный код программы, написанный мной на Си для компилятора
от Microsoft (можно использовать Platform SDK от Visual Studio 6 и выше):
sdt.zip