Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9

список объектов ядра Windows

27.11.2013, 16:00. Показов 2375. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Господа, хотел задать вам вопрос, с надеждой получить на него какой-нибудь исчерпывающий ответ или совет или что угодно другое, лишь бы помогло мне в моей нелегкой для задаче.

вообщем ситуация такова, что у меня появилось задание, в рамках которого надо получить список объектов ядра Винды и показать права доступа к ним(если кому-то может интересно или важно, вот как звучит задание из первых уст "Написать программу на языке Си/Си++, выполняющую получение списка объектов ядра Windows и отображение прав доступа (списков контроля доступа) к ним.")

так вот собственно дело в том, что, исходя из моих наблюдений, задачи такого рода делаются с помощью функций NtQuerySystemInformation, NtQueryDirectoryObject и NtOpenDirectoryObject входящих в состав NTDLL.DLL.
Порылся и примерно понял, как этими функциями пользоваться, но общей картины все равно нет до сих пор, вероятнее всего потому что мне раньше с WinAPI никогда не приходилось сталкиваться.

вообщем буду очень надеяться на вашу помощь, ребята.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.11.2013, 16:00
Ответы с готовыми решениями:

Список объектов ядра Windows
Всем доброго времени суток! Есть следующее задание: "написать программу на языке Си/Си++, выполняющую получение списка объектов ядра...

Список объектов ядра
Доброго времени суток. Есть цель: получение списка объектов ядра. Какие функции/библиотеки лучше использовать? Заранее спасибо.

Синхронизация на базе объектов ядра
Help me! Необходимо написать курсовик на тему синхронизация на базе объектов ядра! Но не хватает фантазии какую именно написать программу с...

17
267 / 189 / 33
Регистрация: 15.01.2011
Сообщений: 681
27.11.2013, 16:21
из r3 полноценной картины получить не получится , но кое что можно вытянуть тут есть кое что по теме.

Добавлено через 9 минут
вот кодец , спионеренный с wasm.ru не проверял но может подойти.
rights.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
#include <windows.h>
#include <stdio.h>
#include <Sddl.h>
 
#define NT_SUCCESS(inpNumber) ((inpNumber) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
 
#define SystemHandleInformation 16
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2
 
typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength
    );
typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
    HANDLE SourceProcessHandle,
    HANDLE SourceHandle,
    HANDLE TargetProcessHandle,
    PHANDLE TargetHandle,
    ACCESS_MASK DesiredAccess,
    ULONG Attributes,
    ULONG Options
    );
typedef NTSTATUS (NTAPI *_NtQueryObject)(
    HANDLE ObjectHandle,
    ULONG ObjectInformationClass,
    PVOID ObjectInformation,
    ULONG ObjectInformationLength,
    PULONG ReturnLength
    );
 
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
 
typedef struct _SYSTEM_HANDLE
{
    ULONG ProcessId;
    BYTE ObjectTypeNumber;
    BYTE Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
 
typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG HandleCount;
    SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
 
typedef enum _POOL_TYPE
{
    NonPagedPool,
    PagedPool,
    NonPagedPoolMustSucceed,
    DontUseThisType,
    NonPagedPoolCacheAligned,
    PagedPoolCacheAligned,
    NonPagedPoolCacheAlignedMustS
} POOL_TYPE, *PPOOL_TYPE;
 
typedef struct _OBJECT_TYPE_INFORMATION
{
    UNICODE_STRING Name;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG TotalPagedPoolUsage;
    ULONG TotalNonPagedPoolUsage;
    ULONG TotalNamePoolUsage;
    ULONG TotalHandleTableUsage;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    ULONG HighWaterPagedPoolUsage;
    ULONG HighWaterNonPagedPoolUsage;
    ULONG HighWaterNamePoolUsage;
    ULONG HighWaterHandleTableUsage;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccess;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    USHORT MaintainTypeList;
    POOL_TYPE PoolType;
    ULONG PagedPoolUsage;
    ULONG NonPagedPoolUsage;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
{
    return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает строку наоборот
void Reverse(char s[])
{
    int i, j;
    char c;
 
    for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Перевод строки из 10сс в 2сс
char * IntToBinary(int inpNumber)
{
    static char outStr[32];
    memset(outStr, 0, 32);
    outStr[32] = '\0';
 
    outStr[0] = inpNumber & 0xa000000;
 
    for (int step = 0; step <= 31; step++, inpNumber >>= 1)
    {
        if (inpNumber & 0x1 == 1)
            strcat(outStr, "1");
        else
            strcat(outStr, "0");
    }
    Reverse(outStr);
    static char endStr[33];
    memset(endStr, 32, 33);
    strncpy(endStr, outStr, 16);
    strncpy(endStr+17, outStr+16, 16);
    return endStr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Пробуем повысить привилегии
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa446619
BOOL SetPrivilege(
    HANDLE hToken,          //хэндл процесса для установки
    LPCTSTR lpszPrivilege,  //какую будем устанавливать
    BOOL bEnablePrivilege   //установить или снять
    ) 
{
    TOKEN_PRIVILEGES tp;
    LUID luid;
 
    //Получим LUID
    if ( !LookupPrivilegeValue( 
        NULL,
        lpszPrivilege,
        &luid ) )
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return FALSE; 
    }
 
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;
 
    if ( !(AdjustTokenPrivileges(
        hToken, 
        FALSE, 
        &tp, 
        sizeof(TOKEN_PRIVILEGES), 
        (PTOKEN_PRIVILEGES) NULL, 
        (PDWORD) NULL) ))
    { 
        printf("AdjustTokenPrivileges GetLastError: %u\n", GetLastError() ); 
        //попробуем дальше без повышения
        return FALSE; 
    } 
    //всё ок, получили повышение!
    return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void PrintToFile(FILE *f, POBJECT_TYPE_INFORMATION objectTypeInfo)
{
    fprintf(f, "GENERIC READ:\t%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericRead));
    fprintf(f, "GENERIC WRITE:\t%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericWrite));
    fprintf(f, "GENERIC EXECUTE:%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericExecute));
    fprintf(f, "GENERIC ALL:\t%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericAll));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

rights.c
Кликните здесь для просмотра всего текста

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
#include "rights.h"
 
int wmain(int argc, WCHAR *argv[])
{
    //Импортим из библиотек Native-API функции
    _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)
        GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
    _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)
        GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
    _NtQueryObject NtQueryObject = (_NtQueryObject)
        GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
 
    HANDLE hToken = NULL;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
    SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
    //SetPrivilege(hToken, SE_TCB_NAME, TRUE);
 
    NTSTATUS status;
    PSYSTEM_HANDLE_INFORMATION handleInfo;
    ULONG handleInfoSize = 0x10000;
    ULONG pid;
    HANDLE processHandle;
 
    //Получено ли значение требуемого процесса
    if (argc < 2)
    {
        printf("Give me PID through the console\n");
        return 1;
    }
 
    pid = _wtoi(argv[1]);
 
    //Пробуем подсоединиться к процессу, чтобы получить скопировать его хэндл
    if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)))
    {
        DWORD q = GetLastError();
        printf("Could not open PID %d! Error: %d\n", pid, q);
        return 1;
    }
 
    FILE *fToPrint;
    //a - открыть для ДОзаписи, или создать для записи, если файла нет
    //w - перезапись по новой
    fToPrint = fopen("output.txt", "w");
    fprintf(fToPrint, "For process: %d\n", pid);
    handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
 
    //Подгнояем размер буфера
    while ((status = NtQuerySystemInformation(
        SystemHandleInformation,
        handleInfo,
        handleInfoSize,
        NULL
        )) == STATUS_INFO_LENGTH_MISMATCH)
        handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
 
    //NtQuerySystemInformation не вернула STATUS_INFO_LENGTH_MISMATCH
    if (!NT_SUCCESS(status))
    {
        printf("NtQuerySystemInformation failed!\n");
        return 1;
    }
 
    for (ULONG i = 0; i < handleInfo->HandleCount; i++)
    {
        SYSTEM_HANDLE handle = handleInfo->Handles[i];
 
        //только если подходит идентификатор - наш процесс
        if (pid != handle.ProcessId)
        {
            continue;
        }
 
        HANDLE dupHandle = NULL;
        POBJECT_TYPE_INFORMATION objectTypeInfo;
        PVOID objectNameInfo;
        UNICODE_STRING objectName;
        ULONG returnLength;
 
        //Копируем объект в свое адресное пространство
        if (!NT_SUCCESS(NtDuplicateObject(
            processHandle,
            (HANDLE)handle.Handle,
            GetCurrentProcess(),
            &dupHandle,
            0,
            0,
            0
            )))
        {
            //Память не выделилась, убираться за собой не нужно, переходим к следующему
            continue;
        }
 
        //Тащим информацию из объекта
        objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectTypeInformation,
            objectTypeInfo,
            0x1000,
            NULL
            )))
        {
            //В случае ошибки - чистим память за собой
            CloseHandle(dupHandle);
            continue;
        }
 
        //Извлекаем инфу об имени
        //Если закончится неудачно - в returnLength вернется нужное количество и мы вызовем ещё раз, только уже с адекватной длиной
        objectNameInfo = malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectNameInformation,
            objectNameInfo,
            0x1000,
            &returnLength
            )))
        {
            //returnLength адекватна для получения
            objectNameInfo = realloc(objectNameInfo, returnLength);
            if (!NT_SUCCESS(NtQueryObject(
                dupHandle,
                ObjectNameInformation,
                objectNameInfo,
                returnLength,
                NULL
                )))
            {
                //Не удалось получить имя
                fprintf(fToPrint, 
                    "[%#x] %.*S: (can't get name)\n",
                    handle.Handle,
                    objectTypeInfo->Name.Length / 2,
                    objectTypeInfo->Name.Buffer
                    );
                PrintToFile(fToPrint, objectTypeInfo);
 
                free(objectTypeInfo);
                free(objectNameInfo);
                CloseHandle(dupHandle);
                continue;
            }
        }
        //Имя есть,
        //переведем в строку Юникода
        objectName = *(PUNICODE_STRING)objectNameInfo;
        
        if (objectName.Length)
        {
            DWORD len;
            long buf[1024];
            PSECURITY_DESCRIPTOR desc = (PSECURITY_DESCRIPTOR)buf;
            DWORD length = sizeof(desc);
 
            fprintf(fToPrint, 
                "[%#x] %.*S: %.*S\n",
                handle.Handle,
                objectTypeInfo->Name.Length / 2,
                objectTypeInfo->Name.Buffer,
                objectName.Length / 2,
                objectName.Buffer
                );
            PrintToFile(fToPrint, objectTypeInfo);
        }
        else
        {
            //Объект безымянен
            fprintf(fToPrint, 
                "[%#x] %.*S: (unnamed)\n",
                handle.Handle,
                objectTypeInfo->Name.Length / 2,
                objectTypeInfo->Name.Buffer
                );
            PrintToFile(fToPrint, objectTypeInfo);
        }
 
        //Подчищаем память
        free(objectTypeInfo);
        free(objectNameInfo);
        CloseHandle(dupHandle);
    }
 
    free(handleInfo);
    CloseHandle(processHandle);
 
    return 0;
}
1
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
27.11.2013, 16:39  [ТС]
большое спасибо)

код я видел, но понимаю его процентов на 30)

был бы очень благодарен, если бы нашелся человек, который сможет пообильнее откомментить то, что тут написано, тогда думаю сложится картина.
0
267 / 189 / 33
Регистрация: 15.01.2011
Сообщений: 681
27.11.2013, 17:05
этот кодец только с виду такой страшный ) , для лучшего понимания погоняйте его под отладчиком и тогда будет видно что куда и на каком этапе происходит.
0
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
27.11.2013, 17:28  [ТС]
Цитата Сообщение от ssXXss Посмотреть сообщение
этот кодец только с виду такой страшный ) , для лучшего понимания погоняйте его под отладчиком и тогда будет видно что куда и на каком этапе происходит.

ну это мнение человека, который имел дело с WinAPI, а для меня этот код почти, как темный лес)

там что для меня лучше все-таки, чтобы кто-то откомментил)
но гонять я его разумеется буду, куда денусь)
0
267 / 189 / 33
Регистрация: 15.01.2011
Сообщений: 681
27.11.2013, 18:01
я бы посоветовал почитать вначале литературу ,к примеру Внутренне устройство Windows Русиновича-Соломона
Недокументированные возможности Windows 2000 Шрайбер мануальчик староват но актуальности не потерял, ну и конечно Создание эффективных WIN32-приложений с учётом специфики 64-разрядной версии Windows Джеффри РИХТЕР документированные вещи надо брать в первую очередь у разработчиков то бишь заглянуть в MSDN путь конечно не быстрый . зато проверенный) .
0
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
27.11.2013, 18:25  [ТС]
ssXXss, Рихтера я уже себе скачал, буду разбираться

я бы собственно так и сделал, как вы сказали, вот только у меня всего неделя на выполнение, вот в чем загвоздка(
поэтому, как вы понимаете, мне гораздо проще попытаться просто найти и как следует вникнуть в работу какого-нибудь уже имеющегося кода по такого рода заданию, потому что в будущем с WinAPI мне, вероятнее всего. больше не придется сталкиваться)
0
267 / 189 / 33
Регистрация: 15.01.2011
Сообщений: 681
27.11.2013, 18:37
как говорится - " дорогу осилит идущий ", вот еще ссылка не заглядывал но вроде есть сорцы Windows Process Manager может чем и поможет.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.11.2013, 22:12
Цитата Сообщение от Giddeon Посмотреть сообщение
Написать программу на языке Си/Си++, выполняющую получение списка объектов ядра Windows и отображение прав доступа (списков контроля доступа) к ним.
Сразу скажу, что, во-первых, из режима пользователя можно в большинстве случаев
читать только именованные объекты ядра, а во-вторых, значительная часть
этой информации недокументированна и может меняться между версиями Windows.
Вот здесь я кое-что описывал по теме (капля в море): Модуль ядра для windows
1
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
28.11.2013, 09:43  [ТС]
Убежденный, да, я читал ваш топик, там все очень хорошо описано)
из-за вас как раз и создалось хоть какое впечатление о то, что и как
Но, к сожалению, полной картины, или хотя бы достаточной для написания какого-то кода, у меня не сложилось
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2013, 01:24
Цитата Сообщение от Giddeon Посмотреть сообщение
Но, к сожалению, полной картины, или хотя бы достаточной для написания какого-то кода, у меня не сложилось
Именованные объекты ядра организованы в иерархическую структуру, как файлы и папки.
В каждой такой папке будут объекты ядра одного или нескольких определенных типов.
Чтобы лучше осознать эту картину, скачайте и запустите утилиту WinObj из Sysinternals.

Вам нужно с помощью NtOpenDirectoryObject открыть корневую папку этой структуры, а
затем выполнить рекурсивное перечисление объектов и папок, которые в ней находятся,
для этого существует другая функция - NtQueryDirectoryObject. Каждый найденный
элемент будет или объектом ядра или очередной папкой, на которую следует
распостранить перечисление.

Win32 API здесь не помощник, здесь придется использовать в основном Nt-функции и
внутренние структуры, объявленные в заголовке Winternl.h. Также я бы посоветовал
раскопать известные исходники Windows (NT4/W2K/WRK) и за такими вопросами
заглядывать туда.
0
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
29.11.2013, 15:20  [ТС]
Убежденный, спасибо, буду пробовать

я тут еще подумал, что можно можно в цикле просто перебрать, через GetKernelObjectSecurity.

этот вариант вообще нормальный, или лучше не пытаться?

Добавлено через 12 минут
вроде такого
C++
1
2
3
4
5
for (int i=0; i<9999; i++)
    GetKernelObjectSecurity( i, ... ) //result in security_descriptor
    GetSecurityDescriptorDacl( security_descriptor, ... ) // result in lpbDaclPresent
    if (lpbDaclPresent)
        //lpbDaclPresent - need to get
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2013, 18:02
Цитата Сообщение от Giddeon Посмотреть сообщение
я тут еще подумал, что можно можно в цикле просто перебрать, через GetKernelObjectSecurity.
этот вариант вообще нормальный, или лучше не пытаться?
HANDLE имеет размер указателя, т.е. 32 бита на x84 и 64 на x64.
Перебирать можно о-очень долго...
1
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
29.11.2013, 18:32  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
HANDLE имеет размер указателя, т.е. 32 бита на x84 и 64 на x64.
Перебирать можно о-очень долго...
но ведь в теории так можно?

мне просто интересно
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
29.11.2013, 19:07
Цитата Сообщение от Giddeon Посмотреть сообщение
но ведь в теории так можно?
Можно. Но данным кодом Вы добъетесь лишь того, что получите информацию
об объектах, открытых в контексте текущего процесса, не более.
1
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
02.12.2013, 01:38  [ТС]
Убежденный, а какую именно информацию?
не ту ли, которая мне нужна?)

и, если нет, то нет ли способа, как-нибудь по похожему принципу вывести то, что по заданию нужно мне?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
02.12.2013, 09:18
Цитата Сообщение от Giddeon Посмотреть сообщение
Убежденный, а какую именно информацию?
Ту, что выдают GetKernelObjectSecurity и GetSecurityDescriptorDacl.

Цитата Сообщение от Giddeon Посмотреть сообщение
не ту ли, которая мне нужна?)
Я же говорю - используя этот "брутфорс", можно получить информацию
только об объектах ядра, которые открыты в контексте текущего процесса.

Цитата Сообщение от Giddeon Посмотреть сообщение
и, если нет, то нет ли способа, как-нибудь по похожему принципу вывести то, что по заданию нужно мне?
Способ был описан несколькими сообщениями выше, добавить к этому нечего.
0
0 / 0 / 0
Регистрация: 27.11.2013
Сообщений: 9
02.12.2013, 21:29  [ТС]
Убежденный, был бы очень признателен, если бы вы привели пример кода, написанного исходя из вашего способа.
просто очень хочется разобраться, что да как, а на словах я всю жизнь как-то туго понимал.
на конкретных примерах всегда проще

заранее благодарен!

Добавлено через 7 часов 43 минуты
мог бы кто-нибудь дать список библиотек, необходимых, чтобы это запустилось?
буду очень признателен


Цитата Сообщение от ssXXss Посмотреть сообщение
вот кодец , спионеренный с wasm.ru не проверял но может подойти.
rights.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
#include <windows.h>
#include <stdio.h>
#include <Sddl.h>
 
#define NT_SUCCESS(inpNumber) ((inpNumber) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
 
#define SystemHandleInformation 16
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2
 
typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength
    );
typedef NTSTATUS (NTAPI *_NtDuplicateObject)(
    HANDLE SourceProcessHandle,
    HANDLE SourceHandle,
    HANDLE TargetProcessHandle,
    PHANDLE TargetHandle,
    ACCESS_MASK DesiredAccess,
    ULONG Attributes,
    ULONG Options
    );
typedef NTSTATUS (NTAPI *_NtQueryObject)(
    HANDLE ObjectHandle,
    ULONG ObjectInformationClass,
    PVOID ObjectInformation,
    ULONG ObjectInformationLength,
    PULONG ReturnLength
    );
 
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
 
typedef struct _SYSTEM_HANDLE
{
    ULONG ProcessId;
    BYTE ObjectTypeNumber;
    BYTE Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
 
typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG HandleCount;
    SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
 
typedef enum _POOL_TYPE
{
    NonPagedPool,
    PagedPool,
    NonPagedPoolMustSucceed,
    DontUseThisType,
    NonPagedPoolCacheAligned,
    PagedPoolCacheAligned,
    NonPagedPoolCacheAlignedMustS
} POOL_TYPE, *PPOOL_TYPE;
 
typedef struct _OBJECT_TYPE_INFORMATION
{
    UNICODE_STRING Name;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG TotalPagedPoolUsage;
    ULONG TotalNonPagedPoolUsage;
    ULONG TotalNamePoolUsage;
    ULONG TotalHandleTableUsage;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    ULONG HighWaterPagedPoolUsage;
    ULONG HighWaterNonPagedPoolUsage;
    ULONG HighWaterNamePoolUsage;
    ULONG HighWaterHandleTableUsage;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccess;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    USHORT MaintainTypeList;
    POOL_TYPE PoolType;
    ULONG PagedPoolUsage;
    ULONG NonPagedPoolUsage;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
{
    return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Возвращает строку наоборот
void Reverse(char s[])
{
    int i, j;
    char c;
 
    for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Перевод строки из 10сс в 2сс
char * IntToBinary(int inpNumber)
{
    static char outStr[32];
    memset(outStr, 0, 32);
    outStr[32] = '\0';
 
    outStr[0] = inpNumber & 0xa000000;
 
    for (int step = 0; step <= 31; step++, inpNumber >>= 1)
    {
        if (inpNumber & 0x1 == 1)
            strcat(outStr, "1");
        else
            strcat(outStr, "0");
    }
    Reverse(outStr);
    static char endStr[33];
    memset(endStr, 32, 33);
    strncpy(endStr, outStr, 16);
    strncpy(endStr+17, outStr+16, 16);
    return endStr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Пробуем повысить привилегии
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa446619
BOOL SetPrivilege(
    HANDLE hToken,          //хэндл процесса для установки
    LPCTSTR lpszPrivilege,  //какую будем устанавливать
    BOOL bEnablePrivilege   //установить или снять
    ) 
{
    TOKEN_PRIVILEGES tp;
    LUID luid;
 
    //Получим LUID
    if ( !LookupPrivilegeValue( 
        NULL,
        lpszPrivilege,
        &luid ) )
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return FALSE; 
    }
 
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;
 
    if ( !(AdjustTokenPrivileges(
        hToken, 
        FALSE, 
        &tp, 
        sizeof(TOKEN_PRIVILEGES), 
        (PTOKEN_PRIVILEGES) NULL, 
        (PDWORD) NULL) ))
    { 
        printf("AdjustTokenPrivileges GetLastError: %u\n", GetLastError() ); 
        //попробуем дальше без повышения
        return FALSE; 
    } 
    //всё ок, получили повышение!
    return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void PrintToFile(FILE *f, POBJECT_TYPE_INFORMATION objectTypeInfo)
{
    fprintf(f, "GENERIC READ:\t%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericRead));
    fprintf(f, "GENERIC WRITE:\t%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericWrite));
    fprintf(f, "GENERIC EXECUTE:%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericExecute));
    fprintf(f, "GENERIC ALL:\t%s\n", IntToBinary(objectTypeInfo->GenericMapping.GenericAll));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

rights.c
Кликните здесь для просмотра всего текста

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
#include "rights.h"
 
int wmain(int argc, WCHAR *argv[])
{
    //Импортим из библиотек Native-API функции
    _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)
        GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
    _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)
        GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
    _NtQueryObject NtQueryObject = (_NtQueryObject)
        GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
 
    HANDLE hToken = NULL;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
    SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
    //SetPrivilege(hToken, SE_TCB_NAME, TRUE);
 
    NTSTATUS status;
    PSYSTEM_HANDLE_INFORMATION handleInfo;
    ULONG handleInfoSize = 0x10000;
    ULONG pid;
    HANDLE processHandle;
 
    //Получено ли значение требуемого процесса
    if (argc < 2)
    {
        printf("Give me PID through the console\n");
        return 1;
    }
 
    pid = _wtoi(argv[1]);
 
    //Пробуем подсоединиться к процессу, чтобы получить скопировать его хэндл
    if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid)))
    {
        DWORD q = GetLastError();
        printf("Could not open PID %d! Error: %d\n", pid, q);
        return 1;
    }
 
    FILE *fToPrint;
    //a - открыть для ДОзаписи, или создать для записи, если файла нет
    //w - перезапись по новой
    fToPrint = fopen("output.txt", "w");
    fprintf(fToPrint, "For process: %d\n", pid);
    handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
 
    //Подгнояем размер буфера
    while ((status = NtQuerySystemInformation(
        SystemHandleInformation,
        handleInfo,
        handleInfoSize,
        NULL
        )) == STATUS_INFO_LENGTH_MISMATCH)
        handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
 
    //NtQuerySystemInformation не вернула STATUS_INFO_LENGTH_MISMATCH
    if (!NT_SUCCESS(status))
    {
        printf("NtQuerySystemInformation failed!\n");
        return 1;
    }
 
    for (ULONG i = 0; i < handleInfo->HandleCount; i++)
    {
        SYSTEM_HANDLE handle = handleInfo->Handles[i];
 
        //только если подходит идентификатор - наш процесс
        if (pid != handle.ProcessId)
        {
            continue;
        }
 
        HANDLE dupHandle = NULL;
        POBJECT_TYPE_INFORMATION objectTypeInfo;
        PVOID objectNameInfo;
        UNICODE_STRING objectName;
        ULONG returnLength;
 
        //Копируем объект в свое адресное пространство
        if (!NT_SUCCESS(NtDuplicateObject(
            processHandle,
            (HANDLE)handle.Handle,
            GetCurrentProcess(),
            &dupHandle,
            0,
            0,
            0
            )))
        {
            //Память не выделилась, убираться за собой не нужно, переходим к следующему
            continue;
        }
 
        //Тащим информацию из объекта
        objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectTypeInformation,
            objectTypeInfo,
            0x1000,
            NULL
            )))
        {
            //В случае ошибки - чистим память за собой
            CloseHandle(dupHandle);
            continue;
        }
 
        //Извлекаем инфу об имени
        //Если закончится неудачно - в returnLength вернется нужное количество и мы вызовем ещё раз, только уже с адекватной длиной
        objectNameInfo = malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectNameInformation,
            objectNameInfo,
            0x1000,
            &returnLength
            )))
        {
            //returnLength адекватна для получения
            objectNameInfo = realloc(objectNameInfo, returnLength);
            if (!NT_SUCCESS(NtQueryObject(
                dupHandle,
                ObjectNameInformation,
                objectNameInfo,
                returnLength,
                NULL
                )))
            {
                //Не удалось получить имя
                fprintf(fToPrint, 
                    "[%#x] %.*S: (can't get name)\n",
                    handle.Handle,
                    objectTypeInfo->Name.Length / 2,
                    objectTypeInfo->Name.Buffer
                    );
                PrintToFile(fToPrint, objectTypeInfo);
 
                free(objectTypeInfo);
                free(objectNameInfo);
                CloseHandle(dupHandle);
                continue;
            }
        }
        //Имя есть,
        //переведем в строку Юникода
        objectName = *(PUNICODE_STRING)objectNameInfo;
        
        if (objectName.Length)
        {
            DWORD len;
            long buf[1024];
            PSECURITY_DESCRIPTOR desc = (PSECURITY_DESCRIPTOR)buf;
            DWORD length = sizeof(desc);
 
            fprintf(fToPrint, 
                "[%#x] %.*S: %.*S\n",
                handle.Handle,
                objectTypeInfo->Name.Length / 2,
                objectTypeInfo->Name.Buffer,
                objectName.Length / 2,
                objectName.Buffer
                );
            PrintToFile(fToPrint, objectTypeInfo);
        }
        else
        {
            //Объект безымянен
            fprintf(fToPrint, 
                "[%#x] %.*S: (unnamed)\n",
                handle.Handle,
                objectTypeInfo->Name.Length / 2,
                objectTypeInfo->Name.Buffer
                );
            PrintToFile(fToPrint, objectTypeInfo);
        }
 
        //Подчищаем память
        free(objectTypeInfo);
        free(objectNameInfo);
        CloseHandle(dupHandle);
    }
 
    free(handleInfo);
    CloseHandle(processHandle);
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.12.2013, 21:29
Помогаю со студенческими работами здесь

Модуль ядра для windows
Расскажите, добрые люди, что это такое? И в чем отличия модулей ядра от каких бы то ни было драйверов? А самое главное - пошлите меня туда,...

Синхронизация потоков без объектов ядра - возможно ли?
Нужно решить такую задачу: синхронизировать два потока барьером, с помощью asm вставок в код в более высокоуровневом языке, тоесть будет...

Список доступных параметров ядра
Подскажите пожалуйста, где можно посмотреть список доступных параметров ядра и их описание конечно.

Список модулей ядра для работы VMware
Поставил триалку VMWare Workstation Но после перезагрузки модули ядра не загрузились. на 2 модуля vmware подаловалась vmci vmmon их я...

Обновление ядра Windows
Здравствуйте. Я тут кое-что надумал, хочу уточнить. Вот значит, смотрите, есть семейства процессоров. Возьмём, допустим, наборы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru