因为昨天研究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