很想成为计算机高手,可不知道路在何方,我写的这个代码感觉很吃力,也许因为职业不是程序员吧,希望能交些朋友,一起进步,
.const
IDC_LSV3 equ 4001
IDC_BTN5 equ 4008
IDC_BTN6 equ 4009
IDC_EDT1 equ 4010
IDC_CBO1 equ 2011
IDC_STC3 equ 4003
ADD_DATA1 equ 008373cch ;00883c84h ;其他版本要改这个地址值
;ADD_DATA2 equ 008373d0h ;00883c88h ;这个不用
ADD_DATA3_START equ 00010000h ;搜索范围开始地址,可根据需要改动
ADD_DATA3_END equ 7f600000h ;搜索范围结束地址,可根据需要改动
MEMSIZE equ 10000h ;每次读取数据块的大小,不宜太小
.data
szAddress db "地址",0
szValue db "值",0
DATA1 dd 0
.data?
hListView3 dd ?
g_hProcess dd ?
g_arList dd 1024 dup(?)
g_nListCnt dd ?
ProcessId dd ?
h_Mem dd ?
.code
ADDRVALUE struct
_addr dd ?
_value dd ?
ADDRVALUE ends
_GetProcessHandle proc
ret
_GetProcessHandle endp
_GetDataAddr proc uses esi edi hProcess:DWORD,num:DWORD,hmem:DWORD
LOCAL N,ListMemSize,pListMem,ReadSize
LOCAL mbi:MEMORY_BASIC_INFORMATION
invoke EmptyWorkingSet,hProcess ;减少游戏进程提交内存数,希望能减少搜索量,加快搜索速度
invoke SetProcessWorkingSetSize,hProcess,-1,-1 ;不知是否有效?!愿听高手指导
invoke GlobalLock,hmem ;锁定保存搜索结果的内存
mov pListMem,eax
invoke GlobalSize,hmem;保存搜索结果的内存大小
mov ListMemSize,eax
push DATA1
pop N
mov edi,N ;保存金钱数,以便后面比较搜索,原理见前文
invoke GlobalAlloc,GMEM_FIXED,MEMSIZE ;分配内存,为读取数据做准备
mov esi,eax ;保存内存地址
mov ecx,ADD_DATA3_START ;设置要搜索的内存地址范围开始处
.repeat ;循环搜索游戏内存
@@: invoke VirtualQueryEx,hProcess,ecx,addr mbi,sizeof MEMORY_BASIC_INFORMATION ;返回页面虚拟信息
.if mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE ;已提交且为可读写的区域,加速搜索
mov ReadSize,MEMSIZE ;每次可读取的数据大小
.repeat ;循环读取该内存区段中的数据
.if mbi.RegionSize<MEMSIZE ;如果剩下的数据块小于MEMSIZE
mov eax,mbi.RegionSize
mov ReadSize,eax ;读剩下的数据大小
.endif
invoke ReadProcessMemory,hProcess,mbi.BaseAddress,esi,ReadSize,addr N ;读游戏数据
xor ecx,ecx ;ecx为相对于区段首的偏移地址
.repeat ;在读取的数据块中搜索金钱数的地址
.if edi==[esi+ecx] ;数值相等,找到了?invoke RtlZeroMemory,addr @debugstr,sizeof @debugstr
mov eax,num ;地址num中记录了搜索结果的个数
inc dword ptr[eax] ;搜索的结果个数加一
mov eax,dword ptr[eax]
shl eax,2h ;保存结果所需的内存大小
.if eax>ListMemSize ;如果搜索到的结果较多,内存用完,要重新分配内存
push eax
push ecx
add eax,1000h ;追加4K内存
invoke GlobalReAlloc,hmem,eax,GMEM_MOVEABLE ;重新分配内存,原来的数据被复制过来
invoke GlobalLock,eax
mov pListMem,eax ;保存搜索结果的内存首地址
invoke GlobalSize,hmem
mov ListMemSize,eax ;保存搜索结果的内存大小
pop ecx
pop eax
.endif
add eax,pListMem ;相当于pListMem[num]
mov edx,mbi.BaseAddress
add edx,ecx ;首地址+偏移地址=实际地址
mov [eax-4h],edx ;搜索的结果保存起来,pListMem[num-1]=实际地址
.endif
add ecx,4h ;金钱数为DWORD型数值,考虑到内存对齐,这里是不用担心漏掉的
.until ecx>=N ;读取的数据块比较完了吗?
mov eax,ReadSize ;准备再读一次
add mbi.BaseAddress,eax ;下次从这里开始读
sub mbi.RegionSize,eax ;下次要读的大小
.until mbi.RegionSize<=0h ;下次要读的大小为0了吗?为0则本区段读完,去下一区段
.endif
mov ecx,mbi.BaseAddress
add ecx,mbi.RegionSize ;下一区段首地址
.until ecx>=ADD_DATA3_END ;下一区段在搜索范围之外了吗?是则完成第一遍搜索
invoke GlobalFree,esi
ret
_GetDataAddr endp
_FindAddrInList proc uses edi esi hProcess:DWORD,num:DWORD,hmem:DWORD
LOCAL Data,N
LOCAL DD1,DD2
push DATA1
pop DD1
invoke GlobalLock,hmem
mov edi,eax ;前次搜索结果保存的内存首地址
xor esi,esi ;指针,指向第一个结果
mov N,esi ;本次搜索到的个数初始化为0
.repeat ;逐个比较
mov edx,[edi+esi*4h] ;相当于edx=hmem[esi]
; invoke ReadProcessMemory,hProcess,edx,addr DD2,sizeof DD2,NULL ;读取数值
; int 3
mov eax,[edx]
mov DD2,eax
mov eax,DD1
.if eax==DD2 ;等于金钱数吗?等则记录下来
push [edi+esi*4h]
mov eax,N
pop [edi+eax*4h] ;相当于hmem[N]=hmem[esi],即把搜索到的结果向hmem内存前面移
inc N ;搜索到的个数加一
.endif
mov eax,num
inc esi ;指针指向下一个结果
.until esi>=[eax] ;每个都比较过了吗?是则完成这次搜索
mov edx,N ;这次搜索到的结果个数
mov [eax],edx ;修改原来的个数
shl edx,2h ;个数×4=内存大小
invoke GlobalReAlloc,hmem,edx,GMEM_MOVEABLE ;释放多余的内存
ret
_FindAddrInList endp
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!