首页
论坛
专栏
课程

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

2015-2-3 05:39 5338

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

2015-2-3 05:39
5338
很想成为计算机高手,可不知道路在何方,我写的这个代码感觉很吃力,也许因为职业不是程序员吧,希望能交些朋友,一起进步,

.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


[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

上传的附件:
最新回复 (7)
pxhb 2 2015-2-3 07:40
2
0
不错,感谢分享,
雪衫 2015-2-3 08:48
3
0
不管怎么样.都要感谢楼主分享的..
破九 2015-2-3 10:49
4
0
熟能生巧嘛,虽是计算机相关专业的,但也写不出楼主这样的代码,楼主要有信心。
ebhb 2015-5-10 08:58
5
0
谢谢楼主分享。
dalerkd 1 2015-5-10 14:27
6
0
感谢分享学习,以后多多交流
menglv 2015-5-24 22:40
7
0
留个脚印
GeekCheng 2 2015-5-24 23:44
8
0
很不错啊,至少我到目前为止都还没用汇编实现过什么具体功能呢
游客
登录 | 注册 方可回帖
返回