📄 addcrc32tofile.asm
字号:
;************************************************************
;程序名称:演示CRC32原理
;作者:罗聪
;日期:2002-9-8
;出处:http://laoluoc.yeah.net(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:转载自“老罗的缤纷天地”(http://laoluoc.yeah.net)
;************************************************************
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\comdlg32.inc
include CRC32Dll.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\comdlg32.lib
includelib CRC32Dll.lib
WndProc proto :DWORD, :DWORD, :DWORD, :DWORD
.const
IDC_BUTTON_OPEN equ 3000
MAXSIZE equ 260
.data
szDlgName db "lc_dialog", 0
szCaption db "CRC demo by LC", 0
szTemplate db "文件 ""%s"" 的 CRC-32 值是:%X", 13, 10, "您确定要在文件的Win32Version处写入这个 CRC-32 值吗?", 0
szErrOpen db "打开文件出错!", 0
ofn OPENFILENAME <>
szFileName db MAXSIZE dup(0)
szFilterString db "PE可执行文件", 0, "*.exe", 0, 0
szMyTitle db "请打开一个PE可执行文件,进行CRC-32写入操作...", 0
.data?
szCRC32 dd 4 dup(?) ;储存文件的CRC-32值
szText db 300 dup(?)
.code
main:
invoke GetModuleHandle, NULL
invoke DialogBoxParam, eax, offset szDlgName, 0, WndProc, 0
invoke ExitProcess, eax
WndProc proc uses ebx ecx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hFile: HANDLE
LOCAL dwFileSize: DWORD
LOCAL dwNumberOfBytesReadWritten: DWORD
LOCAL dwPE_Header_Addr: DWORD
LOCAL hMemory: HANDLE
LOCAL pMemory: DWORD
.if uMsg == WM_CLOSE
invoke EndDialog, hWnd, 0
.elseif uMsg == WM_COMMAND
mov eax, wParam
mov edx, eax
shr edx, 16
movzx eax, ax
.if edx == BN_CLICKED
.if eax == IDCANCEL
invoke EndDialog, hWnd, NULL
.elseif eax == IDC_BUTTON_OPEN || eax == IDOK
;“打开文件”对话框:
mov ofn.lStructSize, sizeof ofn
push hWnd
pop ofn.hwndOwner
push hWnd
pop ofn.hInstance
mov ofn.lpstrFilter, offset szFilterString
mov ofn.lpstrFile, offset szFileName
mov ofn.nMaxFile, MAXSIZE
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER
mov ofn.lpstrTitle, offset szMyTitle
invoke GetOpenFileName, addr ofn
;******************************************
;关键代码开始:(当当当当……)
;******************************************
;打开文件:
invoke CreateFile, addr szFileName, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
mov hFile, eax
.if hFile == INVALID_HANDLE_VALUE
invoke MessageBox, hWnd, addr szErrOpen, addr szCaption, MB_OK
.else
;获得文件长度:
invoke GetFileSize, hFile, NULL
mov dwFileSize, eax
;分配内存:
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, dwFileSize
mov hMemory, eax
;锁定内存:
invoke GlobalLock, hMemory
mov pMemory, eax
;读取文件内容:
invoke ReadFile, hFile, pMemory, dwFileSize, addr dwNumberOfBytesReadWritten, NULL
;初始化crc32table:
invoke init_crc32table
;下面赋值给寄存器ebx和ecx,以便进行crc32转换:
;EBX是待转换的字符串的首地址:
mov ebx, pMemory
;ECX是文件的长度:
mov ecx, dwFileSize
;进行crc32转换:
invoke arraycrc32
mov szCRC32, eax
;格式化输出:
invoke wsprintf, addr szText, addr szTemplate, addr szFileName, szCRC32
;好啦,让我们写入文件:
invoke MessageBox, hWnd, addr szText, addr szCaption, MB_YESNO or MB_ICONQUESTION
.if eax == IDYES
;读3ch处的PE文件头指针:
invoke SetFilePointer, hFile, 3ch, NULL, FILE_BEGIN
invoke ReadFile, hFile, addr dwPE_Header_Addr, 4, addr dwNumberOfBytesReadWritten, NULL
;定位到PE Optional_Section的Win32Version处:
mov eax, [dwPE_Header_Addr]
add eax, 4ch
invoke SetFilePointer, hFile, eax, NULL, FILE_BEGIN
;写入CRC-32:
invoke WriteFile, hFile, addr szCRC32, 4, addr dwNumberOfBytesReadWritten, NULL
;关闭文件:
invoke CloseHandle, hFile
.endif
;释放内存:
invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory
;关闭文件:
invoke CloseHandle, hFile
.endif
.endif
.endif
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
WndProc endp
end main
;******************* over *******************
;by LC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -