nesse tutorial vou mostrar como visualizo o conteúdo de um processo na memória.
A primeira coisa a se fazer é bem obvia é pegar a lista de todos os processos que estão rodando.
Para tal, usamos a função CreateToolhelp32Snapshot para tirar um snapshot dos processos.
Depois utilizamos Process32First para pegar o primeiro processo da lista.
E para mudar para o próximo processo usamos Process32Next.
Quando usamos Process32Frist ou Process32Next é necessário passar uma variável do tipo, PROCESSENTRY32.
Nessa a estrutura é:
Private Type PROCESSENTRY32 dwSize As Long 'Tamanho da estrutura End TypecntUsage As Long 'Long usado sempre é zero th32ProcessID As Long 'Identificador do processo th32DefaultHeapID As Long 'Long usado sempre é zero th32ModuleID As Long 'Long usado sempre é zero cntThreads As Long 'Numero de thread executados pelo processo th32ParentProcessID As Long 'Identifica o process pai pcPriClassBase As Long 'A base primária de qualquer thread criado pelo processo dwFlags As Long 'Long usado sempre é zero szExeFile As String * MAX_PATH 'Nome do executável |
Abaixo uma função que pega todos os processos que estão rodando.
'Pego listagem de todos os processos Private Sub TodosProcessos() Dim hSnapShot As Long ' End SubDim uProcess As PROCESSENTRY32 'Estrutura dos processos Dim r As Long 'Limpo a lista de processo Me.lstvProcessos.ListItems.Clear 'pega um snapshot dos processos hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&) uProcess.dwSize = Len(uProcess) 'Pega o primeiro processo r = Process32First(hSnapShot, uProcess) 'Enquanto estiver tiver um processo na lista fica no loop Do While r 'Adiciona o id do processo na lista Me.lstvProcessos.ListItems.Add , , uProcess.th32ProcessID 'Pega o nome do processo Me.lstvProcessos.ListItems.Item(Me.lstvProcessos.ListItems.Count).SubItems(1) = Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0)) 'Termina qualquer tipo de evento DoEvents 'Pega o próximo processo r = Process32Next(hSnapShot, uProcess) Loop 'Fecho o snapshot CloseHandle hSnapShot |
pegar as regiões onde esse processo se encontra.
Para isso usamos a API VirtualQueryEx nela é necessário passar o identificador
do processo.
Um ponteiro para o endereço base.
Um variável do tipo MEMORY_BASIC_INFORMATION.
E o tamanho da estrutura de MEMORY_BASIC_INFORMATION.
Para pegar o identificado do processo usamos OpenProcess passando a constante
PROCESS_ALL_ACCESS, para ter livre acesso no processo, depois (False) diz para não herdar o handle do processo atual, depois passe a identificação do processso que deseja abrir.
Será retornado o valor do handle do process aberto.
O endereço base se inicia com 0, no loop é implementado na variável lPosMem que é a soma do endereço encontrado com o tamanho da região.
lPosMem = mbi.BaseAddress + mbi.regionSize |
A estrutura de MEMORY_BASIC_INFORMATION:
Private Type MEMORY_BASIC_INFORMATION BaseAddress As Long 'Base do endereço de memória End TypeAllocationBase As Long 'Contem o endereço base da memoria do processo AllocationProtect As Long 'Mostra qual tipo de proteção utilizado regionSize As Long 'Tamanho da região State As Long 'Estado da Região Protect As Long 'Tipo de proteçao lType As Long 'Tipo de região |
Para as informações State(Estado), Protect(Proteção) e lType(qual é o tipo da região).
Usamos as seguintes constantes para definir o que é cada coisa.
'State memory Private Const MEM_COMMIT = &H1000 'Indicates committed pages for which physical storage has been allocated, 'either in memory or in the paging file on disk. Private Const MEM_FREE = &H10000 'Indicates free pages not accessible to the calling process and available 'to be allocated. For free pages, the information in the AllocationBase, 'AllocationProtect, Protect, and Type members is undefined. Private Const MEM_RESERVE = &H2000 'Indicates reserved pages where a range of the process's virtual address 'space is reserved without any physical storage being allocated. 'For reserved pages, the information in the Protect member is undefined. 'Type Memory Private Const MEM_IMAGE = &H1000000 'Indicates that the memory pages within the region are mapped into the 'view of an image section. Private Const MEM_MAPPED = &H40000 'Indicates that the memory pages within the region are mapped into the view 'of a section. Private Const MEM_PRIVATE = &H20000 'Indicates that the memory pages within the region are private '(that is, not shared by other processes). 'Tipo de proteção Private Const PAGE_NOACCESS = &H1 Private Const PAGE_READONLY = &H2 Private Const PAGE_READWRITE = &H4 Private Const PAGE_WRITECOPY = &H8 Private Const PAGE_EXECUTE = &H10 Private Const PAGE_EXECUTE_READ = &H20 Private Const PAGE_EXECUTE_READWRITE = &H40 Private Const PAGE_EXECUTE_WRITECOPY = &H80 |
A função abaixo percorre toda a memória do processo.
Basicamente, inicia do zero depois lê o a primeira região pega o endereço da região
e soma com o tamanho da região o resultado da soma é usado como endereço base na
próxima região que será "pegada" vez que iniciar o do zero novamente.
'Pega as regiões de memoria Private Sub RetrieveMemRegions(ByVal PID As Long) Dim lHandle As Long 'Handle do processo End SubDim lPosMem As Long 'Posição de memoria lida Dim lRet As Long 'Parte de memoria lida Dim lLenMBI As Long 'Tamanho da estrutura mbi Dim mbi As MEMORY_BASIC_INFORMATION 'Informação da região de memoria Dim si As SYSTEM_INFO 'Informação do sisteam 'initialise les tableaux 'inicializa as tabelas ReDim lBaseAdress(0) ReDim lRegionSize(0) 'Limpo minha lista de endereços Me.lstvPosicoesMemoria.ListItems.Clear 'obtient le handle du processus 'obtém os handle do processo lHandle = OpenProcess(PROCESS_ALL_ACCESS, False, PID) lLenMBI = Len(mbi) 'tamanho da estrutura GetSystemInfo si 'Obtém informações dos endereços de memória e da máquina 'Enquanto o endereço atual não for maior do que o maior endereço atual Do While lPosMem < si.lpMaximumApplicationAddress 'Limpo o tamanho mbi.regionSize = 0 'obtém as informações da memória definida pelo handle processo (hProcess) VirtualQueryEx lHandle, ByVal lPosMem, mbi, lLenMBI With Me.lstvPosicoesMemoria 'Adiciono o endereço de memoria int .ListItems.Add , , mbi.BaseAddress 'Transformo o endereço para hexadecimal .ListItems.Item(.ListItems.Count).SubItems(1) = Hex(mbi.BaseAddress) 'Pego o tamanho do região da memória .ListItems.Item(.ListItems.Count).SubItems(2) = mbi.regionSize 'Seleciono qual é tipo de memória Select Case mbi.lType Case MEM_IMAGE .ListItems.Item(.ListItems.Count).SubItems(3) = "Memory Image" Case MEM_PRIVATE .ListItems.Item(.ListItems.Count).SubItems(3) = "Memory Private" Case MEM_MAPPED .ListItems.Item(.ListItems.Count).SubItems(3) = "Memory Mapped" End Select 'Seleciono qual é o tipo de proteção Select Case mbi.Protect Case PAGE_EXECUTE .ListItems.Item(.ListItems.Count).SubItems(4) = "Executavel" Case PAGE_EXECUTE_READ .ListItems.Item(.ListItems.Count).SubItems(4) = "Execute+Read" Case PAGE_EXECUTE_READWRITE .ListItems.Item(.ListItems.Count).SubItems(4) = "Execute + Read + Write" Case PAGE_EXECUTE_WRITECOPY .ListItems.Item(.ListItems.Count).SubItems(4) = "Execute + WriteCopy" Case PAGE_NOACCESS .ListItems.Item(.ListItems.Count).SubItems(4) = "No Access" Case PAGE_READONLY .ListItems.Item(.ListItems.Count).SubItems(4) = "Read Only" Case PAGE_READWRITE .ListItems.Item(.ListItems.Count).SubItems(4) = "Read + Write" Case PAGE_WRITECOPY .ListItems.Item(.ListItems.Count).SubItems(4) = "Write Copy" End Select 'Seleciono qual é o estado da memória Select Case mbi.State Case MEM_COMMIT .ListItems.Item(.ListItems.Count).SubItems(5) = "Memory Commit" Case MEM_FREE .ListItems.Item(.ListItems.Count).SubItems(5) = "Memory Free" Case MEM_RESERVE .ListItems.Item(.ListItems.Count).SubItems(5) = "Memory Reserve" End Select End With 'Pego o posicionamento atual da memoria lPosMem = mbi.BaseAddress + mbi.regionSize Loop |
para isso usamos a API ReadProcessMemory novamente é necessário passar
o handle do processo, o endereço, o buffer que receberá os dados, o tamanho, o
ultimo parâmetro não sei realmente para que que serve passo como 0.
Essa API não tem muito segredo não. No caso tô lendo o endereço na memória e
colocando tudo dentro de uma string.
Abaixo o código lê uma região de memória coloca em um buffer string e pega os
char e converte para Hex.
Public Sub ReadBytesH(ByVal PID As Long, ByVal lngOffset As Long, ByVal lngRegionSize As Long) Dim sBuf As String 'Buffer que recebe os valores da memoria End SubDim lByte As Long 'Parametro ignorado em ReadProcessMemory Dim posicaoFinal As Long 'Contém o ultimo endereço a ser lido Dim lHandle As Long 'Contém a identificação do processo Dim continua As Integer 'Verifica se continua Dim lenBuffer As Integer 'Tamanho do buffer lido Dim valoresHex As String 'Contém os valores em hex do buffer lido Dim tmpContador As Integer 'Contador temporário(para transforma em hex) 'pego a posição final somando o endereço mais o tamanho da região posicaoFinal = lngOffset + lngRegionSize 'Inicialização das variáveis continua = 1 lenBuffer = 1 'obtém os handle do processo lHandle = OpenProcess(PROCESS_ALL_ACCESS, False, PID) 'Limpo a lista de dados Me.lstvDados.ListItems.Clear 'Cria um buffer sBuf = String$(16, 0) While continua <> 0 'pego os byte do endereço com um tamanho de 16 continua = ReadProcessMemory(lHandle, lngOffset, sBuf, 16, lByte) With Me.lstvDados.ListItems 'Adiciono o endereço em int .Add , , lngOffset 'Converto o endereço para hexadecimal .Item(.Count).SubItems(1) = Hex(lngOffset) 'Pego o tamanho do buffer (16) .Item(.Count).SubItems(4) = Len(sBuf) End With 'Pego a string e retiro os caracteres chr(0) Me.lstvDados.ListItems.Item(Me.lstvDados.ListItems.Count).SubItems(2) = Replace(sBuf, Chr(0), "") 'Inicializo o contador de string lenBuffer = 1 While lenBuffer <= Len(sBuf) 'Pego o valor(byte) 'eu acho' em int e transformo para hex valoresHex = valoresHex & " " & Hex(Asc(Mid(sBuf, lenBuffer, 1))) lenBuffer = lenBuffer + 1 Wend 'Adiciono os valores em hexadecimal Me.lstvDados.ListItems.Item(Me.lstvDados.ListItems.Count).SubItems(3) = valoresHex 'Adiciono mais 16 no endereço atual lngOffset = lngOffset + 16 'Inicializo o buffer que contem os valores em hex valoresHex = "" Wend |
Valeuw!
http://alucard.dxs.googlepages.com/MemoryView.zip
Nenhum comentário:
Postar um comentário