News:

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

Main Menu

Safe string functions

Started by bf2, October 18, 2012, 08:25:44 PM

Previous topic - Next topic

bf2

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.

jj2007

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
   Init
   Let esi="This is a string"
   Let Mid$(esi, 9)="an attempt to overwrite the buffer"
   Inkey esi
   Exit
end start

bf2

Ah, ok. I didn't use fci, fdi or ntstrsafe.

bf2

Now the code assembles and links fine but fails to start because it cannot find fci.dll or fdi.dll.

TouEnMasm

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
Fa is a musical note to play with CL

TouEnMasm

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;
}

Fa is a musical note to play with CL

jj2007

bf2,

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

dedndave

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

jj2007

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


bf2

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?

TouEnMasm

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.
Fa is a musical note to play with CL