📄 find.asm
字号:
_FindDlgProc proto:DWORD ,:DWORD ,:DWORD ,:DWORD
AddFindResult proto:DWORD ,:DWORD
_FindDec proto:DWORD ,:DWORD
_DoFind proto:DWORD ,:DWORD
_cmpstr proto:DWORD ,:DWORD ,:DWORD
_InitFindData proto:DWORD ,:DWORD ,:DWORD ,:DWORD
_AddFindType proto:DWORD ,:DWORD
;=============================================================
;--------------------------------------------------
.code
AddFindResult proc @hDlg,num
local @szBuf[255]:BYTE
invoke wsprintf,addr @szBuf,addr szFmHexD,num
invoke SendDlgItemMessage,@hDlg,IDC_LIST_FINDALLRESULT,LB_FINDSTRINGEXACT,0,addr @szBuf
.if eax==-1
invoke SendDlgItemMessage,@hDlg,IDC_LIST_FINDALLRESULT,LB_ADDSTRING ,0,addr @szBuf
invoke SendDlgItemMessage,@hDlg,IDC_LIST_FINDALLRESULT,LB_SETITEMDATA ,eax,num
.endif
ret
AddFindResult endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 查找 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
_FindDlgProc proc @hDlg,uMsg,wParam,lParam
local @szBuf[255]:BYTE,@hFileEnd
mov eax,uMsg
.if eax==WM_INITDIALOG
invoke ShowWindow,@hDlg,SW_SHOW
invoke _AddFindType,@hDlg,1005
.elseif eax==WM_COMMAND
pushad
mov eax,wParam
.if ax==IDC_CLEARALL
__senddlgmessage IDC_LIST_FINDALLRESULT,LB_RESETCONTENT
.elseif ax==IDC_FINDNEXT || ax==IDC_FINDPRE || ax==IDC_FINDALL
push eax
__senddlgmessage 1005,CB_GETCURSEL
pop ebx
.if eax>=0
inc eax
shl eax,16
or ebx,eax
;ebx的低位保存的是查找方向(下一个,上一个,全部)
;高位保存的是查找类型(字符,整数,十六进制)
invoke _DoFind,@hDlg,ebx
.endif
.elseif ax==IDC_LIST_FINDALLRESULT
shr eax,16
.if eax==LBN_SELCHANGE
__senddlgmessage IDC_LIST_FINDALLRESULT,LB_GETCURSEL
__senddlgmessage IDC_LIST_FINDALLRESULT,LB_GETITEMDATA ,eax
invoke _SetPos, eax
__senddlgmessage 1005,CB_GETITEMDATA ,0
add eax,dwBlockStart
dec eax
mov dwBlockEnd,eax
call _ReDraw
.endif
.endif
popad
.elseif eax==WM_CLOSE
invoke ShowWindow,@hDlg,SW_HIDE
.else
xor eax,eax
ret
.endif
mov eax,TRUE
ret
_FindDlgProc endp
;---------------------------------------------------
__add macro
mov eax,esi
sub eax,lpMemFile
push eax
invoke AddFindResult,@hDlg,eax
call _SetPos
endm
;-------------------------------------------
__find macro
push nLength
lea eax,lpBuf
push eax
push esi
call lpfnCmp
endm
;--------------------------------------------
__contiunesearch macro
inc nSearch
.if !(nSearch & 4096*2-1)
invoke wsprintf,addr @szBuf,ctext("已经搜索了%u个地址",13,"还要继续吗?"),nSearch
invoke MessageBox,@hDlg,addr @szBuf,addr szAppName,20h+MB_OKCANCEL
.break .if eax==IDCANCEL
.endif
endm
;-----------------------------------------------------------
;查找
;wParam:要查找的类型(下拉框中的选择)
_DoFind proc @hDlg,wParam
local @hFileEnd,@szBuf[MAX_PATH ]:BYTE,lpBuf[MAX_PATH /2]:BYTE
local nLength;要搜索的数据的长度,
local nSearch;已经搜索的数量,
local lpfnCmp
pushad
invoke RtlZeroMemory,addr @szBuf,MAX_PATH
mov ebx,wParam
shr ebx,16
invoke _InitFindData,@hDlg,1000,ebx,addr lpBuf
.if eax==0
popad
ret
.endif
mov eax,DWORD ptr lpBuf
mov nLength,edx
mov lpfnCmp,ebx
__senddlgmessage 1005,CB_SETITEMDATA ,0,nLength
mov esi,lpMemFile
mov eax,lpMemFileEnd
sub eax,nLength;防止越界
inc eax
mov @hFileEnd,eax
mov nSearch,0
mov edx,wParam
.if dx==IDC_FINDNEXT ;查找下一个
add esi,dwBlockEnd
inc esi
.while esi<=@hFileEnd
__find
.if eax
__add
.break
.endif
inc esi
__contiunesearch
.endw
.elseif dx==IDC_FINDPRE ;查找上一个
add esi,dwBlockEnd
dec esi
.while esi>=lpMemFile
__find
.if eax
__add
.break
.endif
dec esi
__contiunesearch
.endw
.elseif dx==IDC_FINDALL;查找全部
.while esi<=@hFileEnd
__find
.if eax
mov eax,esi
sub eax,lpMemFile
invoke AddFindResult,@hDlg,eax
.endif
inc esi
__contiunesearch
.endw
.endif
invoke _addItemIfNotExist,@hDlg,1000
popad
ret
_DoFind endp
;----------------------------------------------------
;初始化查找数据
;@hDlg,nId,提供输入查找数据的Edit(或combo)
;wParam查找类型(要以1为基数,即取list,combo的当前选择项时要+1)
;lpBuf将要查找的数据转换后写入的缓冲区
;返回值=============
;如果查找的是字符串,但没有输入查找数据,则返回false
;如果查找的是整数,但没有输入数据,返回true,并置要查找的数值是0
;edx返回要查找的数据的长度
;ebx返回比较函数的地址
_InitFindData proc uses esi @hDlg,nId,wParam,lpBuf
local @szBuf[MAX_PATH]:BYTE
local nLength,lpfnCmp
.if wParam<=2;字符串
.if wParam==1
mov lpfnCmp,offset _cmpstr
.else;if wParam==2
mov lpfnCmp,offset _cmpstri
.endif
invoke GetDlgItemText,@hDlg,nId, lpBuf,MAX_PATH/2
.if eax==0
ret
.endif
mov nLength,eax
.elseif wParam==3;查找的是十六进制
invoke GetDlgItemText,@hDlg,nId,addr @szBuf,MAX_PATH
.if eax==0
ret
.endif
lea esi,@szBuf
push esi
mov nLength,1
.while BYTE ptr [esi]
.if BYTE ptr [esi]==' '
mov BYTE ptr [esi],0
inc nLength
.endif
inc esi
.endw
pop esi
mov edi,lpBuf
.while BYTE ptr [esi]
invoke H2DW,esi
stosb
invoke lstrlen,esi
add esi,eax
inc esi
.endw
mov lpfnCmp,offset _cmpstr
.else;if wParam>3;十进制
.if wParam==4;byte
mov nLength,1
.elseif wParam==5;word
mov nLength,2
.else;dword
mov nLength,4
.endif
invoke GetDlgItemInt,@hDlg,nId,FALSE ,FALSE
mov ebx,lpBuf
mov [ebx],eax
mov lpfnCmp,offset _cmpstr
.endif
mov eax,TRUE
mov edx,nLength
mov ebx,lpfnCmp
ret
_InitFindData endp
;------------------------------------------------------
;比较字符串(区分大小写),用在搜索字符串,十六进制数据列,整数
;相等返回true,否则返回false
_cmpstr proc uses esi edi ecx lpSrc,lpDest,nLen
xor eax,eax
mov esi,lpSrc
mov edi,lpDest
mov ecx,nLen
repz cmpsb
.if zero?
inc eax;mov eax,true
.endif
ret
_cmpstr endp
;------------------------------------------------------------
;比较字符串(不分大小写),用在搜索不分大小的字符串
;相等返回true,否则返回false
_cmpstri proc uses esi edi ebx ecx lpSrc,lpDest,nLen
xor eax,eax
mov esi,lpSrc
mov edi,lpDest
mov ecx,nLen
_cmpnext_:
mov ah,[esi]
mov al,[edi]
inc esi
inc edi
mov bh,ah
sub bh,al
.if zero?
loop _cmpnext_
.elseif bh=='a'-'A' || bh=='A'-'a'
.if ((ah>='a' && ah<='z') || (ah>='A' && ah<='Z')) && \
((al>='a' && al<='z') || (al>='A' && al<='Z'))
loop _cmpnext_
.endif
.endif
xor eax,eax
.if ecx==0
inc eax;mov eax,true
.endif
ret
_cmpstri endp
;----------------------------------------------------
;添加查找类型
_AddFindType proc uses esi @hDlg,nID
.data
szFindType db '字符串(区分大小写)',0
db "字符串(不分大小写)",0
db "十六进制",0
db "十进制(BYTE)",0
db "十进制(WORD)",0
db '十进制(DWORD)',0
db 0
.code
lea esi,szFindType
.while BYTE ptr [esi]
__senddlgmessage nID,CB_ADDSTRING ,0,esi
invoke lstrlen,esi
inc eax
add esi,eax
.endw
__senddlgmessage nID,CB_SETCURSEL ,1
ret
_AddFindType endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -