News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Secure reading function

Started by Grincheux, December 16, 2015, 04:26:10 AM

Previous topic - Next topic

Grincheux

There was something important that was missing. You read a file, ok, but how long is the buffer?
Now you pass the address of a DWORD into which the file size (which also is the buffer size - 256) is returned.
The pointer is initialized to zero at the function entry.


New version (7zip file)


NO VIRUS FOUND INTO THIS FILE

Analyze link

TouEnMasm

ReadFile PROTO hFile:HANDLE ,lpBuffer:XMASM ,nNumberOfBytesToRead:DWORD ,lpNumberOfBytesRead:XMASM ,lpOverlapped:XMASM

use the lpNumberOfBytesRead to get the answer and made a verify all is well done
substract this number to the size of the buffer and you have the rest of memory
Fa is a musical note to play with CL

Grincheux

INVOKE ReadFile,_FileHandle,eax,_dwFileSize,edx,NULL

test eax,eax
jz @Error_03

mov eax,_dwFileSize

sub eax,_dwTmp ; If the number of bytes read is not equal
jnz @Error_03 ; to the number of bytes to read => ERROR

mov eax,__lpdwFileSize
mov edx,_dwFileSize
mov DWord Ptr [eax],edx

INVOKE CloseHandle,_FileHandle

mov eax,_lpMemory
ret


That's what I do

TWell

Do you mean allocated buffer?
HeapSize()?

Grincheux

It's the size of the file.
The size of the allocated buffer is equal to the size of the file plus 256 bytes.

TouEnMasm

It's unclear.
Wich size do you search ??????????
Fa is a musical note to play with CL

Grincheux


hutch--

Philippe,

The normal sequence is you open a file, get its length, allocate a buffer that is large enough then read the file into the buffer.

Just look up the foillowing in the "macros.asm" file in MASM32 and you will find all of the useful API functions for doing file IO. Look for this in the macros file,

  ; **************
  ; File IO Macros
  ; **************

TouEnMasm

I use this one since a certain time:
comments are in french


;   le batch pour batir une librairie
;batch,sources et .inc (contenant les proto)
FichMem    struc
               Hmem     dd ?
               Mpoint   dd ?
               Taille   dd ?
        FichMem    ends

; #########################################################################

      .386                      ; force 32 bit code
      .model flat, stdcall      ; memory model & calling convention
      option casemap :none      ; case sensitive
      ; --------------------------------
      ; Les fichiers inclus içi
      ; --------------------------------
       include \masm32\include\windows.inc
       include \masm32\include\kernel32.inc
       include \masm32\include\user32.inc
        include macros.txt

      ; ---------------------------------------------------------
      ; Les PROTO sont tous regroupés dans un fichier .inc du même
      ; nom que la librairie .lib
      ; ---------------------------------------------------------

.data
ercharge db "Taille ",0
texthou db " Handle fichier ",0
textHmem db "Handle memoire ",0
textPm db "Pointeur memoire ",0
textlu db " Nb octets en lecture ",0
InfosFiles WIN32_FIND_DATA <>

    .code
;################################################################
;----------- pushad popad -----------------
LoadFile proc uses ebx NomAediter:DWORD,PileMem:DWORD
LOCAL retour:DWORD
LOCAL fichier:DWORD
local hMemory:DWORD
local pMemory:DWORD
local hFile:DWORD
local NbOctetsaLire:DWORD
local NbOctetsLus:DWORD

          ;pilemem adresse d'une structure FichMem
   ;rajoute un zero en fin de fichier
   ;nécessaire dans les copies avec clipboard par exemple
   ;utilise  WIN32_FIND_DATA et NomComplet

;FichMem    struc
; Hmem     dd ?
; Mpoint   dd ?
; Taille   dd ?
;FichMem    ends

mov ebx,PileMem
          invoke RtlZeroMemory,addr InfosFiles,sizeof InfosFiles
          invoke FindFirstFile,NomAediter,addr InfosFiles

          ;----------------------------------------------------------
          ; taille du fichier nFileSizeHigh; DWORD    nFileSizeLow WIN32_FIND_DATA
          ;   nom court ou nom long sans chemin ?         
          ;-----------------------------------------------------------
         
          .if eax==INVALID_HANDLE_VALUE
               mov retour,0         
       jmp FindeLoadFile
   .else
    mov edx,eax
          invoke FindClose,edx
               mov retour,1    
          .endif
         ;------------------------------------------------------         
         ; on connait maintenant toutes les infos sur le fichier         
         ;-------------------------------------------------------


;----------------------------
;  ouvrir le fichier
;----------------------------
        invoke CreateFile,NomAediter,GENERIC_READ,NULL,\
                        NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax==INVALID_HANDLE_VALUE
;invoke  MessageBox,NULL,SADD(" Erreur d'ouverture Fichier "),\
; SADD("LoadFile"),MB_OK
mov retour,0
jmp FindeLoadFile
.endif
mov hFile,eax

;-------------------------
;obtenir le handle de mémoire, taille du fichier dw
;-------------------------
mov ecx,InfosFiles.nFileSizeLow
mov dword ptr (FichMem ptr [ebx]).Taille,ecx
inc ecx ;pour rajouter le zero en fin de fichier
add ecx,32 ;mmx utilise des registres de 16 bytes
and ecx,0FFFFFFF0h ;rounded 16 bytes upper
invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,ecx

.if eax == 0
;invoke  MessageBox,NULL,SADD("Pas assez de place mémoire "),\
; SADD("GlobalAlloc"),MB_OK
mov retour,0
jmp FindeLoadFile
.endif           
mov  hMemory,eax
mov dword ptr (FichMem ptr [ebx]).Hmem,eax
;obtenir le pointeur de memoire
invoke GlobalLock,hMemory
mov  pMemory,eax
mov dword ptr (FichMem ptr [ebx]).Mpoint,eax

mov eax,InfosFiles.nFileSizeLow 
mov NbOctetsaLire,eax
invoke ReadFile,hFile,pMemory,NbOctetsaLire,addr NbOctetsLus,NULL

;-------------------------
;libéré la memoire ,fermé le fichier ouvert
;-------------------------
; invoke GlobalUnlock,pMemory
; invoke GlobalFree,hMemory
invoke CloseHandle,hFile
mov retour,1

FindeLoadFile:
mov eax,retour
ret
           

LoadFile endp

;#########################################################################


end

Fa is a musical note to play with CL

Grincheux

I think there is a mistake. Into one of my post I told that I had forgotten the file size. If the buffer needed to be written I did know its size. But I had the information because I call "GetFileSize" function.


I put the entire source code. You can download it here
I appreciate any comment and speed tests. I don't know how to measure how fast/slow the functions are.

.686p                     ; create 32 bit code
.MMX                      ; enable MMX instructions
.XMM                      ; enable SSE instructions
.NOCREF
OPTION casemap :none      ; case sensitive

; -------------------------------------------------------------------------------------------------------------
.Code
; -------------------------------------------------------------------------------------------------------------

; ==================================================================================
ALIGN 4
; ==================================================================================

; ReadWholeFile : INPUT PARAMETER : A pointer on the file name to be read.
; RETURNED VALUE : A pointer on the allocated memory block
; Or NULL if there was an error.

; The memory block must be free by the caller usif HeapFree
; The input file is opened for reading.
; During the read operation all access to the file will fail because there is no share.
; The file must not be empty and its size must be in the range 0...FFFFFFFFh

; Memory allocated size : File size + 256 bytes
; When the fuction returns the input file is closed even if there was an error
; Modified registers : ALL except EBX, EDI and ESI which are not used.

ReadWholeFile PROC __lpszFileName:LPSTR
LOCAL _lpMemory:LPBYTE ; The adress of the returned memory block
LOCAL _FileHandle:HANDLE ; The file handle
LOCAL _dwFileSize:DWORD ; Low part of the file size
LOCAL _dwTmp:DWORD ; Temporary variable

INVOKE PathFileExists,__lpszFileName

test eax,eax ; File does not exist
jz @Error_01

INVOKE CreateFile,__lpszFileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL

cmp eax,INVALID_HANDLE_VALUE ; Can't open the file
je @Error_01

lea edx,_dwTmp
mov _FileHandle,eax

INVOKE GetFileSize,eax,edx

cmp eax,INVALID_FILE_SIZE
je @Error_02

cmp _dwTmp,0
jne @Error_02 ; File is too big

or eax,eax
jz @Error_02 ; File is empty

mov _dwFileSize,eax

add eax,256 ; File size + 256
push eax
push HEAP_ZERO_MEMORY ; Memory initialyzed with '0'
call GetProcessHeap
push eax
call HeapAlloc

test eax,eax ; Memory allocation failed?
je @Error_02

mov _lpMemory,eax
lea edx,_dwTmp

INVOKE ReadFile,_FileHandle,eax,_dwFileSize,edx,NULL

test eax,eax
jz @Error_03

mov eax,_dwFileSize

sub eax,_dwTmp ; If the number of bytes read is not equal
jnz @Error_03 ; to the number of bytes to read => ERROR

@EndOfFile :

INVOKE CloseHandle,_FileHandle

mov eax,_lpMemory
ret

; **********************************************************************************
ALIGN 4
; **********************************************************************************

@Error_03 :

call GetProcessHeap

push _lpMemory
push 0
push eax
push OFFSET @Error_02
jmp HeapFree

; **********************************************************************************
ALIGN 4
; **********************************************************************************

@Error_02 :

push _FileHandle
push OFFSET @Error_01
jmp CloseHandle

; **********************************************************************************
ALIGN 4
; **********************************************************************************

@Error_01 :

xor eax,eax
ret
ReadWholeFile ENDP

; ==================================================================================
ALIGN 4
; ==================================================================================

File_Read PROC __FileHandle:HANDLE,__lpBuffer:LPBYTE,__dwNumberOfBytesToRead:DWord,__lpdwFlag:PTR DWord
LOCAL _dwTmp:DWORD

lea edx,_dwTmp

INVOKE ReadFile,__FileHandle,__lpBuffer,__dwNumberOfBytesToRead,edx,NULL

test eax,eax
jz @Error_01

cmp _dwTmp,0
je @EndOfFile

mov eax,__dwNumberOfBytesToRead

sub eax,_dwTmp
jnz @Error_01

@EndOfFile : ; EOF detected

mov eax,__lpdwFlag
mov edx,_dwTmp
mov DWord Ptr [eax],edx ; NO ERROR - Returns the number of bytes read

mov eax,__lpBuffer

ret

; **********************************************************************************
ALIGN 4
; **********************************************************************************

@Error_01 :

mov eax,__lpdwFlag
mov DWord Ptr [eax],-1 ; ERROR WHILE READING

xor eax,eax
ret
File_Read ENDP