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.
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
Ah, ok. I didn't use fci, fdi or ntstrsafe.
Now the code assembles and links fine but fails to start because it cannot find fci.dll or fdi.dll.
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)
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;
}
bf2,
these "safe" functions are just crap. You can easily substitute them with a memcpy dest, src, min(len(dest), len(src)).
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
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
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?
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.