使用Python从进程的内存中读取数据 [英] reading data from process' memory with Python

查看:2713
本文介绍了使用Python从进程的内存中读取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过输入进程名称,然后使用psutil查找PID来从进程的内存中读取数据。到目前为止,我有:

I'm trying to read data from memory of a process by inputing the process name, then finding PID using psutil. So far I have this:

import ctypes
from ctypes import *
from ctypes.wintypes import *
import win32ui
import psutil # install, not a default module
import sys

# input process name
nameprocess = "notepad.exe"

# find pid
def getpid():
    for proc in psutil.process_iter():
        if proc.name() == nameprocess:
            return proc.pid

PROCESS_ID = getpid()

if PROCESS_ID == None:
    print "Process was not found"
    sys.exit(1)


# read from addresses
STRLEN = 255

PROCESS_VM_READ = 0x0010
process = windll.kernel32.OpenProcess(PROCESS_VM_READ, 0, PROCESS_ID)
readProcMem = windll.kernel32.ReadProcessMemory
buf = ctypes.create_string_buffer(STRLEN)

for i in range(1,100): 
    if readProcMem(process, hex(i), buf, STRLEN, 0):
        print buf.raw


最后的佛如果我理解正确,r循环应读取并打印过程中前100个地址的内容。唯一的事情是,输出看起来完全是乱码。


The last for loop should read and print contents of the first 100 addresses in the process if I'm getting this right. Only thing is, the output looks like complete gibberish.


这里有两个问题:首先,我真的以这种方式从所选进程中读取地址吗?其次,如果可能有某种结束地址,我该如何确定循环应该走多长时间?


There are 2 problems for me here: first, am I really reading the addresses from the selected process this way? And second, how can I figure how long in the loop I should go, if there is maybe some kind of end address?

推荐答案

我没有安装 psutil ,而是使用任务管理器和 SysInternals VMMap 。数字当然会有所不同。

I didn't install psutil, but just pulled a process ID and valid virtual address using Task Manager and SysInternals VMMap. The numbers will vary of course.

ctypes的良好做法是通过 .argtypes 和 .restype 。获取您自己的kernel32库实例,因为更改缓存的 windll.kernel32 实例的属性可能会导致其他使用ctypes和kernel32的模块出现问题。

Good practice with ctypes is to define the argument types and return value via .argtypes and .restype. Get your own instance of the kernel32 library because changing the attributes of the cached windll.kernel32 instance could cause issues with other modules using ctypes and kernel32.

您需要一个有效的虚拟地址。为了回答您的第二个问题,我认为VMMap证明了有一种方法可以做到。

You need a valid virtual address. In answer to your 2nd problem, I think VMMap proves there is a way to do it. Pick up a copy of Windows Internals to learn the techniques.

from ctypes import *
from ctypes.wintypes import *

PROCESS_ID = 9476 # From TaskManager for Notepad.exe
PROCESS_HEADER_ADDR = 0x7ff7b81e0000 # From SysInternals VMMap utility

# read from addresses
STRLEN = 255

PROCESS_VM_READ = 0x0010

k32 = WinDLL('kernel32')
k32.OpenProcess.argtypes = DWORD,BOOL,DWORD
k32.OpenProcess.restype = HANDLE
k32.ReadProcessMemory.argtypes = HANDLE,LPVOID,LPVOID,c_size_t,POINTER(c_size_t)
k32.ReadProcessMemory.restype = BOOL

process = k32.OpenProcess(PROCESS_VM_READ, 0, PROCESS_ID)
buf = create_string_buffer(STRLEN)
s = c_size_t()
if k32.ReadProcessMemory(process, PROCESS_HEADER_ADDR, buf, STRLEN, byref(s)):
    print(s.value,buf.raw)

输出(注意 MZ 程序标头的开头):

Output (Note 'MZ' is the start of a program header):

255 b'MZ\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x0e\x1f\xba\x0e\x00\xb4\t\xcd!\xb8\x01L\xcd!This program cannot be run in DOS mode.\r\r\n$\x00\x00\x00\x00\x00\x00\x00\xd0\x92\xa7\xd1\x94\xf3\xc9\x82\x94\xf3\xc9\x82\x94\xf3\xc9\x82\x9d\x8bZ\x82\x8a\xf3\xc9\x82\xfb\x97\xca\x83\x97\xf3\xc9\x82\xfb\x97\xcd\x83\x83\xf3\xc9\x82\xfb\x97\xcc\x83\x91\xf3\xc9\x82\xfb\x97\xc8\x83\x8f\xf3\xc9\x82\x94\xf3\xc8\x82\x82\xf2\xc9\x82\xfb\x97\xc1\x83\x8d\xf3\xc9\x82\xfb\x976\x82\x95\xf3\xc9\x82\xfb\x97\xcb\x83\x95\xf3\xc9\x82Rich\x94\xf3\xc9\x82\x00\x00\x00\x00\x00\x00\x00\x00PE\x00\x00d\x86\x06\x00^\'\x0f\x84\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00"'

这是VMMap的屏幕快照,指示notepad.exe的标头地址:

Here's a screenshot of VMMap indicating the header address of notepad.exe:

这是notepad.exe内容的十六进制转储的屏幕快照,与程序的输出相匹配:

Here's a screenshot of a hexdump of the content of notepad.exe that matches the output of the program:

这篇关于使用Python从进程的内存中读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆