Как стать автором
Обновить

Комментарии 24

Перефразируя известное выражение, "Есть хорошие статьи, есть плохие, а есть про реверс/низкоуровневый доступ" :)
Но для "низкоуровневиков" как я такие статьи очень ценны, т.к. тема уж очень специфическая и не очень популярная, материалов Чак Норрис наплакал.

Угу, и поэтому старался по максимуму разжевать те участки по которым мало информации. То что доступно (по РЕ формату например) так, вскользь прошелся, чтобы общий контекст не терялся, иначе статья бы распухла неимоверно (и так хабр пишет что 98 минут на чтение - внезапно)

Польза только для ring 0, или прокатит и для ring -1, -2 ?

Это про третье кольцо, т.е. можно подключать в любой прикладной код.

Видимо, стоит обмолвиться, что речь идет о Windows)

Добавил

Очень годное чтиво. Спасибо огромное!

А если сканер сразу делать 64-битным? У ваших клиентов остались где-то 32-битные системы, или есть другая причина так не делать?

Да, у госов встречаются, не так часто как раньше, но бывает.

вообще выглядит интересно , но есть 2 вопроса:
1. почему именно делфи?
2. если я правильно понял суть статьи то подход живет ровно до момента пока хук не встанет на метод проверки на хуки)

1) а почему бы и нет?
2) этот подход должен применятся в стороннем ПО, а не в том, которое будет анализироваться, и в котором живут все перехваты.

Иногда чтобы понять самому куда идти дальше нужно "выплеснуть на бумагу". Респект!

32 процессы в 64 OS:

\system32 перенаправляется в \SysWOW64 самой OS, т.е. для Процесс- 2 \SysWOW64 самой OS представляется как \system32

для доступа к "истинной 64 разрядной" \system32 Процесс- 32 должен использовать

C:\Windows\Sysnative\

т.к. мы "залезли" из 64 в 32, то PPEB_LDR_DATA->Ldr будут ссылаться на \system32, которая

для них "истинная от самой 64 OS"

На примере delphi32.exe Delphi 7 в Windows 10 64

Вид на delphi32.exe из 64 битного процесса (ImageBase,OEP, SizeImage)

Из 64 процесса за реальным 64-процессом delphi32.exe в 64 OS

C:\Program Files (x86)\Borland\Delphi7\Bin\delphi32.exe
base: $0000000000400000 oep: $000000000041FEB4 size: $00089000 (561152)
C:\Windows\SYSTEM32\ntdll.dll
base: $00007FFE95540000 oep: $0000000000000000 size: $001EE000 (2023424) <<-- 64 ntdll
C:\Windows\System32\wow64.dll
base: $00007FFE94850000 oep: $00007FFE948670D0 size: $00053000 (339968)
C:\Windows\System32\wow64win.dll
base: $00007FFE948B0000 oep: $00007FFE948BF030 size: $0007C000 (507904)
C:\Windows\System32\wow64cpu.dll
base: $0000000077CD0000 oep: $0000000077CD12A0 size: $00009000 (36864)

<ВСЕГО 5 МОДУЛЕЙ>

а вот как это видит сама delphi32.exe и другие 32 процессы

0 delphi32.exe
00400000 0041FEB4 00089000
1 ntdll.dll
77CE0000 00000000 0019E000 <<--- 32 ntdll как и все остальные
2 KERNEL32.DLL
76AD0000 76AF0140 000E0000
3 KERNELBASE.dll
76BB0000 76CC5440 00201000
.................................

268 ncryptsslp.dll
6E570000 6E57A720 0001F000
268 модулей (267 DLL)

Смотрим из 64 процесса в 32 процесс

C:\Program Files (x86)\Borland\Delphi7\Bin\delphi32.exe
C:\Windows\SysWOW64\ntdll.dll
C:\Windows\SysWOW64\KERNEL32.DLL
C:\Windows\SysWOW64\KERNELBASE.dll
............................................
C:\Program Files (x86)\Borland\Delphi7\Bin\rtl70.bpl
.............................................
C:\Windows\SysWOW64\cryptnet.dll
C:\Windows\SysWOW64\ncryptsslp.dll

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Взгляд из любого 32 разрядного процесса на процесс delphi32.exe
имена DLL по загрузке

0 C:\Program Files (x86)\Borland\Delphi7\Bin\delphi32.exe
1 C:\Windows\SYSTEM32\ntdll.dll
2 C:\Windows\System32\KERNEL32.DLL
3 C:\Windows\System32\KERNELBASE.dll
.............................................................
8 C:\Program Files (x86)\Borland\Delphi7\Bin\rtl70.bpl
...............................................................
267 C:\Windows\System32\cryptnet.dll
268 C:\Windows\system32\ncryptsslp.dll

267 модулей DLL

То есть, если сканер делать 64-битным, будет проблемой получить список модулей 32-битного процесса?

Да не должно быть, код универсальный и работать будет при любой битности как самой сборки так и исследуемого процесса.

как решать

  1. 64-р сканер

создать из 64-р вспомагательный 32-р процесс => CreateProcess(...My32....)

My32 выполнит ВСЕ необходимое и вернет данные,например, через разделяемый map

file или просто файл

Т.е.нужно писать 32 - р приложение для этого: My32 - консольное (скрытое)

  1. 32-р сканер

Отметим, что из 32-р легче получить доступ к 64-р:

используем Windows API:

OpenProcess => и использовать LookupPrivilegeValueW; AdjustTokenPrivileges для получения привилегий доступа к 64-р процессу
NtQueryInformationProcess
NtWow64QueryInformationProcess64
NtWow64ReadVirtualMemory64
NtQueryInformationThread

структуры:

PROCESS_BASIC_INFORMATION_WOW64
PEB64
RTL_USER_PROCESS_PARAMETERS64

и другие

Зачем создавать 32 битную копию? 64 битный код спокойно получит всю необходимую информацию из 32 битного процесса.

Нет API. А вычитывание недокументированных структур из памяти опасно из-за неатомарности эти чтений. Что будет, если в процессе чтения списки изменятся?

Работа с недокументированными структурами всегда опасна, например буквально в том месяце вышло обновление под Win11 за номером KB5022845 (Build 22621.1265) в котором изменился размер структуры _RTL_HEAP_INFORMATION и что? :)
Ну подправили размеры и работаем дальше, делов то?

Начал читать, подумал MS Rem ожил ...

Я это часто слышу :)

Непонятно, какой смысл в EmptyStr в Delphi?


Пустая строка в C#, например, это полноценный объект, и там string.Empty имеет смысл для экономии памяти. Но в Delphi пустая строка, ровно как и пустой динамический массив, это NULL-ссылка, т.е. указатель со значением 0.

Насколько я помню она оставлена для обратной совместимости и кстати её использование дает мальца просадку по сравнению с просто указанием пустой строки кавычками, но... привычка, видимо я уже настолько стар что эта совместимость для меня и оставлена :)

Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории