ICZelion PE TUT2

zhaozj2021-02-11  217

Tutorial 2: Detecting a Valid PE file

In this Tutorial, We Well Learn How To Check if a given file is a valid pe file.download the example.

THEORY:

How can you verify if a given file is a PE file? That question is difficult to answer. That depends on the length that you want to go to do that. You can verify every data structure defined in the PE file format or you are satisfied with verifying only the crucial ones. Most of the time, it's pretty pointless to verify every single structure in the files. If the crucial structures are valid, we can assume that the file is a valid PE. And we will use that assumption.

The essential structure we will verify is the PE header itself So we need to know a little about it, programmatically The PE header is actually a structure called IMAGE_NT_HEADERS It has the following definition...:

Image_nt_headers Struct Signature DD? FileHeader Image_File_Header <> OptionalHeader Image_Optional_Header32 <> iMage_NT_HEADERS Ends

Signature is a dword that contains the value 50h, 45h, 00h, 00h. In more human term, it contains the text "PE" followed by two terminating zeroes. This member is the PE signature so we will use it in verifying if a given file is a valid PE one.FileHeader is a structure that contains information about the physical layout of the PE file such as the number of sections, the machine the file is targeted and so on.OptionalHeader is a structure that contains information about the logical layout Of The PE File. Despite the "Optional" in ITS Name, It's Always Present.

Our goal is now clear. If value of the signature member of the IMAGE_NT_HEADERS is equal to "PE" followed by two zeroes, then the file is a valid PE. In fact, for comparison purpose, Microsoft has defined a constant named IMAGE_NT_SIGNATURE which we Can readily use.Image_dos_signature eQU 5a4dh image_os2_signature EQU 454EH image_os2_signature_le EQU 454ch image_vxd_signature EQU 454ch image_nt_signature EQU 4550h

The next question: how can we know where the PE header is The answer is simple:?.. The DOS MZ header contains the file offset of the PE header The DOS MZ header is defined as IMAGE_DOS_HEADER structure You can check it out in windows. INC. The E_LFANEW Member of the Image_dos_Header Structure Contains The File Offset of The Pe Header.

The Steps Are Now As Follows:

Verify if the given file has a valid DOS MZ header by comparing the first word of the file with the value IMAGE_DOS_SIGNATURE. If the file has a valid DOS header, use the value in e_lfanew member to find the PE header Comparing the first word of the PE header with the value image_nt_header. If Both Values ​​Match, The File is a Valid PE.

EXAMPLE:

.386 .model flat, stdcall option casemap: none include /masm32/include/windows.inc include /masm32/include/kernel32.inc include /masm32/include/comdlg32.inc include /masm32/include/user32.inc includelib / masm32 /lib/user32.lib includelib /masm32/lib/kernel32.lib includelib /masm32/lib/comdlg32.lib SEH struct PrevLink dd;? the address of the previous seh structure CurrentHandler dd;? the address of the exception handler SafeOffset dd? ; The offset where it's safe to continue execution PrevEsp dd;? the old value in esp PrevEbp dd;? The old value in ebp SEH ends.data AppName db "PE tutorial no.2", 0 ofn OPENFILENAME <> FilterString db "Executable Files (* .exe, * .dll) ", 0," *. EXE; *. DLL ", 0 DB" All Files ", 0," *. * ", 0, 0 FileOpener DB" Cannot Open THE FILE for FOR Reading ", 0 FileOpenMappinger DB" Cannot Open THE FILE for MAMORY MAPPING ", 0 Filemappinger DB" Cannot Map The File Into Memory, 0 FileValidpe DB "this File IS A Valid PE", 0 FileInvalidpe DB "TH Is File Is Not a Valid PE ", 0 .data? Buffer DB 512 DUP (?) HFILE DD? HMApping DD? PMApping DD? Validpe Dd? .code Start Procal SEH: SEH MOV OFN.LSTRUCTSIZE, SIZEOF OFN MOV OFN.. lpstrFilter, OFFSET FilterString mov ofn.lpstrFile, OFFSET buffer mov ofn.nMaxFile, 512 mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY invoke GetOpenFileName, aDDR ofn .if eax == TRUE invoke CreateFile, addr buffer, GENERIC_READ, File_share_read, null, open_existing, file_attribute_normal, null .if eax! =

INVALID_HANDLE_VALUE mov hFile, eax invoke CreateFileMapping, hFile, NULL, PAGE_READONLY, 0,0,0 .if eax! = NULL mov hMapping, eax invoke MapViewOfFile, hMapping, FILE_MAP_READ, 0,0,0 .if eax! = NULL mov pMapping, Eax Assume Fs: Nothing Push Fs: [0] Pop Seh.Prevlink Mov Seh.currenthandler, Offset Sehhandler Mov Seh.SAFEOFFSET, OFFSET FINALEXIT LEA EAX, SEH MOV FS: [0], ESP MOV SEH.PREVESP, ESP MOV SEH. PrevEbp, ebp mov edi, pMapping assume edi: ptr IMAGE_DOS_HEADER .if [edi] .e_magic == IMAGE_DOS_SIGNATURE add edi, [edi] .e_lfanew assume edi: ptr IMAGE_NT_HEADERS .if [edi] .Signature == IMAGE_NT_SIGNATURE mov ValidPE, TRUE. Else Mov Validpe, False .ndif .else mov ValidPE, FALSE .endif FinalExit: .if ValidPE == TRUE invoke MessageBox, 0, addr FileValidPE, addr AppName, MB_OK MB_ICONINFORMATION .else invoke MessageBox, 0, addr FileInValidPE, addr AppName, MB_OK MB_ICONINFORMATION .endif push seh.PrevLink pop fs: [0] invoke UnmapViewOfFile, pMapping .else invoke MessageBox, 0, addr FileMappingError, addr AppName, MB_OK MB_ICONERROR .endif invoke CloseHandle, hMapping .else invoke MessageBox, 0, addr FileOpenMappingError, addr AppName, MB_OK

MB_ICONERROR .endif invoke CloseHandle, hFile .else invoke MessageBox, 0, addr FileOpenError, addr AppName, MB_OK MB_ICONERROR .endif .endif invoke ExitProcess, 0 start endp SEHHandler proc uses edx pExcept: DWORD, pFrame: DWORD, pContext: DWORD, pDispatch : DWORD MOV EDX, PFRAME Assume Edx: Ptr Seh Mov Eax, PCONText Assume Eax: Ptr Context Push [EDX] .safeoffset Pop [EAX] .Regeip Push [EDX] .pregesp PUSH [EDX] .pregesp Push [EDX] .prevebp POP [EAX] .Regebp Mov Validpe, False Mov Eax, ExceptionContinueexecution Ret SEHHANDLER Endp End Startanalysis:

The program opens a file and checks if the DOS header is valid, if it is, it checks the PE header if it's valid. If it is, then it assumes the file is a valid PE. In this example, I use structured exception handling (SEH) so that we do not have to check for every possible error:. if a fault occurs, we assume that it's because the file is not a valid PE thus giving our program wrong information Windows itself uses SEH heavily in its parameter validation Routines. If you're interested in seh, read the article by jeremy gordon.

The Program Displays An Open File CommON Dialog To The User and WHEN THE User Chooses An Executable File, IT Opens The File And Maps It Into Memory. Before ITS UP A SEH:

assume fs: nothing push fs: [0] pop seh.PrevLink mov seh.CurrentHandler, offset SEHHandler mov seh.SafeOffset, offset FinalExit lea eax, seh mov fs: [0], eax mov seh.PrevEsp, esp mov seh.PrevEbp EBP

We start by assuming the use of fs register as nothing. This must be done because MASM assumes the use of fs register to ERROR. Next we store the address of the previous SEH handler in our structure for use by Windows. We store the address of our sEH handler, the address where the execution can safely resume if a fault occurs, the current values ​​of esp and ebp so that our sEH handler can get the state of the stack back to normal before it resumes the execution of our program.mov edi , PMapping Assume EDI: Ptr image_dos_header .IF [EDI] .e_magic == image_dos_signature

After we are done with setting up SEH, we continue with the verification. We put the address of the first byte of the target file in edi, which is the first byte of the DOS header. For ease of comparison, we tell the assembler that it can assume edi as pointing to the IMAGE_DOS_HEADER structure (which is the truth). We then compare the first word of the DOS header with the string "MZ" which is defined as a constant in windows.inc named IMAGE_DOS_SIGNATURE. If the comparison is OK, We Continue to the Pe Header. if NOT, We set the value in validpe to false, meaning what the file is not a valid pe.

Add Edi, [EDI] .e_lfanew assoc_nt_headers .if [EDI]. Signature == Image_NT_SIGNATURE MOV VALIDPE, TRUE .ELSE MOV VALIDPE, FALSE .Endif

To get to the PE header, we need the value in e_lfanew of the DOS header. This field contains the file offset of the PE header, relative to the file beginning. Thus we add this value to edi and we get to the first byte of The PE Header. it's place tria a fault may ivur. if The File IN E_LFANEW WILL BE INCORRECT AND THUS USING IT AMOUNTS TO USING A WILD POINTER. IF We don't use SEH, WE must check the value of the e_lfanew against the file size which is ugly. If all goes well, we compare the first dword of the PE header with the string "PE". Again there is a handy constant named IMAGE_NT_SIGNATURE which we can use. If the result of comparison is true, we assume the file is a valid PE.If the value in e_lfanew is incorrect, a fault may occur and our SEH handler will get control. It simply restores the stack pointer, bsae pointer and resumes the execution at The Safe Offset Which Is At The Finalexit Label.finaleXit: .if Validpe == True Invoke Messagebox, 0, Addr Filevalidpe, Addr Appname, MB_OK MB_ICONITIONBOX, 0, AddR FileInvalidpe, Addr Appname, MB_OK MB_ICONInInformation .endif

The Above Code Is SIMPLITY ITSELF. IT CHECKS The Value in Validpe and Displays a Message To The User Accordingly.

Push seh.prevlink pop fs: [0]

.

[ICZelion's Win32 Assembly HomePage]

转载请注明原文地址:https://www.9cbs.com/read-4648.html

New Post(0)