Форум программистов, компьютерный форум, киберфорум
_lunar_
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Разбираемся в новом API KLoader. Часть 2: Deep Internal Research

Запись от _lunar_ размещена 04.06.2022 в 01:55
Показов 2197 Комментарии 0
Метки c, c++, winapi

Разбираемся в новом API KLoader. Часть 1: Общие сведения

Из первой части исследования стало известно, что в реестре Windows 11 есть раздел, который не доступен с правами администратора.
И чтобы узнать что в нём находится пришлось повысить права реестра до уровня СИСТЕМА.
Следовательно, такими мощными правами обладает собственно сама система (ОС) и драйверы уровня ядра.
Первое что потребуется сделать - определить какой драйвер вызывает этот ключ реестра и попытаться найти в глубинах его кода нужные данные.
Этот вызов содержит драйвер ndis.sys

Посмотрим на функцию KLoaderReferenceModule
Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 454
Размер:	22.0 Кб
ID:	7571

В современном программировании преобладают такие методы написания кода, как шаблоны, структуры и конечно же классы.
Даже не смотря на то, что это драйвер и здесь по логике должен превалировать классический Си.
Как видно имеется класс KLoader. Начал реверсить драйвер ndis.sys в части KLoader API.
Ссылка на репозиторий GitHub KLoader API

У этого класса есть функция-член ReferenceModule, которая принимает два аргумента a1 и v2 (первый a1 это просто this класса).
a1 - это структура KLOADER_REFERENCE_MODULE_CONFIG
v2 - это дескриптор KLOADER_MODULE_REFERENCE
Запомним это, т.к. дальнейшее углубление в дебри этого класса потребует сопоставления данных.

Перейдём в функцию ReferenceModule
Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 388
Размер:	49.6 Кб
ID:	7572

У класса KLoader есть ещё одна функция-член, но уже с индексом К (что намекает на исследуемую api) ReferenceKModule.
Разберёмся с аргументами функции:
qword_1C00EC190 - как я уже и говорил это всего лишь this: KLoader * и его учитывать не нужно
v16 - это внутренняя структура с именем класса KLockHolder (придираться к IDA не станем, правильное имя этой структуры я назову чуть позже)
v17 - это декларируемый дескриптор
C++
1
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
struct KModule *v17 и есть дескриптор KLOADER_MODULE_REFERENCE
(опять же не стоит придираться к IDA, дизассемблер итак делает много работы и полный автоматизм просто невозможен)
C++
1
2
DECLARE_HANDLE(KLOADER_MODULE_REFERENCE);
typedef KLOADER_MODULE_REFERENCE* PKLOADER_MODULE_REFERENCE;
Опустимся ещё глубже - в функцию ReferenceKModule
Нажмите на изображение для увеличения
Название: 3.png
Просмотров: 349
Размер:	67.1 Кб
ID:	7573

Во-первых обратите внимание на этот код
C++
1
2
3
4
5
KLockHolder v13{};
v13.m_State = Unlocked;
v13.m_Lock = (KPushLockBase *)this;
v13.m_Region.m_Entered = 0;
AcquireExclusive(&v13);
Теперь стали известны члены структуры KLockHolder. Но прежде чем продолжить нужно разобраться с понятийным блоком.
KLockHolder, как я уже говорил, это неправильное имя структуры. Правильное - KLOADER_REFERENCE_MODULE_CONFIG и вот её прототип
C++
1
2
3
4
5
typedef struct _KLOADER_REFERENCE_MODULE_CONFIG {
    KLOCK_HOLDER State;
    PKPUSH_LOCK Lock;
    KCRITICAL_REGION Region;
} KLOADER_REFERENCE_MODULE_CONFIG, * PKLOADER_REFERENCE_MODULE_CONFIG;
Я опущу некоторые моменты исследования, т.к. это скучная рутинная работа, и чтобы не забивать этой информацией блог сразу приведу прототипы членов структуры
C++
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
typedef enum _KLOCK_HOLDER {
    Unlocked = 0,
    Shared = 1,
    Exclusive = 2
} KLOCK_HOLDER, * PKLOCK_HOLDER;
 
typedef struct _KPUSH_LOCK {
    EX_PUSH_LOCK ExPushLock; // or EX_PUSH_LOCK from ntos.h
} KPUSH_LOCK, * PKPUSH_LOCK;
 
typedef struct _KCRITICAL_REGION {
    BOOLEAN Entered;
} KCRITICAL_REGION, * PKCRITICAL_REGION;
 
 
class KPushLockManualConstruct {
public:
    void Initialize(void);
};
 
 
KLOADER_REFERENCE_MODULE_CONFIG KModuleConfig{};
 
KModuleConfig.State = Unlocked;
KModuleConfig.Lock = (PKPUSH_LOCK)&KPushLockManualConstruct;
KModuleConfig.Region.Entered = FALSE;
KLOADER_REFERENCE_MODULE_CONFIG это основная структура, которая передаётся функции KLoaderReferenceModule.
В свою очередь функция KLoaderReferenceModule, после обработки данных из структуры, возвращает дескриптор KLOADER_MODULE_REFERENCE.

Затем вызывается внутренняя функция AcquireExclusive. Обратите внимание на её имя и на перечисление KLOCK_HOLDER -> Exclusive = 2
Я составил прототип этой функции и функции для Shared = 1 (хотя Shared применяется для самого ndis, а не для KLoader)
C++
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
#include <ntddk.h>
 
void AcquireExclusive(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    PKPUSH_LOCK Lock{};
 
    KeEnterCriticalRegion();
    Lock = pKModuleConfig->Lock;
    pKModuleConfig->Region.Entered = TRUE;
    ExAcquirePushLockExclusiveEx(&Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Exclusive;
}
 
void AcquireShared(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    PKPUSH_LOCK Lock{};
 
    KeEnterCriticalRegion();
    Lock = pKModuleConfig->Lock;
    pKModuleConfig->Region.Entered = TRUE;
    ExAcquirePushLockSharedEx(&Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Shared;
}
 
void ReleaseExclusive(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    ExReleasePushLockExclusiveEx(&pKModuleConfig->Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Unlocked;
    pKModuleConfig->Region.Entered = FALSE;
    KeLeaveCriticalRegion();
}
 
void ReleaseShared(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    ExReleasePushLockSharedEx(&pKModuleConfig->Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Unlocked;
    pKModuleConfig->Region.Entered = FALSE;
    KeLeaveCriticalRegion();
}
В двух словах, что здесь происходит:
сперва инициализируется структура KLOADER_REFERENCE_MODULE_CONFIG с разблокированной памятью - Unlocked
затем вызывается функция AcquireExclusive, где происходит следующая магия:
ядро переходит в защищенный регион - KeEnterCriticalRegion
вход в память Region.Entered меняется с FALSE на TRUE
далее инициализируется EX_PUSH_LOCK через процедуру ExAcquirePushLockExclusiveEx
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct _EX_PUSH_LOCK {
    union {
        struct {
            ULONG_PTR Locked : 1;
            ULONG_PTR Waiting : 1;
            ULONG_PTR Waking : 1;
            ULONG_PTR MultipleShared : 1;
            ULONG_PTR Shared : sizeof(ULONG_PTR) * 8 - 4;
        } s1;
        ULONG_PTR Value;
        PVOID Ptr;
    };
} EX_PUSH_LOCK, * PEX_PUSH_LOCK;
и регион памяти меняется на pKModuleConfig->State = Exclusive
Функция ReleaseExclusive возвращает всё на свои места и ядро выходит из защищенной области памяти через KeLeaveCriticalRegion.

Теперь перейдём к функции CreateKModule
Нажмите на изображение для увеличения
Название: 4.png
Просмотров: 334
Размер:	41.8 Кб
ID:	7575

Интерес в ней вызывает функция GetModuleServiceName, которая по сути получает имя сервиса, запускаемого через API KLoader.
Аргументом функции служит a1 - это структура GUID, которая является именем раздела KLoader 9C0B898D-6275-48EC-81B4-E5EDBE44B535 (см. первую часть).

Ну чтож, вот и финишная функция, которую мы искали круг замкнулся
Нажмите на изображение для увеличения
Название: 5.png
Просмотров: 383
Размер:	36.2 Кб
ID:	7576

Вот кто запускает драйвер ExecutionContext.sys через имя, указанное в реестре, открывая оный с помощью ядерной функции ZwOpenKey с соответствующими правами СИСТЕМЫ.
Ещё раз покажу раздел реестра, чтобы картинка полностью сложилась
Нажмите на изображение для увеличения
Название: 6.png
Просмотров: 322
Размер:	25.3 Кб
ID:	7577

Осталось выложить исходный код API KLoader (конечно же он неполный, и по мере возможности я буду его дополнять).

Файл KLoaderDef.h
C++
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
204
205
206
207
208
209
210
211
212
213
214
215
216
#ifndef _KLOADERDEF_H_
#define _KLOADERDEF_H_
#pragma once
 
#include <ntddk.h>
 
 
#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM                  (L"SharedMemoryAllocationDurationHistogram");
#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_AUTO_RESET       (L"SharedMemoryAllocationDurationHistogramAutoReset");
#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_MAX_HISTOGRAMS   (L"SharedMemoryAllocationDurationHistogramMaxHistograms");
#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_START            (L"SharedMemoryAllocationDurationHistogramStart");
#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_NUM_INTERVALS    (L"SharedMemoryAllocationDurationHistogramNumIntervals");
#define SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_INTERVAL_LENGTH  (L"SharedMemoryAllocationDurationHistogramIntervalLength");
 
 
DECLARE_HANDLE(KLOADER_MODULE_REFERENCE);
typedef KLOADER_MODULE_REFERENCE* PKLOADER_MODULE_REFERENCE;
 
 
typedef enum _PAUSE_OR_RESTART {
    DatapathPaused = 0,
    DatapathRunning = 1
} PAUSE_OR_RESTART, * PPAUSE_OR_RESTART;
 
typedef enum _EXECUTION_CONTEXT_FLAGS {
    ExecutionContextFlagNone = 0,
    ExecutionContextFlagRunDpcForFirstLoop = 1,
    ExecutionContextFlagRunWorkerThreadAtDispatch = 2,
    ExecutionContextFlagTryExtendMaxTimeAtDispatch = 4
} EXECUTION_CONTEXT_FLAGS, * PEXECUTION_CONTEXT_FLAGS;
 
typedef enum _CONFIG_KNOB_NAMESPACE_TYPE {
    ConfigKnobNamespaceNdisGlobal = 0,
    ConfigKnobNamespaceNetworkInterface = 1,
    ConfigKnobNamespaceExecutionContext = 2
} CONFIG_KNOB_NAMESPACE_TYPE, * PCONFIG_KNOB_NAMESPACE_TYPE;
 
typedef enum _KLOCK_HOLDER {
    Unlocked = 0,
    Shared = 1,
    Exclusive = 2
} KLOCK_HOLDER, * PKLOCK_HOLDER;
 
typedef enum _CONFIG_KNOB_FLAG {
    OnlyUpdateOnceAtBoot = 0,
    Uint32Datatype = 0,
    BooleanDatatype = 2,
    Uint64Datatype = 4,
    AllowDynamicUpdate = 32,
    MustBePowerOfTwo = 64
} CONFIG_KNOB_FLAG, * PCONFIG_KNOB_FLAG;
 
 
typedef struct _CONFIG_KNOB_NAMESPACE {
    CONFIG_KNOB_NAMESPACE_TYPE NamespaceType;
    GUID ObjectId;
} CONFIG_KNOB_NAMESPACE, * PCONFIG_KNOB_NAMESPACE;
 
typedef struct _EXECUTION_CONTEXT_WORK_UNIT_KNOBS {
    ULONG AtPassive;
    ULONG AtDispatch;
} EXECUTION_CONTEXT_WORK_UNIT_KNOBS, * PEXECUTION_CONTEXT_WORK_UNIT_KNOBS;
 
typedef struct _EXECUTION_CONTEXT_RUNTIME_KNOBS {
    ULONG Size;
    EXECUTION_CONTEXT_FLAGS Flags;
    ULONG MaxTimeAtDispatch;
    ULONG DispatchTimeWarning;
    ULONG DispatchTimeWarningInterval;
    ULONG DpcWatchdogTimerThreshold;
    ULONG WorkerThreadPriority;
    EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsSend;
    EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsSendComplete;
    EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsReceive;
    EXECUTION_CONTEXT_WORK_UNIT_KNOBS MaxPacketsReceiveComplete;
} EXECUTION_CONTEXT_RUNTIME_KNOBS, * PEXECUTION_CONTEXT_RUNTIME_KNOBS;
 
typedef struct _KREG_KEY {
    PVOID ptr;
} KREG_KEY, * PKREG_KEY;
 
typedef struct _KARRAY {
    ULONG bufferSize;
    ULONG numElements;
    PVOID _p;
} KARRAY, * PKARRAY;
 
typedef struct _KCRITICAL_REGION {
    BOOLEAN Entered;
} KCRITICAL_REGION, * PKCRITICAL_REGION;
 
typedef struct _BIND_STATE {
    PVOID Miniport;
    BOOLEAN AllowBindDespiteMandatory;
    BOOLEAN PretendBindingActive;
    BOOLEAN NeedsPauseAction;
    PVOID AdditionalContext;
    ULONG LastErrorCode;
    ULONG bindSources;
    ULONG unbindReasons;
    ULONG pauseReasons;
    PAUSE_OR_RESTART actualPauseState;
    KARRAY bindContext;
} BIND_STATE, * PBIND_STATE;
 
typedef struct _KSPIN_LOCK_2 {
    KARRAY Protocols;
    KARRAY Filters;
    BIND_STATE Miniport;
    ULONG ChangeEpoch;
} KSPIN_LOCK_2, * PKSPIN_LOCK_2;
 
typedef struct _KACQUIRE_SPIN_LOCK {
    KIRQL oldIrql;
    KSPIN_LOCK_2 lock;  // or KSPIN_LOCK from ntddk.h
} KACQUIRE_SPIN_LOCK, * PKACQUIRE_SPIN_LOCK;
 
typedef struct _KPUSH_LOCK {
    EX_PUSH_LOCK ExPushLock; // or EX_PUSH_LOCK from ntos.h
} KPUSH_LOCK, * PKPUSH_LOCK;
 
typedef struct _KNOB_DESCRIPTOR {
    LPCTSTR Name;   // SHARED_MEMORY_ALLOC_DURATION_HISTOGRAM_
    PVOID Value;
    ULONG_PTR DefaultValue;
    CONFIG_KNOB_FLAG Flags;
    ULONG_PTR MinimumValue;
    ULONG_PTR MaximumValue;
} KNOB_DESCRIPTOR, * PKNOB_DESCRIPTOR;
 
 
typedef struct _KLOADER_MODULE_CHARACTERISTICS {
    DRIVER_OBJECT driverObject;
    CONFIG_KNOB_NAMESPACE id;
    LIST_ENTRY globalLinkage;
    LIST_ENTRY collectionList;
    KPUSH_LOCK lock;
} KLOADER_MODULE_CHARACTERISTICS, * PKLOADER_MODULE_CHARACTERISTICS;
 
typedef struct _KLOADER_REFERENCE_MODULE_CONFIG {
    KLOCK_HOLDER State;
    PKPUSH_LOCK Lock;
    KCRITICAL_REGION Region;
} KLOADER_REFERENCE_MODULE_CONFIG, * PKLOADER_REFERENCE_MODULE_CONFIG;
 
 
class KPushLockManualConstruct {
public:
    void Initialize(void);
};
 
void AcquireExclusive(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    PKPUSH_LOCK Lock{};
 
    KeEnterCriticalRegion();
    Lock = pKModuleConfig->Lock;
    pKModuleConfig->Region.Entered = TRUE;
    ExAcquirePushLockExclusiveEx(&Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Exclusive;
}
 
void AcquireShared(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    PKPUSH_LOCK Lock{};
 
    KeEnterCriticalRegion();
    Lock = pKModuleConfig->Lock;
    pKModuleConfig->Region.Entered = TRUE;
    ExAcquirePushLockSharedEx(&Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Shared;
}
 
void ReleaseExclusive(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    ExReleasePushLockExclusiveEx(&pKModuleConfig->Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Unlocked;
    pKModuleConfig->Region.Entered = FALSE;
    KeLeaveCriticalRegion();
}
 
void ReleaseShared(PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig)
{
    ExReleasePushLockSharedEx(&pKModuleConfig->Lock->ExPushLock, EX_DEFAULT_PUSH_LOCK_FLAGS);
    pKModuleConfig->State = Unlocked;
    pKModuleConfig->Region.Entered = FALSE;
    KeLeaveCriticalRegion();
}
 
 
_IRQL_requires_max_(PASSIVE_LEVEL)
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderRegisterModule(
    _In_ PDRIVER_OBJECT pDriverObject,
    _In_ PUNICODE_STRING pRegistryPath,
    _In_opt_ PVOID arg3,
    _In_ PKLOADER_MODULE_CHARACTERISTICS pKModuleCharacts);
 
_IRQL_requires_max_(PASSIVE_LEVEL)
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderReferenceModule(
    _In_ PKLOADER_REFERENCE_MODULE_CONFIG pKModuleConfig,
    _Out_ PKLOADER_MODULE_REFERENCE* ppKModule);
 
_IRQL_requires_max_(PASSIVE_LEVEL)
NTKERNELAPI
NTSTATUS
FASTCALL
KLoaderDereferenceModule(
    _In_ PKLOADER_MODULE_REFERENCE pKModule);
 
#endif // _KLOADERDEF_H_
Файл Source.cpp
C++
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
#include "KLoaderDef.h"
 
 
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
    NTSTATUS Status = NULL, ModuleDevice = NULL;
    PKLOADER_MODULE_REFERENCE pKModule = nullptr;
    KLOADER_REFERENCE_MODULE_CONFIG KModuleConfig{};
 
    KModuleConfig.State = Unlocked;
    KModuleConfig.Lock = (PKPUSH_LOCK)&KPushLockManualConstruct;
    KModuleConfig.Region.Entered = FALSE;
 
    AcquireExclusive(&KModuleConfig);
    Status = KLoaderReferenceModule(&KModuleConfig, &pKModule);
    ReleaseExclusive(&KModuleConfig);
 
    //=========================================================================================
 
    UNICODE_STRING DestinationString{};
    KLOADER_MODULE_CHARACTERISTICS KModuleCharacts{};
 
    KModuleCharacts.id.NamespaceType = ConfigKnobNamespaceExecutionContext;
    
    RtlInitUnicodeString(&DestinationString, L"WmiTraceMessage");
    KModuleCharacts.driverObject.DeviceObject->Queue.Wcb.DeviceObject =
        MmGetSystemRoutineAddress(&DestinationString);
 
    KModuleConfig.State = Unlocked;
    KModuleConfig.Lock = (PKPUSH_LOCK)&KPushLockManualConstruct;
    KModuleConfig.Region.Entered = FALSE;
 
    AcquireExclusive(&KModuleConfig);
    ModuleDevice = KLoaderRegisterModule(DriverObject, RegistryPath, nullptr, &KModuleCharacts);
    ReleaseExclusive(&KModuleConfig);
 
    //=========================================================================================
 
    KModuleConfig.State = Unlocked;
    KModuleConfig.Lock = (PKPUSH_LOCK)&KPushLockManualConstruct;
    KModuleConfig.Region.Entered = FALSE;
 
    AcquireExclusive(&KModuleConfig);
    Status = KLoaderDereferenceModule(pKModule);
    ReleaseExclusive(&KModuleConfig);
 
    return 0;
}


Небольшой бонус по тегам пула памяти
C++
1
2
3
PoolWithTag = ExAllocatePoolWithTag(PagedPool, 0x20, 0x62694C4E);
 
ExFreePoolWithTag(v24, 0x7274534B);
Идём на MSDN ExAllocatePoolWithTag и смотрим как определяется тег
The pool tag to use for the allocated memory. Specify the pool tag as a non-zero character literal of one to to four characters delimited by single quotation marks (for example, 'Tag1'). The string is usually specified in reverse order (for example, '1gaT'). Each ASCII character in the tag must be a value in the range 0x20 (space) to 0x7E (tilde). Each allocation code path should use a unique pool tag to help debuggers and verifiers identify the code path.
Берём таблицу символов ASCII
Code
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
Char  Dec  Oct  Hex | Char  Dec  Oct  Hex | Char  Dec  Oct  Hex | Char Dec  Oct   Hex
-------------------------------------------------------------------------------------
(nul)   0 0000 0x00 | (sp)   32 0040 0x20 | @      64 0100 0x40 | `      96 0140 0x60
(soh)   1 0001 0x01 | !      33 0041 0x21 | A      65 0101 0x41 | a      97 0141 0x61
(stx)   2 0002 0x02 | "      34 0042 0x22 | B      66 0102 0x42 | b      98 0142 0x62
(etx)   3 0003 0x03 | #      35 0043 0x23 | C      67 0103 0x43 | c      99 0143 0x63
(eot)   4 0004 0x04 | $      36 0044 0x24 | D      68 0104 0x44 | d     100 0144 0x64
(enq)   5 0005 0x05 | %      37 0045 0x25 | E      69 0105 0x45 | e     101 0145 0x65
(ack)   6 0006 0x06 | &      38 0046 0x26 | F      70 0106 0x46 | f     102 0146 0x66
(bel)   7 0007 0x07 | '      39 0047 0x27 | G      71 0107 0x47 | g     103 0147 0x67
(bs)    8 0010 0x08 | (      40 0050 0x28 | H      72 0110 0x48 | h     104 0150 0x68
(ht)    9 0011 0x09 | )      41 0051 0x29 | I      73 0111 0x49 | i     105 0151 0x69
(nl)   10 0012 0x0a | *      42 0052 0x2a | J      74 0112 0x4a | j     106 0152 0x6a
(vt)   11 0013 0x0b | +      43 0053 0x2b | K      75 0113 0x4b | k     107 0153 0x6b
(np)   12 0014 0x0c | ,      44 0054 0x2c | L      76 0114 0x4c | l     108 0154 0x6c
(cr)   13 0015 0x0d | -      45 0055 0x2d | M      77 0115 0x4d | m     109 0155 0x6d
(so)   14 0016 0x0e | .      46 0056 0x2e | N      78 0116 0x4e | n     110 0156 0x6e
(si)   15 0017 0x0f | /      47 0057 0x2f | O      79 0117 0x4f | o     111 0157 0x6f
(dle)  16 0020 0x10 | 0      48 0060 0x30 | P      80 0120 0x50 | p     112 0160 0x70
(dc1)  17 0021 0x11 | 1      49 0061 0x31 | Q      81 0121 0x51 | q     113 0161 0x71
(dc2)  18 0022 0x12 | 2      50 0062 0x32 | R      82 0122 0x52 | r     114 0162 0x72
(dc3)  19 0023 0x13 | 3      51 0063 0x33 | S      83 0123 0x53 | s     115 0163 0x73
(dc4)  20 0024 0x14 | 4      52 0064 0x34 | T      84 0124 0x54 | t     116 0164 0x74
(nak)  21 0025 0x15 | 5      53 0065 0x35 | U      85 0125 0x55 | u     117 0165 0x75
(syn)  22 0026 0x16 | 6      54 0066 0x36 | V      86 0126 0x56 | v     118 0166 0x76
(etb)  23 0027 0x17 | 7      55 0067 0x37 | W      87 0127 0x57 | w     119 0167 0x77
(can)  24 0030 0x18 | 8      56 0070 0x38 | X      88 0130 0x58 | x     120 0170 0x78
(em)   25 0031 0x19 | 9      57 0071 0x39 | Y      89 0131 0x59 | y     121 0171 0x79
(sub)  26 0032 0x1a | :      58 0072 0x3a | Z      90 0132 0x5a | z     122 0172 0x7a
(esc)  27 0033 0x1b | ;      59 0073 0x3b | [      91 0133 0x5b | {     123 0173 0x7b
(fs)   28 0034 0x1c | <      60 0074 0x3c | \      92 0134 0x5c | |     124 0174 0x7c
(gs)   29 0035 0x1d | =      61 0075 0x3d | ]      93 0135 0x5d | }     125 0175 0x7d
(rs)   30 0036 0x1e | >      62 0076 0x3e | ^      94 0136 0x5e | ~     126 0176 0x7e
(us)   31 0037 0x1f | ?      63 0077 0x3f | _      95 0137 0x5f | (del) 127 0177 0x7f
и переводим значения 0x62694C4E и 0x7274534B по правилам, указанным в аннотации к функции ExAllocatePoolWithTag
0x62 = b
0x69 = i
0x4C = L
0x4E = N

0x72 = r
0x74 = t
0x53 = S
0x4B = K

biLN и rtSK читаем в обратном порядке и получаем NLib и KStr
Метки c, c++, winapi
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru