内存修改器,有问题
这是用win32汇编写的一个内存修改器,是想用来修改游戏中的攻击,生命的数值的,无奈写好了之后,竟然搜索不到存放攻击力的内存地址(金山游侠能搜到,地址为 0x02BCFE3E,我的程序在0x008.....之后,直接跳到0x4.......,表明它在这段内存之间没有找到相应数值),非常郁闷于是又写了一个test程序,检测是不是有bug,发现确实可以修改,地址为 0x403003,很普通的地址,我就在想,是不是游戏中有些数据被保护了(或别的什么机制),需要特殊的方法才能找到并修改,各位高手请帮帮忙,给点提示,让我能完成这个修改器,其代码如下
.386
.Model Flat, StdCall
Option Casemap :None
Include windows.inc
Include user32.inc
Include kernel32.inc
Include gdi32.inc
include comdlg32.inc
includelib gdi32.lib
IncludeLib user32.lib
IncludeLib kernel32.lib
includelib comdlg32.lib
include macro.asm
DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
.const
ICO_MAIN equ 0x1000
DLG_MAIN equ 1
IDC_LISTBOX equ 101
IDC_LISTBOX2 equ 100
IDC_TEXT1 equ 103
IDC_TEXT2 equ 104
IDC_TEXT3 equ 105
IDC_FIND equ 106
IDC_LOAD equ 107
IDC_RESET equ 108
.data?
hInstance dd ?
hWinMain dd ?
hList dd ?
szFileName db MAX_PATH dup (?)
szCmdLine db MAX_PATH dup (?)
stStartUp STARTUPINFO <?>
stProcInfo PROCESS_INFORMATION <?>
buffer dd ?
Base dd ?
value dw ?
Xvalue dw ?
i dd ?
j dd ?
.data
szFileExt db '可执行文件(*.exe;*.com)',0,'*.exe',0,'批处理文件(*.bat)',0,'*.bat',0,0
szErrExec db '无法执行文件!',0
szErrWrite db '此地址不能写',0
szMemory db '地址:%08x 值:%d',0
szCaption db '内存修改',0
szTest db '共找着 %d 项',0
szTooBig db '你所搜索的数值有太多项,以下数据可能不满足您的需要',0
Number db 1
align 4
Find db 4096*16 dup (0)
count dd 0
.code
_ProcExec proc uses ebx esi edi _lParam
local @szBuffer[MAX_PATH * 2]:BYTE
;********************************************************************
; 设置按钮状态以及其它准备工作
;********************************************************************
invoke GetDlgItem,hWinMain,IDC_TEXT1
invoke EnableWindow,eax,TRUE
invoke GetDlgItem,hWinMain,IDC_TEXT2
invoke EnableWindow,eax,TRUE
invoke GetDlgItem,hWinMain,IDC_TEXT3
invoke EnableWindow,eax,TRUE
invoke GetDlgItem,hWinMain,IDC_FIND
invoke EnableWindow,eax,TRUE
invoke GetDlgItem,hWinMain,IDC_LOAD
invoke EnableWindow,eax,FALSE
invoke GetDlgItem,hWinMain,IDOK
invoke EnableWindow,eax,TRUE
invoke GetDlgItem,hWinMain,IDC_RESET
invoke EnableWindow,eax,TRUE
;********************************************************************
; 创建进程
;********************************************************************
invoke GetStartupInfo,addr stStartUp
invoke CreateProcess,NULL,addr szFileName,NULL,NULL,NULL,\
NORMAL_PRIORITY_CLASS,NULL,NULL,addr stStartUp,addr stProcInfo
.if eax
;********************************************************************
; 等待进程结束
;********************************************************************
invoke WaitForSingleObject,stProcInfo.hProcess,INFINITE
invoke CloseHandle,stProcInfo.hProcess
invoke CloseHandle,stProcInfo.hThread
.else
invoke MessageBox,hWinMain,addr szErrExec,NULL,MB_OK or MB_ICONWARNING
.endif
;********************************************************************
; 恢复按钮状态
;********************************************************************
invoke RtlZeroMemory,addr stProcInfo,sizeof stProcInfo
invoke GetDlgItem,hWinMain,IDC_TEXT1
invoke EnableWindow,eax,FALSE
invoke GetDlgItem,hWinMain,IDC_TEXT2
invoke EnableWindow,eax,FALSE
invoke GetDlgItem,hWinMain,IDC_TEXT3
invoke EnableWindow,eax,FALSE
invoke GetDlgItem,hWinMain,IDC_LOAD
invoke EnableWindow,eax,TRUE
invoke GetDlgItem,hWinMain,IDC_FIND
invoke EnableWindow,eax,FALSE
invoke GetDlgItem,hWinMain,IDOK
invoke EnableWindow,eax,FALSE
invoke GetDlgItem,hWinMain,IDC_RESET
invoke EnableWindow,eax,FALSE
ret
_ProcExec endp
_Find1 proc
local @Buf[5000]:BYTE
local @buffer[256]:BYTE
mov Base,00401000h ;第一次查找,遍历4MB~2GB内存
mov j,0
.while Base < 7fffffffh
invoke ReadProcessMemory,stProcInfo.hProcess,Base,addr @Buf,4096,NULL
.if eax
mov i,0
.while i < 4096
mov ebx,i
mov dx,value
.if WORD ptr @Buf[ebx] == dx
mov ecx,i
add ecx,Base
mov edi,j
mov DWORD ptr Find[edi*4],ecx ;把满足条件的值存入数组
inc j
inc count
.if j >= 4096*4
invoke MessageBox,NULL,addr szTooBig,addr szCaption,MB_OK ;搜索结果超过4096则不再搜索
jmp s
.endif
.endif
inc i
.endw
.endif
mov eax,Base
add eax,4096
mov Base,eax
.endw
s: invoke wsprintf,addr @buffer,addr szTest,count
invoke MessageBox,NULL,addr @buffer,addr szCaption,MB_OK
mov i,0
.while i < 4096*4
mov ebx,i
.if DWORD ptr Find[ebx*4] != 0
invoke wsprintf,addr @buffer,addr szMemory,DWORD ptr Find[ebx*4],value
invoke SendDlgItemMessage,hWinMain,IDC_LISTBOX,LB_ADDSTRING,0,addr @buffer ;打印至列表框
invoke SendMessage,hList,LB_SETITEMDATA,eax,DWORD ptr Find[ebx*4]
.endif
inc i
.endw
inc Number
ret
_Find1 endp
_FindN proc
local @val[4]:BYTE
local @buff[256]:BYTE
mov i,0
.while i < 4096*4 ;第二~N次查找,在Find数组中
mov ebx,i
invoke ReadProcessMemory,stProcInfo.hProcess,DWORD ptr Find[ebx*4],addr @val,2,NULL
.if eax
mov dx,value
mov ebx,i
.if WORD ptr @val != dx
mov DWORD ptr Find[ebx*4],0 ;不满足的地址清零
.endif
.endif
inc i
.endw
mov i,0
.while i < 4096*4
mov ebx,i
.if DWORD ptr Find[ebx*4] != 0
invoke wsprintf,addr @buff,addr szMemory,DWORD ptr Find[ebx*4],value
invoke SendDlgItemMessage,hWinMain,IDC_LISTBOX,LB_ADDSTRING,0,addr @buff
invoke SendMessage,hList,LB_SETITEMDATA,eax,DWORD ptr Find[ebx*4]
.endif
inc i
.endw
ret
_FindN endp
START:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,0,offset DlgProc,0
invoke ExitProcess,0
DlgProc proc hWnd,uMsg,wParam,lParam
local @dwThreadID
local @stOF:OPENFILENAME
local @Buf[4096]:BYTE
local @buffer[256]:BYTE
.if uMsg==WM_COMMAND
mov eax,wParam
.if ax==IDOK ;选择列表框的项目,修改为所要数值
invoke GetDlgItemInt,hWnd,IDC_TEXT2,NULL,TRUE
mov Xvalue,ax
invoke SendMessage,hList,LB_GETCURSEL,0,0
invoke SendMessage,hList,LB_GETITEMDATA,eax,0
mov ebx,eax
invoke WriteProcessMemory,stProcInfo.hProcess,ebx,addr Xvalue,2,NULL
.if eax
invoke wsprintf,addr @buffer,addr szMemory,ebx,Xvalue
invoke SendDlgItemMessage,hWinMain,IDC_LISTBOX2,LB_ADDSTRING,0,addr @buffer
.else ;如果地址不可写,则提示
invoke MessageBox,NULL,addr szErrWrite,addr szCaption,MB_OK
.endif
.elseif ax==IDC_FIND ;查找
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,LB_RESETCONTENT,0,0
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_RESETCONTENT,0,0
invoke GetDlgItemInt,hWnd,IDC_TEXT1,NULL,TRUE
mov value,ax
.if Number == 1
invoke _Find1
.else
invoke _FindN
.endif
.elseif ax==IDC_RESET ;重置搜索状态,重新搜索
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX,LB_RESETCONTENT,0,0
invoke SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_RESETCONTENT,0,0
mov Number,1
.elseif ax==IDC_LOAD ;载入一个进程
mov Number,1
invoke SendMessage,hList,LB_RESETCONTENT,0,0
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szFileExt
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
invoke GetOpenFileName,addr @stOF
.if eax
invoke SetDlgItemText,hWnd,IDC_TEXT3,addr szFileName
invoke CreateThread,NULL,0,addr _ProcExec,NULL,NULL,addr @dwThreadID
.endif
.endif
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,wParam
.elseif uMsg==WM_INITDIALOG
push hWnd
pop hWinMain
invoke GetDlgItem,hWnd,IDC_LISTBOX
mov hList,eax
invoke LoadIcon,hInstance,100
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,eax
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
END START