The Dynamic Allocation of Memory is a solution to do this.
But it can be slow.
Here is a solution for static buffer.
A macro (SECURE) create the needed data in .data and .data?.
A function (EcritTamp) replace lstrcpy and lstrcat in secure form.
It's not possible to made an Overrun with it.
;************* Avoiding Buffer Overruns ********************************
.const
SECURETAMPON STRUCT
ptampon dd ?
Tailletampon dd ?
decale dd ? ;si zero,ecrit en debut tampon
SECURETAMPON ENDS
LIMITE_TAMP equ 600h
;--------------- SECURE abuffer,db LIMITE_TAMP dup (?) ----------------------------------
SECURE MACRO nombuffer:REQ,quoted_text:VARARG
local declaretampon,declaredata
declaretampon CATSTR <nombuffer>,<_s >,<SECURETAMPON >,<<offset nombuffer,sizeof nombuffer,0>>
declaredata CATSTR <nombuffer>,< >,<quoted_text>
.data?
declaredata
.data
declaretampon
ENDM
.data
SECURE abuffer,db LIMITE_TAMP dup (?) ;create abuffer_s in data and abuffer in data?
;-------------- data to write ----------------
szinclude db "Include Myfile.txt",0
mot1 db " ;Just a sample to concatene text",0
retourligne db 13,10,0
OneBuffer_s SECURETAMPON <>
.code
;---------- write in the buffer ----------------------------------------
EcritTamp PROC uses esi edi ebx init:DWORD,psecuretamp:DWORD,psubchain:DWORD,lenchain:DWORD
Local taille:DWORD,retour
mov retour,0
mov ebx,psecuretamp
.if init == 1
mov [ebx].SECURETAMPON.decale,0 ;init
.elseif init == 2
;init tampon local,need lea to get it's adress
mov eax,psubchain ;utilisé pour passer l'adresse du tampon
mov [ebx].SECURETAMPON.ptampon,eax
mov eax,lenchain ;utilisé pour passer la taille du tampon
mov [ebx].SECURETAMPON.Tailletampon,eax
mov [ebx].SECURETAMPON.decale,0
.endif
.if lenchain == 0
invoke lstrlen,psubchain
.else
mov eax,lenchain
.endif
mov taille,eax
;----------------------------
mov ecx,[ebx].SECURETAMPON.decale
add ecx,taille
.if ecx < [ebx].SECURETAMPON.Tailletampon
mov edi,[ebx].SECURETAMPON.ptampon
add edi,[ebx].SECURETAMPON.decale
mov esi,psubchain
mov ecx,taille
and ecx,3
.if ecx != 0
rep movsb
.endif
mov ecx,taille
and ecx,0fffffffch
shr ecx,2 ;divise 4
.if ecx != 0
rep movsd
.endif
mov byte ptr [edi],0
mov eax,taille
add [ebx].SECURETAMPON.decale,eax
mov retour,1
.else
invoke MessageBox,NULL,psubchain,TXT("EcritTamp Overflow"),MB_OK
.endif
mov eax,retour
ret
EcritTamp ENDP
Protect_Local_Buffer PROC
Local OneBuffer[LIMITE_TAMP]:BYTE
;Couldn't use the macro here
;The OneBuffer_s must be declared in data : OneBuffer_s SECURETAMPON <>
;The parametre 2 init all
invoke EcritTamp,2,addr OneBuffer_s,addr OneBuffer,sizeof OneBuffer ;init
;.......
Protect_Local_Buffer ENDP
;----------------- usage ---------------------------------
start:
;----------------- Same usage as lstrcpy and lstrcat in secure form -------------
;1=Init task + copy
invoke EcritTamp,1,addr abuffer_s,addr szinclude,0 ;init +chercher la longueur
;0=add the chain to the tamp
invoke EcritTamp,0,addr abuffer_s,addr mot1,0
invoke EcritTamp,0,addr abuffer_s,addr retourligne,0
.if eax != 0 ;-- write operations are successfull
invoke MessageBox,NULL,addr abuffer,TXT("pragma"),MB_OK
mov retour,1
.endif
end start