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

Все статьи

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

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

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

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

  Функция возвращает хэндл текущего снапшота
                     -1, если вызов не удался - используйте GetLastError
                                                для получения расширенной
                                                информации

  флаги - TH32CS_SNAPHEAPLIST = 1 ; включить список куч в снапшот
          TH32CS_SNAPPROCESS  = 2 ; включить списко процессов
          TH32CS_SNAPTHREAD   = 4 ; включить список тредов
          TH32CS_SNAPMODULE   = 8 ; включить список модулей
          TH32CS_SNAPALL = 1 | 2 | 4 | 8 ; в снапшот будет включено все
          TH32CS_INHERIT = 080000000h    ; снапшот может наследоваться

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

  push хэндл снапшота
  call CloseHandle

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

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

  push указатель на структуру PROCESSENTRY32
  push хэндл снапшота
  call Process32First

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

  PROCESSENTRY32 struc
    _size            dd ?    ; размер структур - нужно установить до вызова
    _usage           dd ?    ; ссылок на процесс - живет, пока не равно нулю
    _processID       dd ?    ; PID
    _defaultHeapID   dd ?    ; ID кучи процесса по умолчанию
    _moduleID        dd ?    ; MID :))
    _threads         dd ?    ; количество запущенных процессом тредов
    _parentProcessID dd ?    ; PID процесса, создавшего наш процесс
    _priClassBase    dd ?    ; базовый приоритет тредов
    _flags           dd ?    ; зарезервировано
    _exeFile db 255 dup(?)   ; лучшее напоследок - полный путь к процессам!
  PROCESSENTRY32 ends

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

                                                    |
  push указатель на структуру PROCESSENTRY32
  push хэндл снапшота
  call Process32Next

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

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

  push сколько байтов считать в буфер ; если NULL - игнорируется
  push сколько байтов считать из процесса
  push указатель на буфер
  push адрес для чтения
  push PID              ; PID процесса, из которого будет произведено чтение
  call Toolhelp32ReadProcessMemory

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

  адрес для чтения - это значение сначала проверяется системой, поэтому если
                     у вас нет доступа, функция не сработает.

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

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

  push указатель на структуру MODULEENTRY32
  push хэндл снапшота
  call Module32First

  push указатель на структуру MODULEENTRY32
  push хэндл снапшота
  call Module32Next

  MODULEENTRY32 struc
    _size           dd ? ; размер структуры - должен быть установлен до вызова
    _moduleID       dd ? ; MID - в контексте процесса-владельца
    _processID      dd ? ; PID проверяющего процесса
    _glblcntUsage   dd ? ; глобальных ссылок на модуль
    _proccntUsage   dd ? ; ссылок процесса на модуль
    _modBaseAddr    dd ? ; базовый адрес модуля в контексте процесса
    _modBaseSize    dd ? ; размер модуля
    _hModule        dd ? ; хэндл модуля в контексте процесса
    _module db 255 + 1 dup(?) ; имя модуля
    _exePath db 255 dup(?)    ; путь к модулю
  MODULEENTRY32 ends

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

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

  push HEAPLIST32
  push хэндл снапшота
  call Heap32ListFirst

  push HEAPLIST32
  push хэндл снапшота
  call Heap32ListNext

  HEAPLIST32 struc
    _size       dd ? ; уфффф... это размер...
    _processID  dd ? ; PID процесса-владельца
    _teapID     dd ? ; идентификатов кучи
    _flags      dd ? ; определено как HF32_DEFAULT = 1
  HEAPLIST32 ends

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

  push heapID      ; идентификатор кучи, который возвращается функциями xListX
  push PID         ; PID процесса-владельца
  push HEAPENTRY32
  call Heap32First

  push HEAPENTRY32
  call Heap32Next

  HEAPENTRY32 struc
    _size       dd ? ; вы уже поняли :)
    _handle     dd ? ; хэндл блока кучи
    _address    dd ? ; линейный адрес начала блока
    _blockSize  dd ? ; размер блока кучи
    _flags      dd ? ; смоти ниже
    _lockCount  dd ? ; количество закрытий (Global[Local]Lokh)
    _resvd      dd ? ; зарезервировано
    _processID  dd ? ; PID проверяемого процесса
    _heapID     dd ? ; ID кучи в контексте процесса
  HEAPENTRY32 ends

  _flags - LF32_FIXED    = 1 ; блок памяти имеет фиксированное местоположение
           LF32_FREE     = 2 ; блок памяти свободен
           LF32_MOVEABLE = 4 ; блок памяти можно переместить

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

  push указатель на структуру THREADENTRY32
  push хэндл снапшота
  call Thread32First

          и

  push указатель на структуру THREADENTRY32
  push хэндл снапшота
  call Thread32Next

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

  THREADENTRY32 struc
    _size           dd ? ; размер структуры
    _usage          dd ? ; ссылок на тред - живет, пока не равно нулю
    _threadID       dd ? ; идентификатор треда
    _ownerProcessID dd ? ; PID процесса, которые владеет тредом
    _basePri        dd ? ; начальный уровень приоритета
    _deltaPri       dd ? ; разность со знаком относительно базового приоритета
    _flags          dd ? ; зарезервировано
  THREADENTRY32 ends

Напоследок

Ладно, это все, что я нашел о Toolhelp.

2002-2013 (c) wasm.ru