欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]用masm32写的一个内存搜索dll,分享一下

[原创]用masm32写的一个内存搜索dll,分享一下

很想成为计算机高手,可不知道路在何方,我写的这个代码感觉很吃力,也许因为职业不是程序员吧,希望能交些朋友,一起进步,
.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

上传的附件 360截图20150203053450843.jpg
dlltab.rar

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功