PE Tutorial 5: Section Table
theory:
To this lesson, we have learned a lot about DOS HEADER and PE HEADER. Next, it will be the step Table. The section table is actually an array of structures next to PE Header. The number of members of the array is determined by the domain value of the NumberOfSections domain in the file header (Image_file_Header). The knot structure is named image_section_header.
Image_sizeof_short_name EQU 8
IMAGE_SECTION_HEADER STRUCT Name1 db IMAGE_SIZEOF_SHORT_NAME dup (?) Union Misc PhysicalAddress dd? VirtualSize dd? Ends VirtualAddress dd? SizeOfRawData dd? PointerToRawData dd? PointerToRelocations dd? PointerToLinenumbers dd? Oh NumberOfRelocations dw? NumberOfLinenumbers dw? Characteristics dd? IMAGE_SECTION_HEADER ENDS
Again, not all members are very useful, we only care about those true.
FieldMeaningsName1 The name of the present domain is "name", just "name" has been used by MASM as a keyword, so we can only replace it with "Name1". The section of this is not more than 8 bytes. Remember that the name is just a tag, we choose any name or even empty, pay attention to the end of NULL. Name is not an ASCIIZ string, so you don't have to end with NULL. VirtualAddress's RVA (relative virtual address) in this section. The PE loader reads this value when it is mapped to memory, so if the domain value is 1000h, the PE file is installed at 400000H, then this section is contained in 401000h. The SIZEOFRAWDATA is aligned with the post size, and the PE loader extracts the domain value to understand the number of the number of personns that need to be mapped into the memory. (Translator Note: Suppose a file's file alignment size is 0x200, if the previous VirtualSize domain indicates that this section is 0x388 bytes, the domain value is 0x400, indicating that this section is 0x400 byte length). PointertorawData This is a section of the file, and the PE loader finds the location of the data in the file via this domain value. Characteristics contains tags to indicate feature properties, such as whether the festival contains executable code, initialized data, not initial data, can be writable, readable, and so on.
Now we have known the image_section_header structure, and then simulate the work of the PE loader:
Read image_file_header's NumberOfSections domain, know the number of questions of the file. The SizeOfHeaders domain value is used as the file offset of the section table and locates the section table. Traverse the entire structure array to check each member value. For each structure, we read the PointertorawData domain value and locate the file offset. Then read the SIZEOFRAWDATA domain value to determine the number of bytes that map the memory. Plus the VirtualAddress domain value plus the imagebase domain value equal to the virtual address starting. Then you will refill the section into the memory and set the properties according to the CHARACTERISTICS domain value. Traverse the entire array until all sections have been processed.
Note that we have not used the section: This is actually not important. Example:
This routine opens a PE file to traverse its section, and displays information about the sections at the list box control.
.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 include / masm32 /include/comctl32.inc includelib /masm32/lib/comctl32.lib includelib /masm32/lib/user32.lib includelib /masm32/lib/kernel32.lib includelib /masm32/lib/comdlg32.lib IDD_SECTIONTABLE equ 104 IDC_SECTIONLIST equ 1001 sEH struct
PrevLink dd;? The address of the previous seh structure CurrentHandler dd;? The address of the new 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.5", 0 OFN OpenFileName <> Filterstring DB "Executable files (* .exe, * .dll)", 0, "*. EXE; *. DLL", 0 DB "All Files", 0, "*. *", 0, 0 Fileopenerse DB "Cannot Open THE FILE for Reading", 0 FileOpenMappinger DB "Cannot Open THE FILE MAMORY MAPPING", 0 Filemappinger DB "Cannot Map The File Into Memory, 0 FileInvalidpe DB "this file is not a valid pe", 0 template db "% 08LX", 0 sectionname db "section", 0 VirtualSize DB "v.size", 0 VirtualAddress DB "v.address", 0 SizeOfRawData db "Raw Size", 0 rawOffset db "Raw Offset", 0 Characteristics db "Characteristics", 0 .data? hInstance dd? buffer db 512 dup (?) hFile dd? hMapping dd? pMapping dd? ValidPE dd? NumberOfSections dd ? Code Start Proc LOCAL seh: SEH invoke GetModuleHandle, NULL mov hInstance, eax 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 .endif .else mov ValidPE, FALSE .endif FinalExit: push seh.PrevLink pop fs: [0] .if ValidPE == TRUE call ShowSectionInfo .else invoke MessageBox, 0, addr FileInValidPE, addr AppName, MB_OK MB_ICONINFORMATION .endif 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 invoke InitCommonControls start endp SEHHandler proc uses edx pExcept: DWORD, pFrame: DWORD, pContext: DWORD , Pdispatch: DWORD MOV EDX, PFRAME Assume Edx: Ptr Seh MOV ED, PCONText Assume Eax: Ptr Context Push [EDX] .safeoffset Pop [EAX] .Regeip Push [EDX] .prevesp pop [ex] .regesp push [edx] .PrevEbp pop [eax] .regEbp mov ValidPE, FALSE mov eax, ExceptionContinueExecution ret SEHHandler endp DlgProc proc uses edi esi hDlg: DWORD, uMsg: DWORD, wParam: DWORD, lParam: DWORD LOCAL lvc: LV_COLUMN LOCAL lvi: LV_ITEM .if uMsg ==
WM_INITDIALOG mov esi, lParam mov lvc.imask, LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM mov lvc.fmt, LVCFMT_LEFT mov lvc.lx, 80 mov lvc.iSubItem, 0 mov lvc.pszText, offset SectionName invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_INSERTCOLUMN , 0, addr lvc inc lvc.iSubItem mov lvc.fmt, LVCFMT_RIGHT mov lvc.pszText, offset VirtualSize invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_INSERTCOLUMN, 1, addr lvc inc lvc.iSubItem mov lvc.pszText, offset VirtualAddress invoke SendDlgItemMessage, hDlg , IDC_SECTIONLIST, LVM_INSERTCOLUMN, 2, addr lvc inc lvc.iSubItem mov lvc.pszText, offset SizeOfRawData invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_INSERTCOLUMN, 3, addr lvc inc lvc.iSubItem mov lvc.pszText, offset rawOffset invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST , LVM_INSERTCOLUMN, 4, ADDR LVC INC LVC.ISUBITEM MOV LVC.PSZTEXT, OFFSET Characteristics Invoke Senddl gItemMessage, hDlg, IDC_SECTIONLIST, LVM_INSERTCOLUMN, 5, addr lvc mov ax, NumberOfSections movzx eax, ax mov edi, eax mov lvi.imask, LVIF_TEXT mov lvi.iItem, 0 assume esi: ptr IMAGE_SECTION_HEADER .while edi>
0 mov lvi.iSubItem, 0 invoke RtlZeroMemory, addr buffer, 9 invoke lstrcpyn, addr buffer, addr [esi] .Name1,8 lea eax, buffer mov lvi.pszText, eax invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_INSERTITEM, 0, addr lvi invoke wsprintf, addr buffer, addr template, [esi] .Misc.VirtualSize lea eax, buffer mov lvi.pszText, eax inc lvi.iSubItem invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_SETITEM, 0, addr lvi invoke wsprintf, addr buffer, addr template, [esi] .VirtualAddress lea eax, buffer mov lvi.pszText, eax inc lvi.iSubItem invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_SETITEM, 0, addr lvi invoke wsprintf, addr buffer, addr template, [esi] .SizeOfRawData lea Eax, Buffer Mov Lvi.psztext, Eax Inc Lvi.isubitem Invoke Senddlgitemmessage, HDLG, IDC_SECTIONLIST, LVM_SETITITETITET, 0, AddR Lvi Invoke Wsprintf, Addr Buffer, Addr TE mplate, [esi] .PointerToRawData lea eax, buffer mov lvi.pszText, eax inc lvi.iSubItem invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_SETITEM, 0, addr lvi invoke wsprintf, addr buffer, addr template, [esi] .Characteristics lea eax , buffer mov lvi.pszText, eax inc lvi.iSubItem invoke SendDlgItemMessage, hDlg, IDC_SECTIONLIST, LVM_SETITEM, 0, addr lvi inc lvi.iItem dec edi add esi, sizeof IMAGE_SECTION_HEADER .endw .elseif uMsg ==
WM_CLOSE invoke EndDialog, hDlg, NULL .else mov eax, FALSE ret .endif mov eax, TRUE ret DlgProc endp ShowSectionInfo proc uses edi mov edi, pMapping assume edi: ptr IMAGE_DOS_HEADER add edi, [edi] .e_lfanew assume edi: ptr IMAGE_NT_HEADERS mov ax, [edi] .FileHeader.NumberOfSections movzx eax, ax mov NumberOfSections, eax add edi, sizeof IMAGE_NT_HEADERS invoke DialogBoxParam, hInstance, IDD_SECTIONTABLE, NULL, addr DlgProc, edi ret ShowSectionInfo endp end start analysis:
This example reuses the code of the PE tutorial 2. After the validity of the PE file is verified, continue calling the function showsectionInfo to display each section.
ShowsectionInfo Proc Uses Edi Mov Edi, PMapping Assume EDI: PTR Image_DOS_HE_LFANEW Assume EDI: PTR Image_NT_HEADERS
We use the EDI as a pointer to PE file data. First, the PMApping of the DOS Header address will be assigned to the EDI, plus the E_LFANEW domain value equal to the address of the PE Header.
MOV AX, [EDI] .fileHeader.Numberofsections Mov Numberofsections, AX
Because we want to traverse the festival table, you must first get the number of questions of the file. This has to rely on the Numberofsections domain in File Header, remember this is a Word domain.
Add Edi, SizeOf Image_NT_HEADERS
Now EDI is pointing to the start address of Pe Header, plus the PE Header structure, just pointing to the section table.
Invoke Dialogboxparam, Hinstance, IDD_SECTIONTABLE, NULL, ADDR DLGPROC, EDI
Call the DialogBoxParam Display List dialog, note that we have passed the section table address as the last parameter, which can be extracted from the LPARAM parameter of the WM_INITDIALOG message.
In the dialog process, we respond to the WM_INITDIALOG message, save the lParam value (section table address) into the ESI, and the number of sums of the EDI and set the list control. After passing everything, enter the loop to insert each section into the list control, this part is quite simple.
.While Edi> 0 MOV LVI.ISUBITEM, 0
The string is placed in the first column.
Invoke RTLZERMEMORY, ADDR BUFFER, 9 Invoke Lstrcpyn, Addr Buffer, Addr [ESI] .Name1, 8 Lea Eax, Buffer Mov Lvi.psztext, EAX
To display the name of the section, of course, convert it to the ASCIIZ string first.
Invoke Senddlgitemmessage, HDLG, IDC_SECTIONLIST, LVM_INSERTITEM, 0, ADDR LVI
Then display the first column. Continue our great project, showing the next structure of the horse after the last word in this section.
Dec Edi Add ESI, SIZEOF Image_SECTION_HEADER .Endw Decrease EDI per handle, then add an image_section_header size to the next Image_SECTION_HEADER structure.
The step of traversing a knot:
PE file validity check. Located to the starting address of Pe Header. Get the number of days from the NumberOfSections domain of File HEADER. By two ways positioning section table: ImageBase SizeOfheaders or PE HEADER's start address PE HEADER structure size. (The knot is followed by Pe Header). If not using a file mapping method, you can use setFilePointer to locate the file pointer to the section table. The file offset of the section table is stored in the SizeOfheaders field. (SIZEOFHEADERS is an Image_Optional_Header structure member) handles each image_section_header structure.
Translation: IAMGUFENG [ICZelion's Win32 Assembly Home] [Luoyunbin's Win32 ASM Page]