PE Dump汇编程序

PE Dump 的实现
是PE文件字码查看器,利用它可以查看和总计指定的PE文件的十六进制字节码,帮助我们更好地分析PE结构


列一:是地址。地址的值是第(n*16+1)个字节在文件中的位置

列二:是由空格分隔符分隔的16个字节的十六进制显示

列三:这16个字节对应的ASCII码值。

打开PE文件---》获取文件大小totalSize----》求循环显示16字节数据-----》显示剩余totalSize%16个字节

内存映射文件
是指将硬盘上的文件不做修改地装载到内存中。这样,文件中的字节与字节之间就是顺序排列的了。
在硬盘上,文件被分割成若干簇,这些簇不一定会按照文件内容顺序排列在一起,当我们访问磁盘上的文件时,需要计算机首先将不同位置的内容读取到内存。有了内存映射文件,访问就会变得更轻松和快捷,由于读取磁盘的操作集中到了一起执行,读写效率会提高很多。被一次性读取到内存的文件字节按线性排序,访问相对简单,速度也提升了不少。
PE内存映像:
是指将PE文件按照一定的规则装载到内存中,装入后整个文件头内容不会发生变化,但PE文件的某一部分如节的内容会按照字段中的对齐方式在内存中对齐,从而使得内存中的PE映像与装载前的PE文件不同。
PE文件是由操作系统装载进内存的,其目的是为了运行。为了配合操作系统的运行,方便高度,提高运行效率,PE映像必须按照一定的格式对齐,所以内存中的PE映像和原来硬盘上的文件是不同的,当然与内存映射文件也就不一样了。

1)RC文件
    编译:rc -r PEDump.rc
#include <resource.h>

#define ICON_MAIN 	1000
#define DLG_MAIN	1000
#define IDC_INFO	1001
#define IDM_MAIN	2000
#define	IDM_OPEN	2001
#define IDM_EXIT	2002

#define	IDM_1		4000
#define IDM_2		4001
#define IDM_3		4002
#define IDM_4		4003


ICO_MAIN	ICON	"main.ico"

DLG_MAIN	DIALOG	50,50,544,399
STYLE	DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION	"PE Dump by evan"
MENU	IDM_MAIN
FONT	9,"宋体"
BEGIN
	CONTROL "",IDC_INFO,"RichEdit20A",196|ES_WANTRETURN|WS_CHILD|ES_READONLY|
				WS_VISIBLE|WS_BORDER|WS_VSCROLL|WS_TABSTOP,0,0,540,396
END

IDM_MAIN	menu	discardable
BEGIN
	POPUP "File(&F)"
	BEGIN
		menuitem "Open File(&O)...",IDM_OPEN
		menuitem separator
		menuitem "Exit(&X)",IDM_EXIT
	END
	POPUP "Edit(&E)"
	BEGIN
		menuitem separator
	END
	POPUP "Format"
	BEGIN
		menuitem separator
	END
	
	POPUP "View"
	BEGIN
		menuitem "StopDump..",IDM_1
		menuitem "Alpha",IDM_2
		menuitem separator
		menuitem "Size",IDM_3
		menuitem "Width",IDM_4
	END
	
	POPUP "Help(&H)"
	BEGIN
		menuitem separator
	END
END


2)Asm文件

 生成PEDump.obj

ml -c -coff PEDump.asm

链接生成可执行文件

link -subsystem:windows PEDump.obj PEDump.res

	.386
	.model flat,stdcall
	option casemap:none
	
	include windows.inc
	include user32.inc
	includelib	user32.lib
	include 	kernel32.inc
	includelib 	kernel32.lib
	include		comdlg32.inc
	includelib	comdlg32.lib
	
	ICO_MAIN	equ		1000
	DLG_MAIN	equ		1000
	IDC_INFO	equ		1001
	IDM_MAIN	equ		2000
	IDM_OPEN	equ		2001
	IDM_EXIT	equ		2002
	IDM_1		equ		4000
	IDM_2		equ		4001
	IDM_3		equ		4002
	
	.data
	hInstance	dd ?	;进程实例句柄
	hRichEdit	dd ?	;富文本动态链接库句柄
	hWinMain	dd ?	;窗口句柄
	hWinEdit	dd ?	;文本控件句柄
	totalSize 	dd ?	;文件大小
	lpMemory	dd ?	;内存映像文件在内存的起始位置
	szFileName	dd	MAX_PATH dup(?)	;要打开的文件路径及名称名
	
	lpServicesBuffer 	db	100 dup(0)	;所有内容
	bufDisplay			db 	50	dup(0)	;第三列ASCII码字符显示
	szBuffer			db 	200 dup(0)	;临时缓冲区
	lpszFilterFmt4		db 	'%08x	',0
	lpszManyBlanks		db	'	',0
	lpszBlanks			db 	' ',0
	lpszSplit			db	'-',0
	lpszScanFmt			db	'%02x',0
	lpszHexArr			db	'0123456789ABCDEF',0
	lpszReturn			db	0dh,0ah,0
	lpszDoubleReturn	db  0dh,0ah,0dh,0ah,0
	lpszOut1			db	'文件大小:%d',0
	dwStop				dd 	0
		
	
	.const
	szDllEdit	db	'RichEd20.dll',0
	szClassEdit	db	'RichEdit20A',0
	szFont		db	'宋体',0
	
	szExtPe		db 	'PE File',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
				db  'All Files(*.*)',0,'*.*',0,0
	szErr		db 	'文件格式错误!',0
	szErrFormat	db	'操作文件时出现错误!',0
	
	
	.code
	;---------------------
	;初始化窗口程序
	;---------------------
	_init proc
		local @stCf:CHARFORMAT
		
		invoke	GetDlgItem,hWinMain,IDC_INFO
		mov hWinEdit,eax
		
		;为窗口设置图标
		invoke LoadIcon,hInstance,ICO_MAIN
		invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax
		
		;设置编辑控件
		invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
		invoke RtlZeroMemory,addr @stCf,sizeof @stCf
		mov @stCf.cbSize,sizeof @stCf
		mov @stCf.yHeight,14*1440/96
		mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
		invoke lstrcpy,addr @stCf.szFaceName,addr szFont
		invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
		invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
		ret
	_init endp
	
	;---------------------------
	;错误handler
	;---------------------------
	_Handler proc _lpExceptionRecord,_lpSEH,_lpContext,_lpDispathcerContext
		pushad
		mov esi,_lpExceptionRecord
		mov edi,_lpContext
		assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
		mov eax,_lpSEH
		push [eax+0ch]
		pop  [edi].regEbp
		push [eax+8]
		pop  [edi].regEip
		push [eax]
		pop [edi].regEsp
		assume esi:nothing,edi:nothing
		popad
		mov eax,ExceptionContinueExecution
		ret
	_Handler endp
	
	;---------------------------
	;向文本框中追加文本
	;---------------------------
	_appendInfo proc _lpsz
		local @stCR:CHARRANGE
		
		pushad
			invoke GetWindowTextLength,hWinEdit
			mov @stCR.cpMin,eax;将插入点移动到最后
			mov @stCR.cpMax,eax
			invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
			invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
		popad
		ret
	_appendInfo endp
	
	;---------------------------
	;打开PE文件并处理
	;---------------------------
	_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 szExtPe
		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
						
						;invoke wsprintf,addr szBuffer,addr lpszOut1,totalSize
						;invoke MessageBox,NULL,addr szBuffer,NULL,MB_OK
						
						.while TRUE
							.if totalSize ==0 ; 最后一行
							;填充空格
								.while TRUE
									.break	.if @dwBlanks==0
									invoke lstrcat,addr lpServicesBuffer,addr lpszBlanks
									dec @dwBlanks
								.endw
								; 第二列与第三列中间的空格
								invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
								; 第三列内容
								invoke lstrcat,addr lpServicesBuffer,addr bufDisplay
								; 回车换行符号
								invoke lstrcat,addr lpServicesBuffer,addr lpszReturn
								.break
							.endif
							;将al翻译成可以显示的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中
							
							;组合字节的十六进制字符串到@bufTemp1中,类似于:"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
							
							; 将第二列写入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
	;---------------------
	;窗口回调函数
	;---------------------
	_ProcDlgMain  proc uses ebx edi esi hWnd,wMsg,wParam,lParam
		local @szClient
		
		mov eax,wMsg
		.if eax==WM_CLOSE
			invoke EndDialog,hWnd,NULL
		.elseif eax==WM_INITDIALOG ;初始化
			push hWnd
			pop hWinMain
			call _init
		.elseif eax==WM_COMMAND ;菜单
			mov eax,wParam
			.if eax==IDM_OPEN
			 mov dwStop,0
			 invoke CreateThread,NULL,0,addr _openFile,addr @szClient,0,NULL
			 ; invoke _openFile
			.elseif eax==IDM_1
			 mov dwStop,1
			.elseif eax==IDM_2
			.elseif eax==IDM_3
			.endif
		.else
			mov eax,FALSE
			ret
		.endif
		mov eax,TRUE
		ret
	_ProcDlgMain   endp
	
	start:
		invoke LoadLibrary,offset szDllEdit
		mov hRichEdit,eax
		invoke GetModuleHandle,NULL
		mov hInstance,eax
		invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
		invoke FreeLibrary,hRichEdit
		invoke ExitProcess,NULL
	end start
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蚂蚁_CrkRes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值