首先说一下在MASM32Editor中,可以使用快捷键进行编译和运行——
F12(第一次需要手动选择Project-Console Assemble & Link)进行编译,之后就可以按下Ctl+D召唤出cmd小黑窗啦~
再来说一下踩到的雷,刚开始连个缓冲区是啥也不知道(-_-||太菜了呜呜呜),现在的粗浅一些的理解就是你找了一个大箱子,可以往里面塞东西,所以一定要给你的缓冲区开辟一定大小的空间(对,说的就是下文的buf3),如果不开空间就会出现一些莫名其妙的乱码(可能甚至在你根本没有输出的时候输出一堆你根本不认识的字儿强制你了解汉字的魅力。。。)
题目要求呢,就是读出一些PE文件的内容,我们可以先用Ollydbg看看正确输出的结果是什么【具体操作是在View-File里面打开你的目标文件】;然后需要明确的一点是,咱们需要读取的内容是通过指针偏移量来定位的,所以需要确定好指针的起始位置,是Dos部首(MZ那块),还是PE文件头(PE那块)
话不多说,直接上代码~
.386
.model flat,stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\macros\macros.asm
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
.data
que BYTE "Please input a PE file: ",0
que11 BYTE "IMAGE_DOS_HEADER",0Ah,0Dh,0
que12 BYTE " e_magic:",0
que13 BYTE " e_lfanew:",0
que21 BYTE "IMAGE_DOS_HEADER",0Ah,0Dh,0
que22 BYTE " Signature:",0
que31 BYTE "IMAGE_DOS_HEADER",0Ah,0Dh,0
que32 BYTE " NumberOfSections:",0
que33 BYTE " TimeDateStamp:",0
que34 BYTE " Charateristics:",0
que41 BYTE "IMAGE_DOS_HEADER",0Ah,0Dh,0
que42 BYTE " e_magic:",0
que43 BYTE " e_lfanew:",0
que51 BYTE "IMAGE_DOS_HEADER",0Ah,0Dh,0
que52 BYTE " AddressOfEntryPoint:",0
que53 BYTE " ImageBase:",0
que54 BYTE " SectionAlignment:",0
que55 BYTE " FileAlignment:",0
;!!!!!!!!!!!!!!!!!!!!!!!血与泪的教训,,一定要给buf3开足空间!!!!!!!!!!!!!!!!!!!!!!!
buf3 DWORD 4000 DUP(0) ;缓冲区指针
buf4 DWORD 4000 DUP(0) ;转成十六进制
buf5 WORD 4000 DUP (0) ;存储后四位
buf2 BYTE "dec2dw.exe",0 ;这里写死了,所以每次读取的是dec2dw
ans BYTE 20 DUP(0),0
hfile DWORD 0,0 ;文件句柄
endl BYTE 0Ah,0Dh,0 ;换行
temp DWORD 0,0 ;存ecx的值,之前实验的时候好像发现ecx可能被悄悄改了
temp1 DWORD 0,0 ;定位指针的初始位置,是Dos头还是PE头
.code
Output PROC ;读取相应位置的内容并转化成二进制,顺便再控制一波格式
;edx为偏移量
mov esi,OFFSET buf3
add esi,edx ;把偏移量加上
add esi,temp1 ;DOS头还是NT头
mov eax,DWORD PTR[esi]
mov ebx,eax
invoke dw2hex,eax,addr buf4 ;dw2hex包里有好像
mov ecx,temp
.if ecx==8
invoke StdOut,addr buf4
.else
mov ax,WORD PTR [buf4+4]
mov buf5,ax
invoke StdOut,addr buf5
mov ax,WORD PTR [buf4+6]
mov buf5,ax
invoke StdOut,addr buf5
.endif
invoke StdOut,addr endl
ret
Output ENDP
start:
invoke StdOut,addr que ;输出请求
invoke StdIn,addr ans,20 ;输入exe名称(象征性输入,,直接回车也莫得问题)
;打开文件
invoke CreateFile,addr buf2,\ ;亲身实验,好像不加“\”也没问题
GENERIC_READ,\
FILE_SHARE_READ,\
0,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_ARCHIVE,\
0
mov hfile,eax ;保存文件句柄
invoke SetFilePointer,hfile,0,0,FILE_BEGIN
invoke ReadFile,hfile,addr buf3,4000,0,0
mov esi,OFFSET buf3;文件入口
;buf3的地址是Dos部首的头,buf3的值是MZ啥的
;.....................................................................
invoke StdOut,addr que11
invoke StdOut,addr que12
;EM
mov edx,0
mov temp1,edx
mov ecx,4
mov temp,ecx
invoke Output
invoke StdOut,addr que13
;EF
mov edx,3ch
mov ecx,8
mov temp,ecx
invoke Output
invoke StdOut,addr que21
invoke StdOut,addr que22
mov temp1,ebx
;S
mov edx,0
invoke Output
invoke StdOut,addr que31
invoke StdOut,addr que32
;NOS
mov edx,6h
mov ecx,4
mov temp,ecx
invoke Output
invoke StdOut,addr que33
;TDS
mov edx,8h
mov ecx,8
mov temp,ecx
invoke Output
invoke StdOut,addr que34
;C
mov edx,16h
mov ecx,4
mov temp,ecx
invoke Output
invoke StdOut,addr que51
invoke StdOut,addr que52
;AOE
mov edx,28h
mov ecx,8
mov temp,ecx
invoke Output
invoke StdOut,addr que53
;IB
mov edx,34h
invoke Output
invoke StdOut,addr que54
;SA
mov edx,38h
invoke Output
invoke StdOut,addr que55
;FA
mov edx,3ch
invoke Output
invoke CloseHandle,hfile
invoke ExitProcess,0
end start
唉!依然是在ddl上奔跑的一天......
本人新手+菜鸡一枚,有啥不对的地方欢迎大家指出来~
虽然不是考试周,,但是已经濒临破防.......xdm...挺住!!!共勉!