• XSS.stack #1 – первый литературный журнал от юзеров форума

как скопировать структуру EPROCESS чтобы потом обращается к её полям(PCB) а не использовать встроенные функции

Решение
Имхо парсить eprocess в ручную можно только в целях самообразования, т.к. это внутренняя структура ядра и оффсеты полей в ней отличаются не только в x32/64, но и в разных релизах одной и той-же версии Win, т.е. о никакой кросплатформенности тут не может быть и речи. Например то-же поле "ActiveProcessLinks" на моей Win7-х64 лежит по смещению 0x188 от начала eprocess, на Win10 уже 0x2f0, а в Win11 вообще 0x448 (оффсеты зависят от размера вложенной структуры kprocess=pcb). В результате, на какой машине ты соберёшь исходник драйвера, компиль подставит офсеты именно твоей текущей ос, и соответственно после смены платформы, профит от кода окажется под вопросом.

Допустим нашёл ты нужный процесс через...
Есть экспорт в нтоскернеле PsInitialSystemProcess который даст указатель на EPROCESS процесса системы.
Имя на руках этот поинтер проходишься по PEPROCESS->ActiveProcessLinks пока не найдёшь нужный процесс по пиду или имени и уже получаешься для найденного процесса PEPROCESS->Pcb
 
получить доступ к этой структуре EPROCESS
она в ядре, а потому под юзером без драйвера ты не сможешь её прочитать.
в Ring(3) доступны только структуры: PEB, TEB, и KUSER_SHARED_DATA
 
она в ядре, а потому под юзером без драйвера ты не сможешь её прочитать.
в Ring(3) доступны только структуры: PEB, TEB, и KUSER_SHARED_DATA
Я через драйвер всё это делаю конечно
 
Спасибо, завтр
Есть экспорт в нтоскернеле PsInitialSystemProcess который даст указатель на EPROCESS процесса системы.
Имя на руках этот поинтер проходишься по PEPROCESS->ActiveProcessLinks пока не найдёшь нужный процесс по пиду или имени и уже получаешься для найденного процесса PEPROCESS->Pcb
Спасибо, завтра попробую
 
Есть экспорт в нтоскернеле PsInitialSystemProcess который даст указатель на EPROCESS процесса системы.
Имя на руках этот поинтер проходишься по PEPROCESS->ActiveProcessLinks пока не найдёшь нужный процесс по пиду или имени и уже получаешься для найденного процесса PEPROCESS->Pcb
если вас не затруднит можете написать экспорт данной функции PsInitialSystemProcess а то я посмотрел и не нашёл
 
Пожалуйста, обратите внимание, что пользователь заблокирован
если вас не затруднит можете написать экспорт данной функции PsInitialSystemProcess а то я посмотрел и не нашёл
Это переменная

1709670202236.png


В IDA Shift+F4

ntddk.h

1709671021369.png
 
Последнее редактирование:
Всё верно..
В WinDbg значение любой переменной можно получить командой "dp".
Если передать ей "PsInitialSystemProcess", то получишь линк на EPROCESS процесса "system", PID которого, вроде, всегда равен 4 (см.диспетчер задач Win). Имея PID, сдампить system.eprocess (да и любой) можно чз PsLookupProcessByProcessId(), но если ты не хочешь дёргать api, то используй предложенный указатель.

C-подобный:
0: kd> dp nt!PsInitialSystemProcess L1
fffff800`02ef7028   fffffa80`0182bb10

0: kd> dt _eprocess fffffa80`0182bb10
ntdll!_EPROCESS
   +0x000 Pcb                : _KPROCESS
.........
   +0x180 UniqueProcessId    : 0x00000000`00000004   //<---- PID процесса "system"
   +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`02a07808 - 0xfffff800`02e6f420 ]
.........
 
Всё верно..
В WinDbg значение любой переменной можно получить командой "dp".
Если передать ей "PsInitialSystemProcess", то получишь линк на EPROCESS процесса "system", PID которого, вроде, всегда равен 4 (см.диспетчер задач Win). Имея PID, сдампить system.eprocess (да и любой) можно чз PsLookupProcessByProcessId(), но если ты не хочешь дёргать api, то используй предложенный указатель.

C-подобный:
0: kd> dp nt!PsInitialSystemProcess L1
fffff800`02ef7028   fffffa80`0182bb10

0: kd> dt _eprocess fffffa80`0182bb10
ntdll!_EPROCESS
   +0x000 Pcb                : _KPROCESS
.........
   +0x180 UniqueProcessId    : 0x00000000`00000004   //<---- PID процесса "system"
   +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`02a07808 - 0xfffff800`02e6f420 ]
.........
Да если я буду использовать PsLookupProcessByProcessId то он будет возвращать структуру процесса но смогу ли я обратится к указателю на следующую структуру другого процесса
 
так "LIST_ENTRY" в поле "ActiveProcessLinks" любой структуры для этого и предназначено - это цепочка с двумя указателями вперёд/назад. Можно вообще не искать начало, а стартовать со-своей структуры, и кольцом опять возвратишься к себе.
 
так "LIST_ENTRY" в поле "ActiveProcessLinks" любой структуры для этого и предназначено - это цепочка с двумя указателями вперёд/назад. Можно вообще не искать начало, а стартовать со-своей структуры, и кольцом опять возвратишься к себе.
Я пока что не знаю как это сделать к сожалению
 
В структуре "LIST_ENTRY" лежат 2 указателя: Flink (forward, вперёд), и Blink (backward, назад).
Эти линки указывают на струтуры "LIST_ENTRY" предыдущего и следущего процесса от тебя, т.е. ты посередине. Вот и двигайся хочешь вперёд, хочешь назад, и рано или поздно (в зависимости от кол-ва активных процессов) вернёшься опять к себе.

Код:
0: kd> dt _eprocess fffffa80`0182bb10 ActiveProcessLinks.
ntdll!_EPROCESS
   +0x188 ActiveProcessLinks  :  [ 0xfffffa80`02a07808 - 0xfffff800`02e6f420 ]
      +0x000 Flink               : 0xfffffa80`02a07808 _LIST_ENTRY [ 0xfffffa80`0371c1e8 - 0xfffffa80`0182bc98 ]
      +0x008 Blink               : 0xfffff800`02e6f420 _LIST_ENTRY [ 0xfffffa80`0182bc98 - 0xfffffa80`01cfa348 ]
 
А
В структуре "LIST_ENTRY" лежат 2 указателя: Flink (forward, вперёд), и Blink (backward, назад).
Эти линки указывают на струтуры "LIST_ENTRY" предыдущего и следущего процесса от тебя, т.е. ты посередине. Вот и двигайся хочешь вперёд, хочешь назад, и рано или поздно (в зависимости от кол-ва активных процессов) вернёшься опять к себе.

Код:
0: kd> dt _eprocess fffffa80`0182bb10 ActiveProcessLinks.
ntdll!_EPROCESS
   +0x188 ActiveProcessLinks  :  [ 0xfffffa80`02a07808 - 0xfffff800`02e6f420 ]
      +0x000 Flink               : 0xfffffa80`02a07808 _LIST_ENTRY [ 0xfffffa80`0371c1e8 - 0xfffffa80`0182bc98 ]
      +0x008 Blink               : 0xfffff800`02e6f420 _LIST_ENTRY [ 0xfffffa80`0182bc98 - 0xfffffa80`01cfa348 ]
аааа это да, просто я не так понял
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Все правильно расписали. Тебе нужно реализовать обход double linked list и сверяться либо с полем UniqueProcessId, либо можно с ImageFileName. Тут уже от ситуации зависит.
 
Имхо парсить eprocess в ручную можно только в целях самообразования, т.к. это внутренняя структура ядра и оффсеты полей в ней отличаются не только в x32/64, но и в разных релизах одной и той-же версии Win, т.е. о никакой кросплатформенности тут не может быть и речи. Например то-же поле "ActiveProcessLinks" на моей Win7-х64 лежит по смещению 0x188 от начала eprocess, на Win10 уже 0x2f0, а в Win11 вообще 0x448 (оффсеты зависят от размера вложенной структуры kprocess=pcb). В результате, на какой машине ты соберёшь исходник драйвера, компиль подставит офсеты именно твоей текущей ос, и соответственно после смены платформы, профит от кода окажется под вопросом.

Допустим нашёл ты нужный процесс через цепочку "ActiveProcessLinks". Теперь чтобы найти адрес его eprocess, нужно будет от текущего адреса "ActiveProcessLinks", отнять как-раз смещение этого линка внутри eprocess, которое плавает в диапазоне от 0x188 до 0x448 на разных системах. В отладчике WinDbg это сделать легко, а вот реализовать вручную в зависимости от ос и архитектуры.. Конечно можно заюзать массив заранее предопределённых констант, но это явный костыль. Все эти проблемы снимают вызовы api, тем-более что дров тебя запалит больше, чем парочка безобидных функций.

Но есть один финт, которым можно попытаться динамически вычислить смещение поля "ActiveProcessLinks", правда незнаю, насколько это работает в наши дни. Суть в том, что помимо переменной "PsInitialSystemProcess", в ядре имеется ещё одна переменная "PsActiveProcessHead". Если первая хранит указатель на eprocess системы, то вторая - это указатель как-раз на поле "ActiveProcessLinks" в системном eprocess. Таким образом, если вычесть значение Process из Head, получим смещение в байтах - вот пример:

Код:
0: kd> dp PsActiveProcessHead L1
fffff800`02e3b420   fffffa80`0182bc98     <--- адрес "ActiveProcessLinks" процесса System

0: kd> dp PsInitialSystemProcess L1
fffff800`02ec3028   fffffa80`0182bb10     <--- адрес "EPROCESS" процесса System
---------------------------------------

fffffa80`0182bc98 - fffffa80`0182bb10 = 0x188  <--- оффсет "ActiveProcessLinks" внутри "EPROCESS"

А так можно проверить это-же смещение без ввода явных значений:

Код:
0: kd> ? @@c++(#FIELD_OFFSET(nt!_eprocess, ActiveProcessLinks))
Evaluate expression: 392 = 00000000`00000188
 
Последнее редактирование:
Решение
Имхо парсить eprocess в ручную можно только в целях самообразования, т.к. это внутренняя структура ядра и оффсеты полей в ней отличаются не только в x32/64, но и в разных релизах одной и той-же версии Win, т.е. о никакой кросплатформенности тут не может быть и речи. Например то-же поле "ActiveProcessLinks" на моей Win7-х64 лежит по смещению 0x188 от начала eprocess, на Win10 уже 0x2f0, а в Win11 вообще 0x448 (оффсеты зависят от размера вложенной структуры kprocess=pcb). В результате, на какой машине ты соберёшь исходник драйвера, компиль подставит офсеты именно твоей текущей ос, и соответственно после смены платформы, профит от кода окажется под вопросом.

Допустим нашёл ты нужный процесс через цепочку "ActiveProcessLinks". Теперь чтобы найти адрес его eprocess, нужно будет от текущего адреса "ActiveProcessLinks", отнять как-раз смещение этого линка внутри eprocess, которое плавает в диапазоне от 0x188 до 0x448 на разных системах. В отладчике WinDbg это сделать легко, а вот реализовать вручную в зависимости от ос и архитектуры.. Конечно можно заюзать массив заранее предопределённых констант, но это явный костыль. Все эти проблемы снимают вызовы api, тем-более что дров тебя запалит больше, чем парочка безобидных функций.

Но есть один финт, которым можно попытаться динамически вычислить смещение поля "ActiveProcessLinks", правда незнаю, насколько это работает в наши дни. Суть в том, что помимо переменной "PsInitialSystemProcess", в ядре имеется ещё одна переменная "PsActiveProcessHead". Если первая хранит указатель на eprocess системы, то вторая - это указатель как-раз на поле "ActiveProcessLinks" в системном eprocess. Таким образом, если вычесть значение Process из Head, получим смещение в байтах - вот пример:

Код:
0: kd> dp PsActiveProcessHead L1
fffff800`02e3b420   fffffa80`0182bc98     <--- адрес "ActiveProcessLinks" процесса System

0: kd> dp PsInitialSystemProcess L1
fffff800`02ec3028   fffffa80`0182bb10     <--- адрес "EPROCESS" процесса System
---------------------------------------

fffffa80`0182bc98 - fffffa80`0182bb10 = 0x188  <--- оффсет "ActiveProcessLinks" внутри "EPROCESS"

А так можно проверить это-же смещение без ввода явных значений:

Код:
0: kd> ? @@c++(#FIELD_OFFSET(nt!_eprocess, ActiveProcessLinks))
Evaluate expression: 392 = 00000000`00000188
Спасибо тебе, очень информативно ты сильно мне помог !)
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх