Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
_lunar_
1384 / 1315 / 107
Регистрация: 03.05.2011
Сообщений: 3,038
Завершенные тесты: 1
#1

Пользовательский режим и ZwXxx функции (MiniDebugger своими руками) - C++

04.12.2017, 01:15. Просмотров 180. Ответов 3
Метки нет (Все метки)

Как известно в ядре есть два вида функций (ну конечно не два, а гораздо больше, но сейчас не об этом) - NtXxx и ZwXxx.
Вызов NtXxx функций в ядре не документированный и не рекомендованный способ. Вызов ZwXxx функций из ядра настраивает права доступа, в том числе устанавливает PreviousMode (KernelMode (0) или UserMode (1)) для вызывающего потока (KTHREAD). Узнать о текущем значении можно с помощью ExGetPreviousMode (в ntoskrnl.exe).
При обращении к таблице сервисов (SDT) через шлюз (при переходе из пользовательского режима (Ring3) в режим ядра (Ring0)), для NtXxx функций выставляется значение PreviousMode = UserMode и все функции нуждающиеся в проверке доступа определяют, что вызов пришел из Ring3 и проверяют соответствующие права. При этом, не смотря на то, что код работает в ядре, всё равно может быть отказано в доступе.
При вызове в ядре ZwXxx функций, вызов опять пойдет через таблицу сервисов, но при этом будет установлен PreviousMode = KernelMode и проверка прав доступа не будет осуществляться.
Иными словами, ZwXxx функции это вызов NtXxx функций через специальный wrapper (обертку), меняющий режим вызова текущей нити. Поле PreviousMode структуры ntdll!_KTHREAD текущей нити принудительно меняется на KernelMode. После возврата восстанавливается старое значение.

Если вызывать kernel32!CreateProcess с флагом DEBUG_PROCESS (или DEBUG_ONLY_THIS_PROCESS), то во-первых, приложение, которое отлаживается, может иметь функции антидебага и сражу же отловить созданный с этими флагами процесс по средствам таблицы TLSCallback, которая может загружаться до точки входа в приложение и до передачи управления отладчику. После чего спокойно делает terminate. И во-вторых, с этими флагами подгружается слишком много системных библиотек (ntdll.dll, kernel32.dll, user32.dll, gdi32.dll, etc.), что мешает отлаживать процесс с самого начала пошагово контролируя загрузку компонентов.
Если же вызывать kernel32!CreateProcess с флагом CREATE_SUSPENDED процесс будет заморожен, и в адресное пространство, кроме самого отлаживаемого модуля, попадёт лишь ntdll.dll (здесь подразумевается, что CreateProcess будет вызывать цепочкой других функций ...NtCreateProcess... и в конце PsCreateProcess). Посмотреть можно в любом MapView, к примеру CheatEngine (он умеет загружаться как гипервизор ОС и никакие законы ему не писаны). Теперь задача стоит в том, чтобы перевести процесс из suspended в режим debug.

Я не люблю пользоваться WDK, там чёрт ногу сломит - подключаешь ntddk.h, а внутри системного инклуда куча ошибок с неинициализированными переменными, приходится искать что подключать ещё, ещё и ещё. В общем муторно всё это...
Проще - написать свой инклуд и сделать статическую либу из dll http://xbb.uz/dev/Gjenjeracija-.lib-iz-DLL-s-pomoshhju-Visual-Studio (процесс занимает пару минут). Для облегчения вытаскивания имен экспортируемых функций ниже в посте выложу коротенький код с кнопкой.

ntdef.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
#ifdef _MSC_VER
#pragma once
#endif // _MSC_VER
 
#ifndef _NTDEF_H_
#define _NTDEF_H_
 
#include <Windows.h>
#include <strsafe.h>
 
#define DEBUG_READ_EVENT 0x0001
#define DEBUG_PROCESS_ASSIGN 0x0002
#define DEBUG_SET_INFORMATION 0x0004
#define DEBUG_QUERY_INFORMATION 0x0008
#define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE |    \
    DEBUG_READ_EVENT | DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | \
    DEBUG_QUERY_INFORMATION)
 
typedef enum _DBG_STATE {
    DbgIdle,
    DbgReplyPending,
    DbgCreateThreadStateChange,
    DbgCreateProcessStateChange,
    DbgExitThreadStateChange,
    DbgExitProcessStateChange,
    DbgExceptionStateChange,
    DbgBreakpointStateChange,
    DbgSingleStepStateChange,
    DbgLoadDllStateChange,
    DbgUnloadDllStateChange
} DBG_STATE, *PDBG_STATE;
 
typedef struct _DBGKM_EXCEPTION {
    EXCEPTION_RECORD ExceptionRecord;
    ULONG FirstChance;
} DBGKM_EXCEPTION, *PDBGKM_EXCEPTION;
 
typedef struct _DBGKM_CREATE_THREAD {
    ULONG SubSystemKey;
    PVOID StartAddress;
} DBGKM_CREATE_THREAD, *PDBGKM_CREATE_THREAD;
 
typedef struct _DBGKM_CREATE_PROCESS {
    ULONG SubSystemKey;
    HANDLE FileHandle;
    PVOID BaseOfImage;
    ULONG DebugInfoFileOffset;
    ULONG DebugInfoSize;
    DBGKM_CREATE_THREAD InitialThread;
} DBGKM_CREATE_PROCESS, *PDBGKM_CREATE_PROCESS;
 
typedef struct _DBGKM_EXIT_THREAD {
    NTSTATUS ExitStatus;
} DBGKM_EXIT_THREAD, *PDBGKM_EXIT_THREAD;
 
typedef struct _DBGKM_EXIT_PROCESS {
    NTSTATUS ExitStatus;
} DBGKM_EXIT_PROCESS, *PDBGKM_EXIT_PROCESS;
 
typedef struct _DBGKM_LOAD_DLL {
    HANDLE FileHandle;
    PVOID BaseOfDll;
    ULONG DebugInfoFileOffset;
    ULONG DebugInfoSize;
    PVOID NamePointer;
} DBGKM_LOAD_DLL, *PDBGKM_LOAD_DLL;
 
typedef struct _DBGKM_UNLOAD_DLL {
    PVOID BaseOfDll;
} DBGKM_UNLOAD_DLL, *PDBGKM_UNLOAD_DLL;
 
typedef struct _DBG_CREATE_THREAD {
    HANDLE HandleToThread;
    DBGKM_CREATE_THREAD NewThread;
} DBG_CREATE_THREAD, *PDBG_CREATE_THREAD;
 
typedef struct _DBG_CREATE_PROCESS {
    HANDLE HandleToProcess;
    HANDLE HandleToThread;
    DBGKM_CREATE_PROCESS NewProcess;
} DBG_CREATE_PROCESS, *PDBG_CREATE_PROCESS;
 
typedef struct _CLIENT_ID {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
 
typedef struct _DBG_WAIT_STATE_CHANGE {
    DBG_STATE NewState;
    CLIENT_ID AppClientId;
    union {
        DBGKM_EXCEPTION Exception;
        DBG_CREATE_THREAD CreateThread;
        DBG_CREATE_PROCESS CreateProcessInfo;
        DBGKM_EXIT_THREAD ExitThread;
        DBGKM_EXIT_PROCESS ExitProcess;
        DBGKM_LOAD_DLL LoadDll;
        DBGKM_UNLOAD_DLL UnloadDll;
    } StateInfo;
} DBG_WAIT_STATE_CHANGE, *PDBG_WAIT_STATE_CHANGE;
 
typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
#ifdef MIDL_PASS
    [size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT * Buffer;
#else
    _Field_size_bytes_part_opt_(MaximumLength, Length) PWCH Buffer;
#endif
} UNICODE_STRING, *PUNICODE_STRING;
typedef CONST UNICODE_STRING *PCUNICODE_STRING;
 
typedef struct _OBJECT_ATTRIBUTES {
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
 
#endif // _NTDEF_H_

ntdll.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
#ifdef _MSC_VER
#pragma once
#endif // _MSC_VER
 
#ifndef _NTDLL_H_
#define _NTDLL_H_
 
#include "ntdef.h"
 
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwResumeThread(
    _In_ HANDLE ThreadHandle,
    _Out_opt_ PULONG PreviousSuspendCount
);
 
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwClose(
    _In_ HANDLE Handle
);
 
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwCreateDebugObject(
    _Out_ PHANDLE DebugObjectHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_ POBJECT_ATTRIBUTES ObjectAttributes,
    _In_ ULONG Flags
);
 
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwDebugActiveProcess(
    _In_ HANDLE ProcessHandle,
    _In_ HANDLE DebugObjectHandle
);
 
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwWaitForDebugEvent(
    _In_ HANDLE DebugObjectHandle,
    _In_ BOOLEAN Alertable,
    _In_opt_ PLARGE_INTEGER Timeout,
    _Out_ PVOID WaitStateChange
);
 
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwDebugContinue(
    _In_ HANDLE DebugObjectHandle,
    _In_ PCLIENT_ID ClientId,
    _In_ NTSTATUS ContinueStatus
);
 
#endif // _NTDLL_H_

Ок, теперь создаем процесс и сразу же объект для отлаживания ZwCreateDebugObject. В результате у нас появится хендл этого объекта.
Открываем стандартный цикл для дебага (здесь кому что нравиться for(;, ещё какие-либо извраты с циклами, но лично я предпочитаю do/while).
В suspended режиме наш статус всегда будет ноль, т.к. процесс ничего не делает. Поэтому в case DbgIdle инициализируем функцию ZwDebugActiveProcess и тем самым присоединяемся к созданному процессу.
Открываем ещё один цикл do/while, который уже реально будет циклом дебага и определяем ZwWaitForDebugEvent.
В адресном пространстве процесса уже есть модуль процесса и ntdll.dll, поэтому пройдясь по разу через DbgCreateProcessStateChange и DbgLoadDllStateChange мы снова получим статус 0. Следовательно в DbgIdle нужно вызвать ZwResumeThread.

Собственно код отладчика
Кликните здесь для просмотра всего текста
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
#include "ntdll.h"
#include <Psapi.h>
 
#pragma comment (lib, "ntdll.lib")
 
OBJECT_ATTRIBUTES ObjAttr = { sizeof(ObjAttr) };
DBG_WAIT_STATE_CHANGE WaitStateChange = { sizeof(WaitStateChange) };
WIN32_FIND_DATAW FindData = { 0 };
STARTUPINFO StartInfo = { 0 };
PROCESS_INFORMATION ProcInfo = { 0 };
CLIENT_ID ClientId = { 0 };
LARGE_INTEGER TimeOut;
WCHAR Path[MAX_PATH];
HANDLE DebugObjectHandle;
ULONG PreviousSuspendCount;
 
void MainDebugLoop() {
    TimeOut.QuadPart = Int32x32To64(PERF_100NSEC_TIMER, 10000);
    if (CreateProcessW(L"E:\\Games\\MinPack\\Assassin's Creed Origins\\ACOrigins.exe",
        NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartInfo, &ProcInfo)) {
        ZwCreateDebugObject(&DebugObjectHandle, DEBUG_ALL_ACCESS, &ObjAttr, 0);
        do {
            ZwWaitForDebugEvent(DebugObjectHandle, FALSE, &TimeOut, &WaitStateChange);
            switch (WaitStateChange.NewState) {
            case DbgIdle:
                ZwDebugActiveProcess(ProcInfo.hProcess, DebugObjectHandle);
                do {
                    ZwWaitForDebugEvent(DebugObjectHandle, FALSE, &TimeOut, &WaitStateChange);
                    switch (WaitStateChange.NewState) {
                    case DbgIdle:
                        switch (WaitStateChange.StateInfo.Exception.ExceptionRecord.ExceptionCode) {
                        case STATUS_WAIT_0:
                            ZwResumeThread(ProcInfo.hThread, &PreviousSuspendCount);
                            break;
                        default:
                            break;
                        }
                        break;
                    case DbgReplyPending:
                        switch (WaitStateChange.StateInfo.Exception.ExceptionRecord.ExceptionCode) {
                        case STATUS_PENDING:
                            break;
                        default:
                            break;
                        }
                        break;
                    case DbgCreateThreadStateChange:
                        wprintf(L"\nCreateThread:\n UniqueThreadHandle %lld\n StartAddress 0x%016llX {ntdll.dll!TppWorkerThread(void)}\n",
                            (UINT64)WaitStateChange.AppClientId.UniqueThread,
                            (UINT64)WaitStateChange.StateInfo.CreateThread.NewThread.StartAddress);
                        break;
                    case DbgCreateProcessStateChange:
                        GetModuleFileNameExW(ProcInfo.hProcess, NULL, Path, MAX_PATH);
                        FindFirstFileW(Path, &FindData);
                        wprintf(L"%s\n\nCreateProcess:\n UniqueProcessHandle %lld\n UniqueThreadHandle %lld\n StartAddress 0x%016llX\n",
                            FindData.cFileName,
                            (UINT64)WaitStateChange.AppClientId.UniqueProcess,
                            (UINT64)WaitStateChange.AppClientId.UniqueThread,
                            (UINT64)WaitStateChange.StateInfo.CreateProcessInfo.NewProcess.InitialThread.StartAddress);
                        break;
                    case DbgExitThreadStateChange:
                        wprintf(L"\nExitThread %lld with status 0x%08X\n",
                            (UINT64)WaitStateChange.AppClientId.UniqueThread,
                            WaitStateChange.StateInfo.ExitThread.ExitStatus);
                        break;
                    case DbgExitProcessStateChange:
                        wprintf(L"\nExitProcess %lld with status 0x%08X\n",
                            (UINT64)WaitStateChange.AppClientId.UniqueProcess,
                            WaitStateChange.StateInfo.ExitProcess.ExitStatus);
                        break;
                    case DbgExceptionStateChange:
                        break;
                    case DbgBreakpointStateChange:
                        switch (WaitStateChange.StateInfo.Exception.ExceptionRecord.ExceptionCode) {
                        case STATUS_BREAKPOINT:
                            wprintf(L"\nBreakPoint at 0x%016llX {ntdll.dll!LdrpDoDebuggerBreak()}\n\n",
                                (UINT64)WaitStateChange.StateInfo.CreateThread.NewThread.StartAddress);
                            break;
                        default:
                            break;
                        }
                        break;
                    case DbgSingleStepStateChange:
                        switch (WaitStateChange.StateInfo.Exception.ExceptionRecord.ExceptionCode) {
                        case STATUS_SINGLE_STEP:
                            break;
                        default:
                            break;
                        }
                        break;
                    case DbgLoadDllStateChange:
                        GetFinalPathNameByHandleW(WaitStateChange.StateInfo.LoadDll.FileHandle, Path, MAX_PATH, VOLUME_NAME_NONE);
                        FindFirstFileW(Path, &FindData);
                        wprintf(L"   %s loaded at 0x%016llX\n",
                            FindData.cFileName,
                            (UINT64)WaitStateChange.StateInfo.LoadDll.BaseOfDll);
                        break;
                    case DbgUnloadDllStateChange:
                        GetFinalPathNameByHandleW(WaitStateChange.StateInfo.LoadDll.FileHandle, Path, MAX_PATH, VOLUME_NAME_NONE);
                        FindFirstFileW(Path, &FindData);
                        wprintf(L"  %s unloaded at 0x%016llX\n",
                            FindData.cFileName,
                            (UINT64)WaitStateChange.StateInfo.UnloadDll.BaseOfDll);
                        break;
                    default:
                        break;
                    }
                    ClientId.UniqueProcess = WaitStateChange.AppClientId.UniqueProcess;
                    ClientId.UniqueThread = WaitStateChange.AppClientId.UniqueThread;
                    ZwDebugContinue(DebugObjectHandle, &ClientId, DBG_CONTINUE);
                } while (WaitStateChange.NewState != DbgExitProcessStateChange);
                ZwClose(ProcInfo.hThread);
                ZwClose(ProcInfo.hProcess);
                break;
            default:
                break;
            }
            ZwDebugContinue(DebugObjectHandle, &ClientId, DBG_CONTINUE);
        } while (WaitStateChange.NewState != DbgExitProcessStateChange);
    }
}
 
int wmain(int argc, wchar_t *argv[], wchar_t *envp[]) {
    MainDebugLoop();
    getwchar();
    return 0;
}

Рекомендую компилировать в C и в unicode чтобы не было лишних проблем.

Собственно что хотелось бы узнать: как не использовать юзермодную CreateProcess, чтобы автоматом не подгружалась ntdll.dll, и вообще возможно ли это? Т.е. мне изначально нужен только хендл, а не загруженный модуль. Подозреваю, что придется вручную инициализировать EPROCESS и ETHREAD. Да и хотелось бы перейти на ZwCreateProcess (ZwCreateUserProcess), но что-то инфы в инете нет и определить хендл не получается.

Как и обещал - программа для экспорта функций из системных модулей (в блокнот записываются только имена без прочей ерунды, что облегчает процесс конвертирования dll в lib). Программа построена на стандартном DialogBox (просто созайте проект и добавьте Dialog, всё ни каких других элементов не требуется, скопировали код и вставили)
Кликните здесь для просмотра всего текста
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
#include "resource.h"
#include <Windows.h>
#include <fstream>
#include <ImageHlp.h>
 
#pragma comment (lib, "ImageHlp.lib")
 
OPENFILENAME OpenFileName = { 0 };
LOADED_IMAGE LoadedImage = { 0 };
ULONG uSize = 0;
std::ofstream file;
 
void ExportTable() {
    file.open("E:\\new.txt");
    PIMAGE_EXPORT_DIRECTORY ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(LoadedImage.MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &uSize);
    if (LoadedImage.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size && ExportDirectory->Characteristics == 0) {
        PDWORD AddressOfNames = (PDWORD)ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, ExportDirectory->AddressOfNames, NULL);
        for (DWORD i = 0; i < ExportDirectory->NumberOfNames; i++) {
            PSTR ExportFunctionName = (PSTR)ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, AddressOfNames[i], NULL);
            file << ExportFunctionName << "\n";
        }
        file.close();
    }
    else MessageBox(NULL, "Таблица DIRECTORY_EXPORT не найдена", "Error", MB_ICONERROR);
}
 
void OpenFileDialog() {
    CHAR FilePath[MAXWORD] = "";
    ZeroMemory(&OpenFileName, sizeof(OpenFileName));
    OpenFileName.lStructSize = sizeof(OpenFileName);
    OpenFileName.lpstrFilter = "Executable Files (*.exe)\0*.exe\0 Dynamic Link Libraries (*.dll)\0*.dll";
    OpenFileName.lpstrFile = FilePath;
    OpenFileName.nMaxFile = MAXWORD;
    OpenFileName.Flags = OFN_EXPLORER | OFN_FORCESHOWHIDDEN;
    if (GetOpenFileName(&OpenFileName)) {
        switch (OpenFileName.nFilterIndex) {
        case 1:
            MapAndLoad(FilePath, NULL, &LoadedImage, FALSE, TRUE);
            break;
        case 2:
            MapAndLoad(FilePath, NULL, &LoadedImage, TRUE, TRUE);
            break;
        }
        ExportTable();
    }
}
 
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_CLOSE:
        EndDialog(hwndDlg, NULL);
        break;
    case WM_COMMAND:
        switch (wParam) {
        case IDOK:
            OpenFileDialog();
            break;
        case IDCANCEL:
            EndDialog(hwndDlg, NULL);
            break;
        }
        break;
    }
    return FALSE;
}
 
 
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc, NULL);
    return FALSE;
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.12.2017, 01:15
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Пользовательский режим и ZwXxx функции (MiniDebugger своими руками) (C++):

Сканер портов своими руками - C++ Builder
люди помогите пожалуйста, задание на диплом написать сканер портов на билдере а я в этом не рублю вообще, поделитесь информацией или...

Создание "инсталлятора" своими руками - C++ Builder
Здравствуйте! Создаю &quot;инсталлятор&quot; в C++ Builder XE4. Прошу помочь с одним вопросом. Хотелось бы знать, возможно ли, что бы устанавливаемая...

Framework своими руками (помещение в DLL) - C++ WinAPI
Написал небольшой каркас для фреймворка, и проблема возникла при попытки завернуть его в либу. Описание: Файл globals.h содержит...

Паинт своими руками - C++
Пишу свой паинт (точнее написал) но встала задача переписать его без использования типа данных HDC (указатель контекстного...

pdf reader своими руками - C++
Прошу помощи. Нужна любая информация, которая поможет написать простейший pdf reader на C++, примеры, советы, что угодно, что может...

Ассоциативный массив своими руками - C++
Подскажите, пожалуйста, как реализовать такую конструкцию: array = 324;

3
ISergey
Maniac
Эксперт С++
1407 / 918 / 57
Регистрация: 02.01.2009
Сообщений: 2,736
Записей в блоге: 1
06.12.2017, 15:09 #2
Ну и нагородил...
В Ring3 NtXxx/NtXxx ведут себя одинаково.

Цитата Сообщение от _lunar_ Посмотреть сообщение
Собственно что хотелось бы узнать: как не использовать юзермодную CreateProcess, чтобы автоматом не подгружалась ntdll.dll, и вообще возможно ли это?
ни как.. ntdll мапится гдето в недрах PspCreateProcess..

Цитата Сообщение от _lunar_ Посмотреть сообщение
Подозреваю, что придется вручную инициализировать EPROCESS и ETHREAD.
В Ring3 ? Серьезно?
0
_lunar_
1384 / 1315 / 107
Регистрация: 03.05.2011
Сообщений: 3,038
Завершенные тесты: 1
06.12.2017, 16:37  [ТС] #3
Цитата Сообщение от ISergey Посмотреть сообщение
Ну и нагородил...
В Ring3 NtXxx/NtXxx ведут себя одинаково.
а я разве что-то говорил про Ring3?
понятное дело, что адрес Nt и Zw в ntdll одинаковый.
тут как бы заготовка для дальнейшей разработки через драйвер.
0
ISergey
Maniac
Эксперт С++
1407 / 918 / 57
Регистрация: 02.01.2009
Сообщений: 2,736
Записей в блоге: 1
06.12.2017, 18:13 #4
Цитата Сообщение от _lunar_ Посмотреть сообщение
тут как бы заготовка для дальнейшей разработки через драйвер.
тоесть задача отлаживать приложение r3 с r0? Если так то зачем? ) что это даст?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.12.2017, 18:13
Привет! Вот еще темы с ответами:

Умный указатель своими руками - C++
Доброго времени суток. Изобразил следующую структуру: имеется класс-контейнер, фактически обертка для одномерного массива. И...

Парсер collada своими руками - C++
За рекурсивный парсинг берусь впервые, поэтому просьба &quot;Ересь!&quot; громко не орать и в теме не обзываться. В этом направлении я новичок. Пусть...

Двунаправленный список своими руками, нарушение доступа на чтение - C++
Делаю лабу по двунаправленному списку Сделал добавление и отображение, но получаю исключение &quot;По такому-то адресу нет доступа на чтение&quot; ...

Чем классы-исключения библиотеки могуть быть полезнее классов-исключений написанных своими руками - C++
Чем классы-исключения библиотеки могуть быть полезнее классов-исключений написанных своими руками + Какое исключение может...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru