用python编写内存扫描程序

用python编写内存扫描程序,python,Python,(编辑) 很抱歉更改了内容 我已经更改了密码 nameprocess = 'calc.exe' def getpid(): for proc in psutil.process_iter(): if str(nameprocess) in str(proc.name): print nameprocess,'pid = ', proc.pid return proc.pid PID = getpid() PROCESS_

(编辑)

很抱歉更改了内容

我已经更改了密码

nameprocess = 'calc.exe'
def getpid():
    for proc in psutil.process_iter():

        if str(nameprocess) in str(proc.name):
            print nameprocess,'pid = ', proc.pid
            return proc.pid

PID = getpid()
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

process = windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,False,PID)
readprocess = windll.kernel32.ReadProcessMemory
rdbuf = ctypes.c_uint()
bytread = ctypes.c_ulong(0)
for i in range(11):
    num = int('0x%08X'%(0x00400000+i),16)

    try:
        if readprocess(process,hex(num),ctypes.byref(rdbuf),
            ctypes.sizeof(rdbuf),ctypes.byref(bytread)):
            print hex(num),rdbuf.value

    except:None

print '----------------done---------------'
结果输出为:

calc.exe pid =  4552
0x400000 4293587451
0x400001 4293587451
0x400002 4293587451
0x400003 4293587451
0x400004 4293587451
0x400005 4293587451
0x400006 4293587451
0x400007 4293587451
0x400008 4293587451
0x400009 4293587451
0x40000a 4293587451
----------------done---------------
[Finished in 0.2s]
但我希望它看起来像这样

00400000   AE               SCAS BYTE PTR ES:[EDI]
00400001   0001             ADD BYTE PTR DS:[ECX],AL
00400003   0000             ADD BYTE PTR DS:[EAX],AL
00400005   0000             ADD BYTE PTR DS:[EAX],AL
00400007   01EE             ADD ESI,EBP
00400009   FFEE             JMP FAR ESI                              ; Illegal use of register
0040000B   FF01             INC DWORD PTR DS:[ECX]
就像调试器一样。 我希望你们能理解我的意图。 读取processmemory时,is'rdbuf'获取所有信息
我想要什么?它到底从进程中得到了什么?

当使用
ReadProcessMemory
时,您正在读取特定内存地址的一些值。根据你所说的,你想要的是反汇编二进制代码。我会使用一个简单但功能强大的用于x86和x64的反汇编程序库。查看一个简单的示例:

>>>Decode(0x400000, 'b800000000'.decode('hex'), Decode32Bits)
[(4194304L, 5L, 'MOV EAX, 0x0', 'b800000000')]
请注意,无需打开进程,只需使用标准文件输入读取二进制文件内容即可


希望有帮助

您的代码中存在严重错误。您正在将
(const char*)“0xde2d6c”
传递到
ReadProcessMemory
此处:

    if readprocess(process,hex(num),ctypes.byref(rdbuf),
        ctypes.sizeof(rdbuf),ctypes.byref(bytread)):
hex
将整数转换成十六进制字符串;因此,您最终从
calc.exe
进程中读取字节的位置与Python进程中存储
“0xde2d6c”
字符串的位置相同,由于CPython内存分配的工作方式,Python进程中的地址始终相同

您只需要传入地址,即,
ctypes.cvoid\u p(num)

您的代码可以更清晰地写成:

base = 0x00400000
for addr in range(base, base + 11):
    try:
       if readprocess(process, ctypes.cvoid_p(addr), ctypes.byref(rdbuf),
                      ctypes.sizeof(rdbuf),ctypes.byref(bytread)):

您的代码目前输出了什么?输出是-----------------calc.exe pid=5656 f1e49fff1e4d9fff1e49fff1e4d9fff1e49fff1e4d9fff1e49fff1e4d9fff1e49fff1e4d9fff1e4d9ff--------------------再次打印相同的地址..哦,我感觉向前迈进了一步。我有一个问题要你回答。对未运行的进程进行解扰时。这不意味着我会得到一个文件内存而不是一个虚拟内存吗?这和调试器的PE View intead不一样吗?@KyungHoonBaek我不这么认为,因为你会像调试器一样读取二进制文件来获取ASM代码。非常感谢。我很感激(v)
bytread
是错误的类型和尺寸。它应该是
bytread=ctypes.c\u size\u t()
。碰巧,您可以安全地使用
c_ulong
,因为所有简单类型在内部都使用16字节的缓冲区,因此不存在写入未分配地址的风险。另外,不声明
argtypes
ctypes.sizeof(rdbuf)的值被限制在C
int
的范围内,而不是支持的
size\t
范围内。如果您决定正确声明
ReadProcessMemory.argtypes
,并定义一个
ReadProcessMemory.errcheck
函数,该函数实际上会在出错时引发异常(如ctypes文档中所述),那么请不要使用
windell
。使用
kernel32=ctypes.windell('kernel32',Use\u last\u error=True)
并通过
ctypes.get\u last\u error()
获取失败调用的最后一个错误。