You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用ReadProcessMemory()后,如何读取缓冲区内容检测恶意字符串?

内存扫描工具中提取缓冲区内容并进行恶意特征比对的实现方案

问题背景

使用ctypes开发内存扫描工具时,已通过VirtualAlloc()创建缓冲区并调用ReadProcessMemory()将目标进程内存写入该缓冲区,但不清楚如何提取缓冲区中的内容,完成恶意特征字符串与特征库的比对。核心代码片段如下:

while VQEResult != 0:
    VQEResult = VirtualQueryEx(         # 调用VirtualQueryEx获取内存页信息
            process,            # 目标进程句柄
            Adress,             # 要查询的内存地址
            byref(mbi),         # 存储MEMORY_BASIC_INFORMATION的指针
            sizeof(mbi),        # MEMORY_BASIC_INFORMATION的大小
            )

    print(mbi.BaseAddress,mbi.RegionSize,Adress)
    
    # 注意:原条件逻辑存在问题,应修正为逻辑与判断
    if mbi.State == MEM_COMMIT and mbi.RegionSize > 41000:    # 仅处理已提交且足够大的内存区域
            
            ContentsBuffer = VirtualAlloc (        # 分配与内存页大小一致的缓冲区
                            None,           # 不指定特定地址
                            mbi.RegionSize, # 缓冲区大小等于目标内存页大小
                            0x1000,         # MEM_COMMIT
                            0x04,           # PAGE_READWRITE   
                            )

            if not ReadProcessMemory (
                    process,                    # 目标进程句柄
                    Adress,                     # 目标内存地址
                    ContentsBuffer,             # 输出缓冲区指针
                    mbi.RegionSize,             # 要读取的字节数
                    byref(BytesRead),           # 存储实际读取字节数的指针
                    ):
               continue
               # print("Erro:",GetLastError)
            
    if VQEResult:
            Adress += mbi.RegionSize

实现步骤与代码修改

1. 提取缓冲区内容

VirtualAlloc()返回的是c_void_p类型的内存指针,可通过以下方式读取指针指向的二进制数据:

  • 使用ctypes.string_at():直接从指针地址读取指定长度的字节数据
  • 改用ctypes.create_buffer():更便捷的缓冲区创建方式,可直接访问缓冲区内容

推荐使用create_buffer()替代VirtualAlloc(),无需手动管理内存分配,代码更简洁:

# 替换原VirtualAlloc的代码
ContentsBuffer = create_buffer(mbi.RegionSize)  # 创建指定大小的可访问缓冲区

读取缓冲区内容的两种方式:

# 方式1:用string_at读取VirtualAlloc返回的指针
buffer_data = string_at(ContentsBuffer, BytesRead.value)

# 方式2:直接访问create_buffer创建的缓冲区的raw属性
buffer_data = ContentsBuffer.raw[:BytesRead.value]

2. 恶意特征字符串比对

根据恶意特征的编码类型(ASCII、UTF-8或UTF-16LE),将缓冲区字节数据与特征库中的字符串进行匹配:

ASCII/UTF-8特征比对示例

# 假设恶意特征库是一个字符串列表
malicious_signatures = ["malicious_str1", "malicious_str2", "evil_payload"]

# 提取缓冲区有效字节数据
buffer_bytes = buffer_data

# 遍历特征库检查匹配
for signature in malicious_signatures:
    sig_bytes = signature.encode('utf-8')
    if sig_bytes in buffer_bytes:
        print(f"检测到恶意特征: {signature},内存地址: {Adress}")

宽字符(UTF-16LE)特征比对示例

如果目标进程使用宽字符存储字符串,需将特征转换为UTF-16LE编码:

for signature in malicious_signatures:
    sig_bytes = signature.encode('utf-16le')
    if sig_bytes in buffer_bytes:
        print(f"检测到宽字符恶意特征: {signature},内存地址: {Adress}")

3. 优化内存管理

使用create_buffer()时,Python会自动管理内存释放;若使用VirtualAlloc(),需在使用完缓冲区后调用VirtualFree()释放内存,避免内存泄漏:

VirtualFree(ContentsBuffer, 0, 0x8000)  # 0x8000 = MEM_RELEASE

完整修改后的核心代码片段

while VQEResult != 0:
    VQEResult = VirtualQueryEx(
            process,
            Adress,
            byref(mbi),
            sizeof(mbi),
            )

    print(mbi.BaseAddress, mbi.RegionSize, Adress)
    
    # 修正条件判断逻辑
    if mbi.State == MEM_COMMIT and mbi.RegionSize > 41000:            
            # 使用create_buffer创建缓冲区
            ContentsBuffer = create_buffer(mbi.RegionSize)

            if not ReadProcessMemory(
                    process,
                    Adress,
                    ContentsBuffer,
                    mbi.RegionSize,
                    byref(BytesRead),
                    ):
               continue
            
            # 提取缓冲区内容
            buffer_data = ContentsBuffer.raw[:BytesRead.value]
            
            # 恶意特征比对
            malicious_signatures = ["malicious_str1", "malicious_str2"]
            for sig in malicious_signatures:
                if sig.encode('utf-8') in buffer_data:
                    print(f"发现恶意特征: {sig},位于内存地址: {Adress}")
            
            # 若使用VirtualAlloc,需添加释放代码
            # VirtualFree(ContentsBuffer, 0, 0x8000)
            
    if VQEResult:
            Adress += mbi.RegionSize

内容的提问来源于stack exchange,提问作者Leonardo Poloni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 07:15:38