下面汇编函数里的两条语句会不会内存越界
对下面的
invoke RtlZeroMemory, addr @bufTemp1, 10
invoke RtlZeroMemory, addr @bufTemp2, 20
两行代码有疑问,里面的10和20是怎么来的,回不内存越界?
_openFile proc
local @stOF: OPENFILENAME
local @hFile, @hMapFile
local @bufTemp1; 十六进制字节码
local @bufTemp2; 第一列
local @dwCount; 计数,逢16则重新计
local @dwCount1; 地址顺号
local @dwBlanks; 最后一行空格数
invoke RtlZeroMemory, addr @stOF, sizeof @stOF
mov @stOF.lStructSize, sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter, offset szExePe
mov @stOF.lpstrFile, offset szFileName
mov @stOF.nMaxFile, MAX_PATH
mov @stOF.Flags, OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
invoke GetOpenFileName, addr @stOF; 让用户选择打开的文件
.if !eax
jmp @F
.endif
invoke CreateFile, addr szFileName, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL,\
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
.if eax != INVALID_HANDLE_VALUE
mov @hFile, eax
invoke GetFileSize, eax, NULL ;获取文件大小
mov totalSize, eax
.if eax
invoke CreateFileMapping, @hFile, NULL, PAGE_READONLY, 0,0, NULL
.if eax
mov @hMapFile, eax
invoke MapViewOfFile, eax, FILE_MAP_READ, 0,0,0
.if eax
mov lpMemory,eax ;获得文件在内存的映像起始位置
assume fs:nothing
push ebp
push offset _ErrFormat
push offset _Handler
push fs:[0]
mov fs:[0], esp
; 开始处理文件
; 缓冲去初始化
invoke RtlZeroMemory, addr @bufTemp1, 10
invoke RtlZeroMemory, addr @bufTemp2, 20
invoke RtlZeroMemory, addr lpServicesBuffer, 100
invoke RtlZeroMemory, addr bufDisplay, 50
mov @dwCount, 1
mov esi, lpMemory
mov edi, offset bufDisplay
;将第一列写入lpServicesBuffer
mov @dwCount1,0
invoke wsprintf, addr @bufTemp2, addr lpszFilterFmt4, @dwCount1
invoke lstrcat, addr lpServicesBuffer, addr @bufTemp2
;求最后一行的空格数(16-长度%16)*3
xor edx, edx
mov eax, totalSize
mov ecx, 16
div ecx
mov eax, 16
sub eax, edx
xor edx, edx
mov ecx, 3
mul ecx
mov @dwBlanks, eax
.while TRUE
.if totalSize == 0; 最后一行
;填充空格
.while TRUE
.break .if @dwBlanks == 0
invoke lstrcat, addr lpServicesBuffer, addr lpszBlank
dec @dwBlanks
.endw
;第二列和第三列中间的空格
invoke lstrcat, addr lpServicesBuffer, addr lpszManyBlanks
;第三列的内容
invoke lstrcat, addr lpServicesBuffer, addr bufDisplay
;回车换行符号
invoke lstrcat, addr lpServicesBuffer, addr lpszReturn
.break
.endif
; 将alf翻译成可以显示的ascii码字符,注意不要破坏al的值
mov al, byte ptr [esi]
.if al > 20h && al < 7eh
mov ah, al
.else ;如果不ASCII码值,则显示‘.’
mov ah, 2Eh
.endif
;写入第三列的值
mov byte ptr [edi], ah
;win2k不支持al字节级别,经常导致程序无故结束,
;因此用以下方法替代
;invoke wsprintf,addr @bufTemp1,addr lpszFilterFmt3,al
mov bl, al
xor edx, edx
xor eax, eax
mov al, bl
mov cx, 16
div cx; 结果放在al中,余数在dl中
;组合字节的十六进制字符串到@bfuTemp1中。类似与 "7F\0"
push edi
xor bx, bx
mov bl, al
movzx edi,bx
mov bl, byte ptr lpszHexArr[edi]
mov byte ptr @bufTemp1[0], bl
xor bx, bx
mov bl, dl
movzx edi, bx
mov bl, byte ptr lpszHexArr[edi]
mov byte ptr @bufTemp1[1], bl
mov bl, 20h
mov byte ptr @bufTemp1[2],bl
mov bl, 0
mov byte ptr @bufTemp1[3], bl
pop edi
;将第2列写入lpServicesBuffer
invoke lstrcat, addr lpServicesBuffer, addr @bufTemp1
.if @dwCount == 16; 已到16个字节
;第二列和第三列中间的空格
invoke lstrcat, addr lpServicesBuffer, addr lpszManyBlanks
;显示第三列字符
invoke lstrcat, addr lpServicesBuffer, addr bufDisplay
;回车换行
invoke lstrcat, addr lpServicesBuffer, addr lpszReturn
;写入内容
invoke _appendInfo, addr lpServicesBuffer
invoke RtlZeroMemory, addr lpServicesBuffer, 100
.break .if dwStop == 1
;显示下一行的地址
inc @dwCount1
invoke wsprintf, addr @bufTemp2, addr lpszFilterFmt4, @dwCount1
invoke lstrcat, addr lpServicesBuffer, addr @bufTemp2
dec @dwCount1
mov @dwCount, 0
invoke RtlZeroMemory, addr bufDisplay, 50
mov edi, offset bufDisplay
;为了能和后面的inc edi配合使edi正确定位到bufDisplay处
dec edi
.endif
dec totalSize
inc @dwCount
inc esi
inc edi
inc @dwCount1
.endw
;添加最后一行
invoke _appendInfo, addr lpServicesBuffer
;处理文件结束
jmp _ErrorExit
_ErrFormat:
invoke MessageBox, hWinMain, offset szErrFormat, NULL, MB_OK
_ErrorExit:
pop fs:[0]
add esp, 0ch
invoke UnmapViewOfFile, lpMemory
.endif
invoke CloseHandle, @hMapFile
.endif
invoke CloseHandle, @hFile
.endif
.endif
@@:
ret
_openFile endp