The MASM Forum

General => The Campus => Topic started by: bf2 on October 18, 2012, 08:25:44 PM

Title: Safe string functions
Post by: bf2 on October 18, 2012, 08:25:44 PM
Hello, question on safe string functions:

Where are the prototypes of functions like StringCchCopy, StringCbCopy, strcpy_s, etc? They don't seem to be included in MASM32 because I can't assemble my code.

What alternatives to lstrcpy are included in the MASM32 package?

Thanks.
Title: Re: Safe string functions
Post by: jj2007 on October 18, 2012, 09:25:21 PM
Some are missing indeed, but at least StringCchCopy works:

include \masm32\include\masm32rt.inc
uselib fci
uselib fdi
uselib ntstrsafe

.code
AppName   db "Masm32:", 0

start:   MsgBox 0, "Hello World", addr AppName, MB_OK
   exit


   call  StringCchCopy
;   call StringCbCopy
;   call strcpy_s

end start

Otherwise, there are fairly safe libraries around ;-)
include \masm32\MasmBasic\MasmBasic.inc   ; download (http://masm32.com/board/index.php?topic=94.0)
   Init
   Let esi="This is a string"
   Let Mid$(esi, 9)="an attempt to overwrite the buffer"
   Inkey esi
   Exit
end start
Title: Re: Safe string functions
Post by: bf2 on October 18, 2012, 10:55:56 PM
Ah, ok. I didn't use fci, fdi or ntstrsafe.
Title: Re: Safe string functions
Post by: bf2 on October 19, 2012, 12:13:46 AM
Now the code assembles and links fine but fails to start because it cannot find fci.dll or fdi.dll.
Title: Re: Safe string functions
Post by: TouEnMasm on October 19, 2012, 12:40:25 AM
The strsafe functions are very complex in there constructions.
Some parts are in the windows sdk header's files.
Some others part are on the lib.
And all strsafe.lib are not the same.
A lib of them must be done with the c++ to made them more usable with masm.
The crt offer an equivalent fonction who can also print floating point number.
Before searching for those parts,try to use sprintf_s .
see
http://masm32.com/board/index.php?topic=581.msg4738#msg4738 (http://masm32.com/board/index.php?topic=581.msg4738#msg4738)
Title: Re: Safe string functions
Post by: TouEnMasm on October 19, 2012, 12:49:06 AM
The Two functions you search can be found in strsafe.h

STRSAFEAPI
StringCbCopyA(
    __out_bcount(cbDest) STRSAFE_LPSTR pszDest,
    __in size_t cbDest,
    __in STRSAFE_LPCSTR pszSrc)
{
    HRESULT hr;
    size_t cchDest = cbDest / sizeof(char);

    hr = StringValidateDestA(pszDest, cchDest, STRSAFE_MAX_CCH);

    if (SUCCEEDED(hr))
    {
        hr = StringCopyWorkerA(pszDest,
                               cchDest,
                               NULL,
                               pszSrc,
                               STRSAFE_MAX_LENGTH);
    }

    return hr;
}

Title: Re: Safe string functions
Post by: jj2007 on October 19, 2012, 02:20:28 AM
bf2,

these "safe" functions are just crap. You can easily substitute them with a memcpy dest, src, min(len(dest), len(src)).
Title: Re: Safe string functions
Post by: dedndave on October 19, 2012, 04:16:41 AM
as Jochen mentioned, the safe string functions are slow

also, they are intended to be used in higher-level languages
in assembler, we generally take responsibility to ensure that buffers are not overflowed
in other words, we check lengths and buffer sizes and write the code so that overflow can't occur
that makes the safe string functions somewhat useless, and that's why you don't see us using them
Title: Re: Safe string functions
Post by: jj2007 on October 19, 2012, 07:50:42 AM
If you are really unhappy with the unsafe string copy algos that are around, here is a complete testbed :biggrin:

include \masm32\include\masm32rt.inc

.data?
MyBuffer   db 40 dup(?)
DoNotOverWriteMe   dd ?

.code
SafeStrCopy proc uses esi edi dest, src, maxbytes
  mov edi, dest
  mov esi, src
  mov edx, maxbytes
  add edx, edi
  align 4
  .Repeat
   lodsb
   stosb
  .Until !al || edi>=edx
  sub edx, edi
  xchg eax, edx
  mov byte ptr [edi-1], 0
  ret
SafeStrCopy endp

start:   mov DoNotOverWriteMe, 123456789
   push rv(GetTickCount)
   mov ecx, 10000000
   .Repeat
      invoke SafeStrCopy, offset MyBuffer, chr$("Now let's test if we can trigger a buffer overflow"), sizeof MyBuffer
      dec ecx
   .Until Sign?
   xchg eax, ebx
   call GetTickCount
   pop edx
   sub eax, edx
   print str$(eax), 9, "milliseconds for ten Million safe copies", 13, 10
   xchg eax, ebx
   print str$(eax), 9, "bytes free, result=["
   print offset MyBuffer, "]", 13, 10
   invoke SafeStrCopy, offset MyBuffer, chr$("This one is shorter, it fits"), sizeof MyBuffer
   print str$(eax), 9, "bytes free, result=["
   print offset MyBuffer, "]", 13, 10
   inkey str$(DoNotOverWriteMe), " was not overwritten"
   exit
end start

Output:

1187    milliseconds for ten Million safe copies
0       bytes free, result=[Now let's test if we can trigger a buff]
11      bytes free, result=[This one is shorter, it fits]
123456789 was not overwritten

Title: Re: Safe string functions
Post by: bf2 on October 19, 2012, 11:33:40 PM
Quote from: jj2007 on October 19, 2012, 02:20:28 AM
bf2,

these "safe" functions are just crap. You can easily substitute them with a memcpy dest, src, min(len(dest), len(src)).

Thanks. I like the memcpy suggestion. Nice, clean and easy.

Any idea why it's included as _imp__memcpy and crt_memcpy and not as simple memcpy?
Title: Re: Safe string functions
Post by: TouEnMasm on October 19, 2012, 11:55:21 PM
Quote
Any idea why it's included as _imp__memcpy and crt_memcpy and not as simple memcpy
These two functions are crt functions
The normal way to use them is to translate the c++ prototypes for masm and to link to the msvcrt.lib (that is the way I follow with  a static or dynamic link).
These need three thinks.
The translate of the vc++ header and the link.The masm32 package hadn't this.
Third,the vc++ express to have the librariesThe masm32 had choosen an other part and create his own library.
To solve conflicts of names,he had renamed all the function.
(a dynamic link is a better soluce to solve them)
The method had some inconvenients.You can't mix this lib with a c++ prog who use the crt (You can find some c++ codes who don't use it).
The crt is a part of the system and be incompatible with it offer many problems.