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

Можно ли сделать дамп памяти пользовательского процесса из драйвера режима ядра?

03.04.2022, 19:21. Показов 2241. Ответов 3

Студворк — интернет-сервис помощи студентам
В рамках курсовой нужно сделать драйвер антивируса под Windows10. Необходимо реализовать отслеживание создания процессов и копирование его адресного пространства (дамп памяти), и в зависимости от дампа решить убивать процесс или разрешить ему выполнение. Отследить создание процесса можно с помощью PsSetCreateProcessNotifyRoutineEx. Я понял как завершить процесс, но как его приостановить для создания дампа, и чтоб потом ему можно было продолжить выполнение, мне не понятно. И вообще как сделать дамп памяти пользовательского процесса из драйвера ядра? И возможно ли это? Как я понял, функция MiniDumpWriteDump работает только в пользовательском режиме, а чего-то другого я найти не смог.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.04.2022, 19:21
Ответы с готовыми решениями:

Просмотр файла дампа памяти процесса пользовательского режима
Ну и как его просмотреть?

Как по хэндлу процесса сделать дамп его памяти и записать его в файл?
Имеем VB 5.0. Есть чужое приложение на дельфи. Нужно сохранить в файл область память этого чужого приложения. Понятно, что это будет мною...

Дамп памяти процесса
Здравствуйте уважаемые форумчане Столкнулся с одной проблемой: Мне необходимо сделать дамп памяти скрытого процесса. Раньше делал...

3
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
04.04.2022, 04:29
Цитата Сообщение от ASDf54e Посмотреть сообщение
И вообще как сделать дамп памяти пользовательского процесса из драйвера ядра? И возможно ли это?
Вроде нет такой готовой функции, так-что придётся реализовать всё вручную.
В теории это выглядит приблизительно так..
PsSetCreateProcessNotifyRoutineEx() возвращает вам PID нужного процесса, и остаётся передать его в PsLookupProcessByProcessId() - так получите указатель на структуру EPROCESS клиента.

Далее подключаетесь к процессу через KeStackAttachProcess(), проверяете доступ к региону памяти через ProbeForRead(), и если всё ок, то пытаемся прочитать эту память удобным способом типа MmCopyVirtualMemory() или RtlCopyMemory(). В сети имеется подобный пример:

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
/// Read process memory using RtlCopyMemory()
/// Param : name="pCopy"
/// Return: Status code
 
NTSTATUS ReadMemory(IN PCOPY_MEMORY pCopy)
{
    NTSTATUS status = STATUS_SUCCESS;
 
    PRKAPC_STATE state = NULL;
    PEPROCESS process = NULL;
 
    status = PsLookupProcessByProcessId(pCopy->pid, &process);
 
    if (NT_SUCCESS(status))
    {
        __try {
            KeStackAttachProcess(process, &state);
 
            ProbeForRead((PVOID)pCopy->targetPtr, pCopy->size, 1);
            RtlCopyMemory(pCopy->localbuf, (PVOID)pCopy->targetPtr, pCopy->size);
 
            KeUnstackDetachProcess(&state);
        } 
  __except (EXCEPTION_EXECUTE_HANDLER) {
            KeUnstackDetachProcess(&state); 
            DbgPrint("Address 0x%x isn't accessible.\n", pCopy->targetPtr);
            status = STATUS_SEVERITY_INFORMATIONAL;
        }
    }
 
    return status;
}
1
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
04.04.2022, 07:55
Кстати если это курсовая, можно чуть расширить возможности драйвера..
Из примера выше видно, что придётся дампить мин. 2 Gb доступной процессу памяти, что не очень удобно. Из всего пула, процесс на данный момент может реально использовать лишь некоторую часть, например порядка 100 Mb памяти, а остальное принадлежит процессу, но лежит в резерве, пока её не выделишь через VirtualAlloc().

Поскольку уже имеется линк на EPROCESS, можно вычислить страницы реально используемой вирт.памяти, и в цикле сдампить только их, отсеив таким образом свободные. Если запустить отладчик WinDbg, запросить инфу о вcех процессах !process 0 0, найти среди них свой и просмотреть его структуру, можно обнаружить в ней следующие поля:

Code
1
2
3
4
5
6
lkd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
 
PROCESS 958343c8  SessionId: 1  Cid: 0d70    Peb: 7ffdf000  ParentCid: 025c
    DirBase: 5fea8dc0  ObjectTable: 9ef49f10  HandleCount:  59.
    Image: Win32.EXE
Теперь есть адрес и нужна более детальная информация,
в том числе "VirtualSize", и адрес списка VAD (Virtual Address Descriptor):

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
lkd> !process 958343c8 1
PROCESS 958343c8  SessionId: 1  Cid: 0d70    Peb: 7ffdf000  ParentCid: 025c
    DirBase: 5fea8dc0  ObjectTable: 9ef49f10  HandleCount:  59.
    Image  : Win32.EXE
    VadRoot: 8a1ce0e0  (Vads 49. Clone 0. Private 159. Modified 0. Locked 0.)
    DevMap : 85f9ac60
 
    Token                             a1983748
    Working Set Sizes (now,min,max)   983, 50, 345 (3932KB, 200KB, 1380KB)
    PeakWorkingSetSize                992
    VirtualSize                       44 Mb      <---- Реально используемая память
    PeakVirtualSize                   47 Mb
    PageFaultCount                    1021
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      192
    Job                               8913e5d0
Здесь видно, что из доступных 2Gb (у меня система х32) реально занято процессом лишь 44 Mb (или 11.340 вирт.страниц). Тогда зачем дампить всю память, тем-более, что при копировании можно легко нарваться на AccessViolation, если память не закреплена\выделена.

Все активные страницы процесса хранятся в его древовидном списке VAD, а адрес на этот список прописан в той-же структуре EPROCESS. Поскольку PsLookupProcessByProcessId() уже вернула нам указатель на эту структуру, остаётся вычислить смещение поля "VadRoot" (корень древа), где и будут лежать номера активных вирт.страниц. Значимые поля структуры представлены ниже:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lkd> dt _eprocess 958343c8
nt!_EPROCESS
   +0x000 Pcb                  : _KPROCESS
   +0x0b4 UniqueProcessId      : 0x0d70            <---- PID
   +0x0e0 VirtualSize          : 0x2c4c000         <---- 0x2c4c000 = 46.448.640 = 44 Mb
   +0x0fc WorkingSetPage       : 0x1c29c           <---- Страниц в рабочем наборе
   +0x12c SectionBaseAddress   : 0x00400000        <---- База образа в памяти
   +0x16c ImageFileName        : [15] "Win32.EXE"
   +0x17b PriorityClass        : 0x2 ''
   +0x198 ActiveThreads        : 2
   +0x1a8 Peb                  : 0x7ffdc000 _PEB   <---- Окружение процесса в ЮМ
   +0x1b0 ReadOperationCount   : 0x1               <---- Счётчики различных операций
   +0x1b8 WriteOperationCount  : 0x0
   +0x1c0 OtherOperationCount  : 0x38
   +0x1c8 ReadTransferCount    : 0x3c
   +0x1d0 WriteTransferCount   : 0x0
   +0x1d8 OtherTransferCount   : 0x60
   +0x264 HighestUserAddress   : 0x7fff0000        <---- Макс.доступный адрес
   +0x278 VadRoot              : _MM_AVL_TABLE     <---- Таблица VAD процесса
Далее просматриваем поле "VadRoot", чтобы получить указатель на список активных страниц:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lkd> dt _eprocess 958343c8 vadroot.
nt!_EPROCESS
   +0x278 VadRoot  : 
      +0x000 BalancedRoot               : _MMADDRESS_NODE
      +0x014 DepthOfTree                : 0x7
      +0x014 Unused                     : 0
      +0x014 NumberGenericTableElements : 0x31
      +0x018 NodeHint                   : 0x8a1ce0e0
      +0x01c NodeFreeHint               : (null) 
 
lkd> dt _eprocess 958343c8 vadroot.BalancedRoot.
nt!_EPROCESS
   +0x278 VadRoot               : 
      +0x000 BalancedRoot          : 
         +0x000 u1                    : <unnamed-tag>
         +0x004 LeftChild             : (null) 
         +0x008 RightChild            : 0x8a1ce0e0 _MMADDRESS_NODE
         +0x00c StartingVpn           : 0
         +0x010 EndingVpn             : 0
Древо VAD устроено так, что каждый узел имеет ветки "Left" и "Right", в которых лежат диапазоны памяти в виде VPN (Virtual-Page-Number). При этом в узле "Left" будут собраны все адреса вирт.станиц с меньшими (от текущего) адресами, а в правом с большими.



WindDbg имеет расширение !vad для просмотра древа,
и в моём случае оно выглядит так (адрес см. в первом логе, или записи выше):

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
lkd> !vad 0x8a1ce0e0
 
VAD     level      start      end    commit
89a2d0c0 ( 4)         10       1f         0 Mapped       READWRITE          Pagefile-backed section
89b4b130 ( 5)         20       20         1 Private      READWRITE         
89a38030 ( 3)         30       6f         4 Private      READWRITE         
8a067248 ( 4)         70       73         0 Mapped       READONLY           Pagefile-backed section
89afa4b8 ( 2)         80       80         1 Private      READWRITE         
928a1bb0 ( 5)         90       f6         0 Mapped       READONLY           \Windows\System32\locale.nls
9582ed28 ( 4)        100      100         1 Private      READWRITE         
861b5950 ( 5)        110      110         0 Mapped       READONLY           Pagefile-backed section
81fee5f8 ( 6)        120      120         0 Mapped       READWRITE          Pagefile-backed section
95927cc0 ( 3)        140      14f        16 Private      READWRITE         
89a1ace8 ( 5)        150      217         0 Mapped       READONLY           Pagefile-backed section
a140a588 ( 4)        250      28f        27 Private      READWRITE         
81fa8070 ( 6)        290      30f         1 Private      READWRITE         
81ef6af8 ( 5)        310      31f         3 Private      READWRITE         
8a18e368 ( 6)        320      3fe         0 Mapped       READONLY           Pagefile-backed section
890e36a0 ( 1)        400      404         4 Mapped  Exe  EXECUTE_WRITECOPY  \TEMP\ASM\CODE\Win32.EXE
a14aaab0 ( 6)        410      510         0 Mapped       READONLY           Pagefile-backed section
95847570 ( 5)        520     111f         0 Mapped       READONLY           Pagefile-backed section
89b382b8 ( 6)       1120     14a3         0 Mapped       READWRITE          Pagefile-backed section
89ad5890 ( 4)       14b0     1ddf         0 Mapped       READONLY           \Windows\Fonts\StaticCache.dat
89192560 ( 5)       1eb0     1eef        24 Private      READWRITE         
8b2fc1e0 ( 6)       1ef0     1fef         3 Private      READWRITE         
891ac750 ( 3)       2070     20af         1 Private      READWRITE         
a15951c8 ( 5)       20b0     21af         3 Private      READWRITE         
8b23ef58 ( 4)       21b0     247e         0 Mapped       READONLY           \Windows\Globalization\Sorting\SortDefault.nls
8b2fe0d0 ( 5)       8000     8007         2 Mapped  Exe  EXECUTE_WRITECOPY  \Program Files\Punto Switcher\pshook.dll.1212216085
81f024f8 ( 2)      745d0    745e2         3 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\dwmapi.dll
89a37880 ( 4)      749a0    749df         3 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\uxtheme.dll
959158c0 ( 5)      75b70    75b7b         2 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\cryptbase.dll
890c2d20 ( 3)      75c80    75cca         3 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\KernelBase.dll
928a41e0 ( 5)      75fb0    76050         5 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\advapi32.dll
89a14be0 ( 4)      76310    763ac         3 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\usp10.dll
89b0eef8 ( 6)      76460    765bc         5 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\ole32.dll
861d9fc0 ( 5)      77210    772b1         2 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\rpcrt4.dll
8eeb1ab8 ( 6)      77450    77468         4 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\sechost.dll
8a1ce0e0 ( 0)      77510    7755d         3 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\gdi32.dll
89ba4008 ( 3)      775e0    775fe         2 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\imm32.dll
9584ba60 ( 2)      779b0    77a5b         8 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\msvcrt.dll
81ea3900 ( 3)      77a60    77b28         2 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\user32.dll
8b2eb708 ( 4)      77b30    77bfc         3 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\msctf.dll
89a369e8 ( 1)      77c00    77d41        10 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\ntdll.dll
8b232ac8 ( 4)      77d60    77e34         2 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\kernel32.dll
890f5840 ( 5)      77e40    77e49         2 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\lpk.dll
8ee62c68 ( 3)      77e60    77e60         0 Mapped  Exe  EXECUTE_WRITECOPY  \Windows\System32\apisetschema.dll
8a16f188 ( 4)      7f6f0    7f7ef         0 Mapped       READONLY           Pagefile-backed section
959fc400 ( 2)      7ffb0    7ffd2         0 Mapped       READONLY           Pagefile-backed section
89157538 ( 4)      7ffdd    7ffdd         1 Private      READWRITE         
958eb820 ( 3)      7ffde    7ffde         1 Private      READWRITE         
81ea3b88 ( 4)      7ffdf    7ffdf         1 Private      READWRITE         
 
Total VADs: 49.  Average level: 5.  Maximum depth: 6.
В столбце "Level" указывает уровень узла в древе, где нуль является корнем.
В столбцах "Start\End" лежат уже адреса страниц, относительно базы загрузки образа в память.
Всё это теория и уверен, что в ядре имеются спец.функции для поиска валидных страниц процесса.
2
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
04.04.2022, 08:01
В защищённом режиме для обхода древа VAD используется функция VirtualQuery(). Для драйверов можно поискать в Ntoskrnl.exe что-то аналогичное.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.04.2022, 08:01
Помогаю со студенческими работами здесь

Сохранить дамп памяти процесса в файл
подскажите пожалуйста как на C# (Visual Studio 2010. FW 4.0) сохранить в файл дамп памяти процесса? мне нужно сделать аналог функции в...

Как можно прочесть сохраненный в файл дамп памяти с помощью средств Delphi?
подскажите как можно прочесть сохраненный в файл дамп памяти с помощью средств delphi.аналог утилиты BlueScreenView

Как получить дамп памяти программы, чтоб потом можно было его сохранить и проанализировать?
Ну тут собственно есть нюансы: 1. Как собственно получить сам дамп. То есть это скорее всего должен быть дамп виртуального адресного...

Помогите с драйверами режима ядра
У меня проблема! Не могу скомпилить даже каркас kernel-mode драйвера. Может кто разбирается, поможет. У меня вылетает ошибок 120 и все в...

Можно ли как получать уведомление о изменении области памяти другого процесса?
Возникла необходимость получать изменения в памяти одной программы. Есть вариант просто читать память процесса через определённые участки...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru