这两天把win32汇编拿起来学习一下,主要是为了以后研究逆向的时候方便一点。
之前我们编译多个文件一般比较喜欢使用include方法包含。这样确实很方便的。但是总觉得吧应该有更好用的办法。(主要对于初学者~_~)。罗运兵的书上面就是直接include的。其实我们之前学习的c语言,将源文件编译成obj文件,然后连接,当然可以适用于masm了。
下面上源代码:
这个是一个独立的小模块了;
GetersionInfo 方法的代码
.386
.model flat, stdcall
option casemap :none
include Version.inc
includelib Version.lib
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.const
szRoot db '\',0
szVarInfo db '\VarFileInfo\Translation',0
szStrInfoFmt db '\StringFileInfo\%08x\',0
szArrow db ' --> ',0
szReturn db 0dh,0ah,0
szFixFileInfo db '固定版本信息属性:',0dh,0ah
db 'FileVersion: %d.%d.%d.%d',0dh,0ah
db 'ProductVersion: %d.%d.%d.%d',0dh,0ah
db 'FileOS: %08x',0dh,0ah
db 'FileType: %08x',0dh,0ah,0dh,0ah
db '字符串版本属性:',0dh,0ah,0
;********************************************************************
szStr1 db 'Comments',0
szStr2 db 'CompanyName',0
szStr3 db 'FileDescription',0
szStr4 db 'FileVersion',0
szStr5 db 'InternalName',0
szStr6 db 'LegalCopyright',0
szStr7 db 'LegalTrademarks',0
szStr8 db 'OriginalFilename',0
szStr9 db 'PrivateBuild',0
szStr10 db 'ProductName',0
szStr11 db 'ProductVersion',0
szStr12 db 'SpecialBuild',0
;********************************************************************
lpStr1 dd szStr1
lpStr2 dd szStr2
lpStr3 dd szStr3
lpStr4 dd szStr4
lpStr5 dd szStr5
lpStr6 dd szStr6
lpStr7 dd szStr7
lpStr8 dd szStr8
lpStr9 dd szStr9
lpStr10 dd szStr10
lpStr11 dd szStr11
lpStr12 dd szStr12
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 获取文件版本信息
; 入口参数:文件名,返回信息缓冲区
; 返回参数:TRUE = 成功,FALSE = 失败
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetVersionInfo proc _lpFileName,_lpBuffer
local @dbVerInfo[4096]:byte
local @szStringInfo[128]:byte
local @szString[128]:byte
local @lpBuffer,@dwLen
local @dwVer1,@dwVer2,@dwVer3,@dwVer4
local @dwVer5,@dwVer6,@dwVer7,@dwVer8
pushad
invoke GetFileVersionInfoSize,_lpFileName,NULL
.if !eax
popad
xor eax,eax
ret
.endif
invoke GetFileVersionInfo,_lpFileName,NULL,sizeof @dbVerInfo,addr @dbVerInfo
;********************************************************************
; 获取固定属性
;********************************************************************
invoke VerQueryValue,addr @dbVerInfo,addr szRoot,addr @lpBuffer,addr @dwLen
mov esi,@lpBuffer
assume esi:ptr VS_FIXEDFILEINFO
;********************************************************************
; 计算版本号
;********************************************************************
mov eax,[esi].dwFileVersionMS
movzx ecx,ax
mov @dwVer2,ecx
shr eax,16
mov @dwVer1,eax
mov eax,[esi].dwFileVersionLS
movzx ecx,ax
mov @dwVer4,ecx
shr eax,16
mov @dwVer3,eax
mov eax,[esi].dwProductVersionMS
movzx ecx,ax
mov @dwVer6,ecx
shr eax,16
mov @dwVer5,eax
mov eax,[esi].dwProductVersionLS
movzx ecx,ax
mov @dwVer8,ecx
shr eax,16
mov @dwVer7,eax
invoke wsprintf,_lpBuffer,addr szFixFileInfo,\
@dwVer1,@dwVer2,@dwVer3,@dwVer4,\
@dwVer5,@dwVer6,@dwVer7,@dwVer8,\
[esi].dwFileOS,[esi].dwFileType
assume esi:nothing
;********************************************************************
; 获取语言集
;********************************************************************
invoke VerQueryValue,addr @dbVerInfo,addr szVarInfo,addr @lpBuffer,addr @dwLen
mov eax,@lpBuffer
mov eax,[eax]
ror eax,16
invoke wsprintf,addr @szStringInfo,addr szStrInfoFmt,eax
;********************************************************************
; 获取字符串版本信息
;********************************************************************
mov ebx,offset lpStr1
.while ebx <= offset lpStr12
invoke lstrcpy,addr @szString,addr @szStringInfo
mov eax,[ebx]
invoke lstrcat,addr @szString,eax
mov eax,[ebx]
invoke lstrcat,_lpBuffer,eax
invoke lstrcat,_lpBuffer,addr szArrow ;加上 -->
invoke VerQueryValue,addr @dbVerInfo,addr @szString,addr @lpBuffer,addr @dwLen
.if eax
invoke lstrcat,_lpBuffer,@lpBuffer ;加上获得的版本信息
.endif
invoke lstrcat,_lpBuffer,addr szReturn ;加上回车
add ebx,4
.endw
popad
mov eax,TRUE
ret
_GetVersionInfo endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end ;最后这个end非常的重要,如果没有的话会出现编译的错误。error A2088: END directive required at end of file。所以要加上。
然后我们就使用ml -c -coff编译了,生成了一个odj文件,就是这个方法的实现了。
然后我们编译主文件。
ShowInfo.asm
上代码:
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include Version.inc
includelib Version.lib
include comctl32.inc
includelib comctl32.lib
include comdlg32.inc
includelib comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000h
DLG_MAIN equ 1
IDC_INFO equ 101
IDC_FILE equ 102
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
szBuffer db 4096 dup (?)
.const
szPeFileExt db 'PE文件',0,'*.exe;*.dll;*.scr;*.drv',0,0
szError db '文件中没有包含版本信息!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
_GetVersionInfo proto :dword,:dword 既然是引用当然要先声明一下了,然后就可以编译了方法是一样的;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @szBuffer[MAX_PATH]:byte
local @stOpenFileName:OPENFILENAME
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
;********************************************************************
; 设置标题栏图标
;********************************************************************
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDOK
;********************************************************************
; 打开一个选择文件的对话框
;********************************************************************
invoke RtlZeroMemory,addr @stOpenFileName,sizeof OPENFILENAME
invoke RtlZeroMemory,addr @szBuffer,sizeof @szBuffer
mov @stOpenFileName.lStructSize,SIZEOF @stOpenFileName
mov @stOpenFileName.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
push hWnd
pop @stOpenFileName.hwndOwner
mov @stOpenFileName.lpstrFilter,offset szPeFileExt
lea eax,@szBuffer
mov @stOpenFileName.lpstrFile,eax
mov @stOpenFileName.nMaxFile,MAX_PATH
invoke GetOpenFileName,addr @stOpenFileName
.if eax
;********************************************************************
; 获取版本信息并显示出来
;********************************************************************
invoke _GetVersionInfo,addr @szBuffer,addr szBuffer
.if eax
invoke SetDlgItemText,hWnd,IDC_FILE,addr @szBuffer
invoke SetDlgItemText,hWnd,IDC_INFO,addr szBuffer
.else
invoke MessageBox,hWnd,addr szError,NULL,MB_OK or MB_ICONHAND
.endif
.endif
.endif
;********************************************************************
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
然后就编译了。生成了一个obj文件。当然了还有res文件,使用rc进行编译了
然后使用link进行连接其他的都是一样的,obj文件名用空格隔开就可以了。
资源文件也贴上来了:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 0x1000 //图标
#define DLG_MAIN 1
#define IDC_INFO 101
#define IDC_FILE 102
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 138, 123, 231, 139
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "查看PE文件版本信息"
FONT 9, "宋体"
{
EDITTEXT IDC_INFO, 5, 5, 220, 110, ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_TABSTOP
LTEXT "", IDC_FILE, 5, 123, 165, 8
DEFPUSHBUTTON "选择文件(&B)", IDOK, 175, 120, 50, 14
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
图片自己找个就行了随便都可以。