上次我对扫雷数据进行读写是利用ReadProcessMemory和WriteProcessMemory函数
这次我们采用另外一种方式——DLL注入
这次我们找到更多的数据地址:
数据内容 | 地址 |
---|---|
雷数 | 0x01005194 |
时间 | 0x0100579C |
窗口X坐标 | 0x010056B0 |
窗口Y坐标 | 0x010056B4 |
难度值 | 0x010056A0 |
雷区高度 | 0x010056A8 |
雷区宽度 | 0x010056AC |
其中,难度值(0-初级,1-中级,2-高级,3-自定义),时间最大值为999
首先我们要做一个用于注入到扫雷进程的DLL:
在DLL注入到扫雷后立刻创建一个新的线程:
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
_beginthread(Thread, 0, NULL);
break;
}
return TRUE;
}
为了能够读取扫雷的数据,要让注入的DLL主动向外部发送数据,于是建立新线程后注册一个socket
每隔500ms向Server发送一次数据,每个数据之间使用“#”来分隔,并在末尾加上异或校验码:
initSocket("127.0.0.1", 12368);
for (int i = 0; i < 100; i++)
{
char sendData[1024];
int checkCode = *Number^ *Time^ *X^ *Y^ *Difficult^ *Hight^ *Weight;
sprintf(sendData, "%d#%d#%d#%d#%d#%d#%d#%d", *Number, *Time, *X, *Y, *Difficult, *Hight, *Weight, checkCode);
sendto(sockClient, sendData, strlen(sendData) + 0, 0, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));
Sleep(500);
}
Server端用Python编写:
from socket import *
import platform
import os
def printInf(recvList):
# 清屏
if platform.system() == "Windows":
os.system("cls")
else:
os.system("clear")
print("雷数:"+recvList[0])
print("时间:"+recvList[1])
print("窗口X坐标:"+recvList[2])
print("窗口Y坐标:"+recvList[3])
print("难度值:"+recvList[4])
print("雷区高度:"+recvList[5])
print("雷区宽度:"+recvList[6])
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("127.0.0.1", 12368))
while True:
recv,addr = s.recvfrom(1024)
# print(addr,end="")
recvStr = recv.decode("utf-8")
# print(":"+recvStr)
recvList = recvStr.split("#")
checkCode = int(recvList[0])
for i in recvList[1:-1]:
checkCode ^= int(i)
# print("本地校验码:"+str(checkCode)+"远程校验码:"+recvList[-1])
if checkCode == int(recvList[-1]):
# print("校验成功!")
printInf(recvList)
s.close()
效果图:
{% asset_img 扫雷二.png %}