Site hosted by Angelfire.com: Build your free website today!

Funciones Toolhelp32 relativas a los Procesos y Modulos

Aproximación desde MASM

Por Iczelion

email: Iczelion@galaxycorp.com

Traducción: nuMIT_or

 

Toolhelp es una biblioteca agregada a Windows 3.1. Puedes usar las funciones toolhelp para enumerar procesos, hilos [threads], módulos y montículos [heaps]. Como tales, son una herramienta muy valiosa. Así que cuando Windows 95 salió a la luz, la toolhelp fue integrada en el sistema. La versión de toolhelp bajo Windows 95 es de 32-bit, por eso se le llamó toolhelp32. Sin embargo, toolhelp32 no está disponible Windows NT 4.0 [pero sí en Windows 2000 (nota del trad.] .

Por debajo de la capucha [under the hood], las funciones toolhelp a través de un íntimo conocimiento del sistema operativo. Con el fin de enumerar los procesos, debes tener conocimientos sobre la base de datos de los procesos. Si estás interesado en esta información, debes leer Windows 95 System Programming Secrets de Matt Pietrek.

Podemos dividir las funciones en la toolhelp32 en de 4 grupos:
  1. Funciones de enumeración de procesos
  2. Funciones de enumeración de módulos
  3. Funciones de enumeración de montículos [heaps]
  4. Funciones de enumeración de hilos [threads]

El uso de cada categoría es muy similar así que usaré las funciones de enumeración de procesos y de módulos.

He escrito un programa de ejempo con el scódigo fuente que enumera todos los procesos y los módulos en cada proceso. Puedes bajar el ejmplo desde aquí

Antes de que puedas usar las fucniones de la toolhelp32, debes obtener un handle a un 'snapshot'. Un 'snapshot' le dice a la toolhelp32 lo que quieres hacer. Primero debes llamar a la función CreateToolhelp32Snapshot para obtener el handle al snapshot. Su sintaxis es la siguiente:

CreateToolhelp32Snapshot PROTO dwFlags : DWORD, th32ProcessID : DWORD

Esta función toma dos parámetros:

dwFlags : Especificar el tipo de snapshot que quieres.

TH32CS_SNAPHEAPLIST
equ 1
TH32CS_SNAPPROCESS
equ 2
TH32CS_SNAPTHREAD
equ 4
TH32CS_SNAPMODULE
equ 8
TH32CS_SNAPALL
equ TH32CS_SNAPHEAPLIST + TH32CS_SNAPPROCESS
+ TH32CS_SNAPTHREAD + TH32CS_SNAPMODULE
TH32CS_INHERIT
equ 80000000h

Por ejemplo, si quieres enumerar procesos, debes usar TH32CS_SNAPPROCESS.

th32processID : El processID del proceso con el que quieres que opere(n) la(s) función(es) to operate. Este parámetro sólo es usado cuando TH32CS_SNAPHEAPLIST o TH32CS_SNAPMODULE es especificado porque los montículos y los módulos dependen del proceso. Puedes especificar 0 como valor para este parámetro, lo cual será interpretado por toolhelp32 como processID del proceso actual.

CreateToolhelp32Snapshot regresa un handle al snapshot que solicitas. Después que lo hayas usado para tus fines, necesitas llamar a CloseHandle para cerrarlo.

Después de obtener el handle al snapshot, podemos llamar a las funciones toolhelp32. Primero mostraré cómo enumerar los procesos.

Para enumerar procesos debes llamar a CreateToolhelp32Snapshot con TH32CS_SNAPPROCESS, y th32processID debería ser cero. Luego llamamos a Process32First para obtener información sobre el primer proceso y Process32Next para recuperar la información del siguiente proceso. Estas funciones se definen así:

Process32First PROTO hSnapshot : DWORD, lppe : DWORD
Process32Next PROTO hSnapshot : DWORD, lppe : DWORD

hSnapshot : el handle al snapshot handle obtenido en la llamada a CreateToolhelp32Snapshot

lppe : puntero a una estructura PROCESSENTRY32 definida de la siguiente manera:

PROCESSENTRY32 STRUCT DWORD
dwSize
DWORD?; Tamaño de esta estructura
cntUsage
DWORD?; Número de instancias (?)
th32ProcessID
DWORD?; ProcessID del proceso
th32DefaultHeapID
DWORD?; ID del montículo por defecto
th32ModuleID
DWORD?; ModuleID exe asociado
cntThreads
DWORD?; Número de hilos [threads] en el proceso
th32ParentProcessID
DWORD?; ProcessID del proceso padre
pcPriClassBase
DWORD?; Prioridad base de los hilos del proceso
dwFlags
DWORD?; Reservado
szExeFile
db 260 dup (?) ; Nombre completo del archivo (incluyendo el camino [path]) del archivo exe propietario del proceso.
PROCESSENTRY32 ENDS

Process32First y Process32Next regresan TRUE si la operación es exitosa, FALSE si no hay proceso que enumerar.

Veamos un recorte de código:

.data

hSnapshot DWORD ?
.data?

pe32 PROCESSENTRY32 <>

.code
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
; obtener un handle al snapshot para la 
; enumeración de los procesos
mov hSnapshot, eax
; Guardar el handle al snapshot
mov pe32.dwSize, sizeof PROCESSENTRY32
; dwSize es el único miebro a llenar
invoke Process32First, hSnapshot, addr pe32
; Obtener info sobre el primer proceso
.while eax==TRUE
; Enumerar hasta que no haya otro
; proceso
   <do something with the information in pe32 structure>
   invoke Process32Next, hSnapshot, addr pe32
; Obtener info sobre procesos
; subsecuentes
.endw
invoke CloseHandle, hSnapshot
; Cerrar el handle del snapshot al
; terminar la enumeración.

La enumeración de módulos essimilar a la operación anterior pero con una pequeña diferencia: se debe obtener el processID del proceso cuyos módulos quieres enumerar. Puedes usar el miembro th32processID de la estructura PROCESSENTRY32 como segundo parámetro de la función CreateToolhelp32Snapshot. Hay dos funciones para realizar la enumeración:

Module32First PROTO hSnapshot : DWORD, lpme : DWORD
Module32Next PROTO hSnapshot : DWORD, lpme : DWORD

hSnapshot : handle al snapshot.

lpme : puntero a una estructura MODULEENTRY32 que está definida así:

MODULEENTRY32 STRUCT DWORD
dwSize
DWORD?; Tamaño de esta estructura
th32ModuleID
DWORD?; Este módulo
th32ProcessID
DWORD?; Proceso propietario
GlblcntUsage
DWORD?; Global usage count sobre el módulo
ProccntUsage
DWORD?; Module usage count en el contexto del th32ProcessID
ModBaseAddr
DWORD?; Dirección base del módulo en el contexto del th32ProcessID
ModBaseSize
DWORD?; Tamaño en bytes del módulo inicial en modBaseAddr
hModule
DWORD?; El hModule de este módulo en el contexto del th32ProcessID
szModule
db 256 dup (?) ; Nombre del módulo (sin camino [path])
szExePath
db 260 dup (?) ; Nombre incluyendo el camino [path] completo del módulo
MODULEENTRY32 ENDS

Como Process32First y Process32Next, el valor de regreso es TRUE si la operación tiene éxito y FALSE si ya no hay más módulos que enumerar.

Ahora veámosla en acción. Enumeraremos todos los módulos en el proceso actual.

.data

hSnapshot dd ?
.data
me32 MODULEENTRY32 <>

.code
invoke GetCurrentProcessID
; obtener el processID del proceso actual
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS,
; obtener el handle snapshot para
    eax
; enumerar módulos.
mov hSnapshot, eax
; Salvar el handle al snapshot
mov me32.dwSize, sizeof MODULEENTRY32
; dwSize es el único miembro que debemos
;  llenar
invoke Module32First, hSnapshot, addr me32
; Obtener info sobre el primer módulo en el
;  proceso
.while eax==TRUE
; Enumerar hasta que no hayan módulos
   <do something with the information in me32 structure>
   invoke Module32Next, hSnapshot, addr me32
; Obtener nfo sobre subsecuentes módulos
.endw
invoke CloseHandle, hSnapshot
; Cerrar el handle al snapshot al terminar

La historia de las funeciones de enumeración de los hilos es la misma que la de las funciones de enumeración de módulos. Tienes que especificar el ID del proceso cuyos hilos quieres enumerar.

Las funciones en toolhelp32 están ahora almacenadas en n kernel32.dll así que para ellas no necesitas una dll separadas. Si quieres funciones similares bajo Windows NT 4.0, debes usar psapi.dll.