Функции toolhelp

Дата публикации 27 июн 2002

Функции toolhelp — Архив WASM.RU

Ладно, эта статья не будет переполнена теорией. Я думаю, что использование toolhelp'а достаточно легко, поэтому я объясню функции API, которые относятся к нему без всякой теоретической чепухи.

Итак, если у нас есть доступ к функциям Toolhelp (не в NT4), вы можете узнать о процессах, модулях, тредах и кучах, которые запущены сейчас в системе. Прекрасно... теперь немного теории :smile3:)). Есть нечто, что называется снапшотом системы. MSDN говорит: "Снапшот - это доступная только для чтения копия текущего состояния одного или более из следующих списков объектов, находящихся в системе: процессы, треды, модули и кучи." И это правда :smile3:)). Поэтому, если вы можете получить хэндл снапшота, вы можете увидеть запущенные в системе процессы и получить их полные пути. Отлично... с теорией все :smile3:)).

Чтобы получить хэндл снапшота, используйте функцию CreateToolhelp32Snapshot:

Код (Text):
  1.  
  2.   Функция возвращает хэндл текущего снапшота
  3.                      -1, если вызов не удался - используйте GetLastError
  4.                                                 для получения расширенной
  5.                                                 информации
  6.  
  7.   флаги - TH32CS_SNAPHEAPLIST = 1 ; включить список куч в снапшот
  8.           TH32CS_SNAPPROCESS  = 2 ; включить списко процессов
  9.           TH32CS_SNAPTHREAD   = 4 ; включить список тредов
  10.           TH32CS_SNAPMODULE   = 8 ; включить список модулей
  11.           TH32CS_SNAPALL = 1 | 2 | 4 | 8 ; в снапшот будет включено все
  12.           TH32CS_INHERIT = 080000000h    ; снапшот может наследоваться

Теперь у нас есть хэндл снапшота, который нам требовался. После того, как мы закончим с ним работать, его можно закрыть с помощью функции CloseHandle.

Код (Text):
  1.  
  2.   push хэндл снапшота
  3.   call CloseHandle

Представьте, что у нас есть хэндл снапшота процессов...

Обход процессов (и всего остального, что включено в снапшот) похож на обход файлов с помощью FindFirstFile и FindNextFile.

Код (Text):
  1.  
  2.   push указатель на структуру PROCESSENTRY32
  3.   push хэндл снапшота
  4.   call Process32First

Функция возращает TRUE в случае успеха, переданная структура содержит данные

Код (Text):
  1.  
  2.   PROCESSENTRY32 struc
  3.     _size            dd ?    ; размер структур - нужно установить до вызова
  4.     _usage           dd ?    ; ссылок на процесс - живет, пока не равно нулю
  5.     _processID       dd ?    ; PID
  6.     _defaultHeapID   dd ?    ; ID кучи процесса по умолчанию
  7.     _moduleID        dd ?    ; MID <img src="styles/smiles_s/smile3.gif" class="mceSmilie" alt=":smile3:" title="Smile3    :smile3:">)
  8.     _threads         dd ?    ; количество запущенных процессом тредов
  9.     _parentProcessID dd ?    ; PID процесса, создавшего наш процесс
  10.     _priClassBase    dd ?    ; базовый приоритет тредов
  11.     _flags           dd ?    ; зарезервировано
  12.     _exeFile db 255 dup(?)   ; лучшее напоследок - полный путь к процессам!
  13.   PROCESSENTRY32 ends

Чтобы получить следующий процесс:

Код (Text):
  1.                                                     |
  2.   push указатель на структуру PROCESSENTRY32
  3.   push хэндл снапшота
  4.   call Process32Next

Функция возвращает TRUE в случае успеха, PROCESSENTRY32 содержит данные

Есть еще одна функция, предоставленная Toolhelp, для работы с процессами:

Код (Text):
  1.  
  2.   push сколько байтов считать в буфер ; если NULL - игнорируется
  3.   push сколько байтов считать из процесса
  4.   push указатель на буфер
  5.   push адрес для чтения
  6.   push PID              ; PID процесса, из которого будет произведено чтение
  7.   call Toolhelp32ReadProcessMemory
  8.  
  9.   Функция возвращает TRUE в случае успеха
  10.  
  11.   адрес для чтения - это значение сначала проверяется системой, поэтому если
  12.                      у вас нет доступа, функция не сработает.

Представьте, что у нас есть хэндл снапшота модулей...

Этот снапшот включает список модулей, используемых каждым запущенным процессов.

Код (Text):
  1.  
  2.   push указатель на структуру MODULEENTRY32
  3.   push хэндл снапшота
  4.   call Module32First
  5.  
  6.   push указатель на структуру MODULEENTRY32
  7.   push хэндл снапшота
  8.   call Module32Next
  9.  
  10.   MODULEENTRY32 struc
  11.     _size           dd ? ; размер структуры - должен быть установлен до вызова
  12.     _moduleID       dd ? ; MID - в контексте процесса-владельца
  13.     _processID      dd ? ; PID проверяющего процесса
  14.     _glblcntUsage   dd ? ; глобальных ссылок на модуль
  15.     _proccntUsage   dd ? ; ссылок процесса на модуль
  16.     _modBaseAddr    dd ? ; базовый адрес модуля в контексте процесса
  17.     _modBaseSize    dd ? ; размер модуля
  18.     _hModule        dd ? ; хэндл модуля в контексте процесса
  19.     _module db 255 + 1 dup(?) ; имя модуля
  20.     _exePath db 255 dup(?)    ; путь к модулю
  21.   MODULEENTRY32 ends

Представьте, что у нас есть хэндл снапшота куч

С помощью этого снапшот мы можем узнать о куче каждого из запущенных процессов. сначала мы должны получить ID кучи в процессе. Это делается так:

Код (Text):
  1.  
  2.   push HEAPLIST32
  3.   push хэндл снапшота
  4.   call Heap32ListFirst
  5.  
  6.   push HEAPLIST32
  7.   push хэндл снапшота
  8.   call Heap32ListNext
  9.  
  10.   HEAPLIST32 struc
  11.     _size       dd ? ; уфффф... это размер...
  12.     _processID  dd ? ; PID процесса-владельца
  13.     _teapID     dd ? ; идентификатов кучи
  14.     _flags      dd ? ; определено как HF32_DEFAULT = 1
  15.   HEAPLIST32 ends

Ладно, с помощью этой функции мы получаем ID кучи, который понадобиться нам в дальнейшем:

Код (Text):
  1.  
  2.   push heapID      ; идентификатор кучи, который возвращается функциями xListX
  3.   push PID         ; PID процесса-владельца
  4.   push HEAPENTRY32
  5.   call Heap32First
  6.  
  7.   push HEAPENTRY32
  8.   call Heap32Next
  9.  
  10.   HEAPENTRY32 struc
  11.     _size       dd ? ; вы уже поняли <img src="styles/smiles_s/smile3.gif" class="mceSmilie" alt=":smile3:" title="Smile3    :smile3:">
  12.     _handle     dd ? ; хэндл блока кучи
  13.     _address    dd ? ; линейный адрес начала блока
  14.     _blockSize  dd ? ; размер блока кучи
  15.     _flags      dd ? ; смоти ниже
  16.     _lockCount  dd ? ; количество закрытий (Global[Local]Lokh)
  17.     _resvd      dd ? ; зарезервировано
  18.     _processID  dd ? ; PID проверяемого процесса
  19.     _heapID     dd ? ; ID кучи в контексте процесса
  20.   HEAPENTRY32 ends
  21.  
  22.   _flags - LF32_FIXED    = 1 ; блок памяти имеет фиксированное местоположение
  23.            LF32_FREE     = 2 ; блок памяти свободен
  24.            LF32_MOVEABLE = 4 ; блок памяти можно переместить

Представьте, что у нас есть хэндл снапшота тредов

Код (Text):
  1.  
  2.   push указатель на структуру THREADENTRY32
  3.   push хэндл снапшота
  4.   call Thread32First
  5.  
  6.           и
  7.  
  8.   push указатель на структуру THREADENTRY32
  9.   push хэндл снапшота
  10.   call Thread32Next

Функция возвращает то же, что и аналогичные функции работы с процессами

Код (Text):
  1.  
  2.   THREADENTRY32 struc
  3.     _size           dd ? ; размер структуры
  4.     _usage          dd ? ; ссылок на тред - живет, пока не равно нулю
  5.     _threadID       dd ? ; идентификатор треда
  6.     _ownerProcessID dd ? ; PID процесса, которые владеет тредом
  7.     _basePri        dd ? ; начальный уровень приоритета
  8.     _deltaPri       dd ? ; разность со знаком относительно базового приоритета
  9.     _flags          dd ? ; зарезервировано
  10.   THREADENTRY32 ends

Напоследок

Ладно, это все, что я нашел о Toolhelp. © mort[MATRiX], пер. Aquila


0 1.265
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532