最近看了一下论坛上关于PE文件头的描述也跟着写了一个BIN文件,可是不知道为什么一运行就出异常,想了很久不明白,求高手指教!
;DOS文件头
DOS_Header:
.e_magic dw 'MZ';DOS头标志
.e_dblp dw 0
.e_cp dw 0
.e_crlc dw 0
.e_cparhdr dw 0
.e_minalloc dw 0
.e_maxalloc dw 0xffff
.e_ss dw 0
.e_sp dw 0
.e_csum dw 0
.e_ip dw 0
.e_cs dw 0
.e_lfarlc dw 0
.e_ovno dw 0
.e_res dw 0,0,0,0
.e_oemid dw 0
.e_oeminfo dw 0
.e_res2 dw 0,0,0,0,0,0,0,0,0,0
.e_lfanew dd PE_Header
PE_Header:
.Signature db 'PE',0,0
.machine dw 0x014c
.numberofsections dw 0x0001
.timedatestamp dd 0
.pointertosymboltable dd 0
.numberofsymbols dd 0
.sizeofoptionalheader dw 0x00e0
.characteristics dw 0x010f
Optional_Header:
.Magic dw 0x010b
.MajorLinkerVersion db 0
.MinorLinkerVersion db 0
.SizeOfCode dd 0
.SizeOfInitializedData dd 0
.SizeOfUninitialzedData dd 0
.AddressOfEntryPoint dd code+0xe00
.BaseOfCode dd 0x1000
.BaseofData dd 0x200
.ImageBase dd 0x00040000
.SectionAlignment dd 0x00001000
.FileAlignment dd 0x00000200
.MajorOperatingSystemVersion dw 0
.MinorOperatingSystemVersion dw 0
.MajorImageVersion dw 0
.MinorImageVersion dw 0
.MajorSubsystemVersion dw 4
.MinorSubsystemVersion dw 0
.Win32VersionValue dd 0
.SizeOfImage dd 0x00002000
.SizeOfHeaders dd start
.CheckSum dd 0
.Subsystem dw 2
.DllCharacteristics dw 0
.SizeOfStackReserve dd 0x10000
.SizeOfStackCommit dd 0x100
.SizeOfHeapReserve dd 0x10000
.SizeOfHeapCommnit dd 0x100
.Loaderflags dd 0
.NumberOfRvaAndSizes dd 0x10
;下面就是16个表的偏移和大小,因为我基本没有用到表所以都写为0了
dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
sections:
.SectionName db '.text',0,0,0
.VirtualSize dd 0x1000
.VirtualAddress dd 0x1000
.SizeOfRawData dd end-start
.PointerToRawData dd start
.PointerToRelocations dd 0
.PointerToLinenumbers dd 0
.NumberOfRelocations dw 0
.NumberOfLinenumbers dw 0
.Characteristics dd 0xe00000e0;表示段中有可执行属性,可读属性,可写属性,有代码,有初始化数据,有未初始化数据
align 0x200,db 0
start:
kernel32_Address resd 1
user32_Address resd 1
GetProcAddress_Address resd 1
ExitProcess_Address resd 1
MessageBoxA_Address resd 1
LoadLibraryA_Address resd 1
Title db 'Hello',0
Content db 'Hello World!',0
GetProcAddress db 'GetProcAddress',0
ExitProcess db 'ExitProcess',0
LoadLibraryA db 'LoadLibraryA',0
user32 db 'user32.dll',0
MessageBoxA db 'MessageBoxA',0
code:
mov eax,[fs:0x30]
mov eax,[eax+0xc]
mov eax,[eax+0x1c]
mov eax,[eax]
mov eax,[eax+0x8];eax里面是kernel32的基地址
mov [kernel32_Address],eax
mov ebx,[eax+0x3c];ebx中是PE头的相对地址
mov ebx,[ebx+eax+0x78]
add ebx,eax;引出表地址
mov ecx,[ebx+0x20]
add ecx,eax
xor edx,edx
push edx
CompareNext:
pop edx
inc edx
mov edi,[ecx]
add edi,eax
add ecx,4
push edx
mov esi,GetProcAddress
CompareName:
mov dl,[edi]
mov dh,[esi]
cmp dl,dh
jne CompareNext
inc edi
inc esi
cmp byte [esi],0
je GetAddress
jmp CompareName
GetAddress:
pop edx
dec edx
shl edx,1
mov ecx,[ebx+0x24]
add ecx,eax
add ecx,edx
xor edx,edx
mov dx,[ecx]
shl edx,2
mov ecx,[ebx+0x1c]
add ecx,eax
add ecx,edx
add eax,[ecx];eax里面就是getprocaddress
mov [GetProcAddress_Address],eax
push ExitProcess
push dword [kernel32_Address]
call eax
mov [ExitProcess_Address],eax
push LoadLibraryA
push dword [kernel32_Address]
call dword [GetProcAddress_Address]
mov [LoadLibraryA_Address],eax
push user32
call eax
mov [user32_Address],eax
push MessageBoxA
push eax
call dword [GetProcAddress_Address]
mov [MessageBoxA_Address],eax
push 0
push Title
push Content
push 0
call eax
push 0
call dword [ExitProcess_Address]
end:
备注除了文件头部分,在把.text节属性改为0e00000e后代码运行正常,应该可以说明代码本身不存在问题,问题出在PE文件头里所以想请高手给指正
[课程]Android-CTF解题方法汇总!