To get the length of a file, we can use the API function getfilesize ().
For files in PE format, we can also use the information in the PE file header to obtain the file length by: sizeofheaders value in optional Header + sizeofrawdata value in all section tables = file length
For details about the PE file format, refer to the PE tutorial of iczelion.
Http://www.google.cn/search? Complete = 1 & HL = ZH-CN & newwindow = 1 & Q = iczelion % E7 % 9A % 84pe % E6 % 95% E7 % A8 % 8B & btng = Google + % E6 % 90% 9C % E7 % B4 % A2 & meta = CR % 3 dcountrycn & AQ = f
The following code is also modified in the Demo code in the PE tutorial.
; <<
; Filename: filesize. ASM
; Function: select a PE file and display it's size with it's PE file head info
; Author: puple endurer
;
; Log
;-----------------------------------------------
; 2008-04-09 created!
; <<
. 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
D_useseh equ 0
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
Getpefilesize proto: lpstr
Ispefilemap proto: DWORD
Countsectionsize proto: DWORD,: DWORD
Countpefilesize proto: handle
. Data
G_szappname DB "PE file size", 0
G_stofn openfilename <>
G_szfilterstring DB "*. EXE, *. dll", 0, "*. EXE; *. dll", 0
DB "*. *", 0, "*. *", 0, 0
G_szfileopenerror DB "failed to open file to read", 0
G_szfileopenmappingerror DB "failed to open file for memory ing", 0
G_szfilemappingerror DB "failed to map file to memory", 0
G_szfileinvalidpe DB "Non"
G_szfilevalidpe DB "valid PE files", 0
G_sztmpfilesize DB "file length: % d bytes", 0
;. Data?
G_buffer512 dB 512 DUP (?)
G_dwvalidpe dd?
. Code
Start proc
MoV g_stofn.lstructsize, sizeof g_stofn
MoV g_stofn.lpstrfilter, offset g_szfilterstring
MoV g_stofn.lpstrfile, offset g_buffer512
MoV g_stofn.nmaxfile, 512
MoV g_stofn.flags, ofn_filemustexist or ofn_pathmustexist or ofn_longnames or ofn_explorer or ofn_hidereadonly
Invoke getopenfilename, ADDR g_stofn
. If eax = true
Invoke getpefilesize, offset g_buffer512
Invoke MessageBox, 0, eax, ADDR g_szappname, mb_ OK
. Endif
Invoke exitprocess, 0
Start endp
Getpefilesize proc lpszfilespec: lpstr
Local hfile, hmapping, pmapping: DWORD
Invoke createfile, lpszfilespec, 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
Invoke ispefilemap, eax
. If g_dwvalidpe = true
Invoke countpefilesize, pmapping
Invoke wsprintf, ADDR g_buffer512, ADDR g_sztmpfilesize, eax
; Invoke MessageBox, null, ADDR g_buffer512, ADDR g_buffer512, null
Push offset g_buffer512; g_szfilevalidpe
. Else
Push offset g_szfileinvalidpe
. Endif
. Else
Push offset g_szfilemappingerror
. Endif
Invoke closehandle, hmapping
. Else
Push offset g_szfileopenmappingerror
. Endif
Invoke closehandle, hfile
Pop eax
. Else
MoV eax, offset g_szfileopenerror
. Endif
RET
Getpefilesize endp
Ispefilemap proc pmapping: DWORD
If d_useseh EQ 1
Local seh: seh
Endif; d_useseh
MoV g_dwvalidpe, false
MoV EDI, pmapping
If d_useseh EQ 1
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
Endif; d_useseh
Assume EDI: PTR image_dos_header
. If [EDI]. e_magic = image_dos_signature
Add EDI, (image_dos_header PTR [EDI]). e_lfanew; add EDI, [EDI]. e_lfanew
Assume EDI: PTR image_nt_headers
. If [EDI]. Signature = image_nt_signature
MoV g_dwvalidpe, true
. Endif
. Endif
Finalexit:
RET
Ispefilemap endp
; Input: dwnumberofsections -- number of sections
; Psectiontabbeginaddr -- The begion address of the First Section Table
; Output: eax = all sections size
Countsectionsize proc dwnumberofsections: DWORD, psetabtabbeginaddr: DWORD
MoV EDI, dwnumberofsections
MoV ESI, psectiontabbeginaddr
XOR eax, eax
. While (EDI> 0)
Add eax, (image_section_header PTR [esi]). sizeofrawdata
Dec EDI
Add ESI, sizeof image_section_header
. Endw
RET
Countsectionsize endp
; Input: pmapping -- the pointer to PE file mapping
; Output: eax = File Size
Countpefilesize proc pmapping: handle
MoV EDI, pmapping
Add EDI, (image_dos_header PTR [EDI]). e_lfanew
Movzx eax, (image_nt_headers PTR [EDI]). fileheader. numberofsections
Test eax, eax
. If! Zero?
Push EDI
Add EDI, sizeof image_nt_headers
Invoke countsectionsize, eax, EDI
Pop EDI
. Endif
Add eax, (image_nt_headers PTR [EDI]). optionalheader. sizeofheaders
RET
Countpefilesize endp
If d_useseh EQ 1
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]. prevesp
Pop [eax]. regesp
Push [edX]. prevebp
Pop [eax]. regebp
MoV g_dwvalidpe, false
MoV eax, predictioncontinueexecution
RET
Sehhandler endp
Endif; d_useseh
End start