Python 获取指定模块基址

本文介绍了如何使用WinAPI在Python中获取指定模块的基址,通过创建进程快照、遍历模块并利用MODULEENTRY32结构体。在尝试过程中,遇到Python 32位和64位版本的兼容性问题,最终在Python 2环境下成功实现。文章分享了完整的代码示例,并呼吁了解相关API的大佬指导。
摘要由CSDN通过智能技术生成

在这里插入图片描述
因为昨天研究FPS游戏时候,发现有个动态地址每次重启电脑都会不同,然后因为有过用C和易语言编写指定模块名获取基址的经验,所以打算用Python来试试

在网上搜索了一点资料,发现有吾爱有一篇是使用Python32位,通过Ntdll库进行模块遍历。

将代码复制粘贴,因为我使用的是 Python64位的,改了改代码,但是发现失败了,搜不出来,因为代码涉及到PE头,目前还没碰到这块区域,代码作者也说他只是复制粘贴的,所以也不甚清楚为什么,就只能另寻出路了。

def _ReadMemeryInt(hGameHandle,_address,bufflength):
    addr = ctypes.c_ulong()
    ReadProcessInt = kernel32.ReadProcessMemory
    ReadProcessInt(int(hGameHandle), _address, ctypes.byref(addr), bufflength, None)
    return addr.value

def _ReadMemeryWchar(hGameHandle,_address,bufflength):
    addr = ctypes.c_wchar_p("0" * bufflength)
    ReadProcessInt = kernel32.ReadProcessMemory
    ReadProcessInt(int(hGameHandle), _address, addr, bufflength, None)
    return addr.value

def ReadVirtualMemory(hGameHandle,addr, n=8):
    # 这里定义一个函数来读取,传入三个参数,第一个是进程句柄,第二个是我们要读取的地址,我们可以默认为8,可以偷懒,第三个是要读取的长度
    addr = ctypes.c_ulonglong(addr)
    ret = ctypes.c_ulonglong()
    BufferLength = ctypes.c_ulonglong(n)
    ReadProcessInt = kernel32.ReadProcessMemory
    ReadProcessInt(int(hGameHandle), addr, ctypes.byref(ret), BufferLength, 0)
    return ret.value  # c_ulonglong的类型中,他的数值是放在他的属性value中的,所以返回的时候我们只需要获取value中存放的数值就好了

def ReadVirtualMemoryWchar(hGameHandle,addr, n):
    # 这里定义一个函数来读取,传入三个参数,第一个是进程句柄,第二个是我们要读取的地址,我们可以默认为8,可以偷懒,第三个是要读取的长度
    addr = ctypes.c_ulonglong(addr)
    ret = ctypes.c_wchar_p("0" * n)
    BufferLength = ctypes.c_ulonglong(n*2+1)
    ReadProcessInt = kernel32.ReadProcessMemory
    ReadProcessInt(int(hGameHandle), addr, ret, BufferLength, None)
    return ret.value  # c_ulonglong的类型中,他的数值是放在他的属性value中的,所以返回的时候我们只需要获取value中存放的数值就好了

def GetBaseAddr(hGameHandle, ModuleName):  
    NumberOfBytesRead = ctypes.c_ulong()
    Buffer = PROCESS_BASIC_INFORMATION()
    Size = ctypes.c_ulong(48)

    name_len = len(ModuleName)

    ntdll.NtQueryInformationProcess(int(hGameHandle), 0, ctypes.byref(Buffer), Size, ctypes.byref(NumberOfBytesRead))

    ret = ReadVirtualMemory(hGameHandle, Buffer.PebBaseAddress + 24, 8)
    print(ret)
    ret = ReadVirtualMemory(hGameHandle, ret + 24, 8)

    for i in range(1000):  # 这里用for循环其实是怕程序卡死,下面如果出了问题不能退出的话,循环结束一样可以退出
        modulehandle = ReadVirtualMemory(hGameHandle, ret + 40, 8)
        print(modulehandle)
        if modulehandle == 0:
            break
        nameaddr = ReadVirtualMemory(hGameHandle, ret + 96, 8)
        print(nameaddr)
        name = ReadVirtualMemoryWchar(hGameHandle, nameaddr, name_len)
        print(name)
        #3ED30000  1054015488
        #00CE0000
        if name == ModuleName:
            return modulehandle
        ret = ReadVirtualMemory(hGameHandle, ret + 8, 8)

    return 0

返回值是0,我也有尝试过修改 ret + xx后面的数字进行搜索,原作者说这个数是涉及PE头的知识,后面发现,无论怎么改都搜不出来,就放弃了。
在这里插入图片描述

使用WinAPI完成指定模块基址读写

1.先了解下要使用到的函数

MODULEENTRY32

MODULEENTRY32是一种编程数据结构。

结构

Describes an entry from a list of the modules belonging to the specified proce
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值