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

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

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

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

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

Посмотрим на функцию KLoaderReferenceModule
Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 477
Размер:	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
Просмотров: 410
Размер:	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
Просмотров: 371
Размер:	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
Просмотров: 359
Размер:	41.8 Кб
ID:	7575

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

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

Вот кто запускает драйвер ExecutionContext.sys через имя, указанное в реестре, открывая оный с помощью ядерной функции ZwOpenKey с соответствующими правами СИСТЕМЫ.
Ещё раз покажу раздел реестра, чтобы картинка полностью сложилась
Нажмите на изображение для увеличения
Название: 6.png
Просмотров: 338
Размер:	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
Комментарии
 
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru