Display the first characters of an unsigned char* - c++

I have the following code (I stripped down the useless parts):
unsigned char* decrypted= (unsigned char *) malloc(500);
bufSize = operations.RSADecrypt(newEncrypted, bufSize, key, decrypted);
printf("Test: %s", decrypted);
And I would like to display only the bufSize first characters of decrypted because actually it displays a lot of nonsense characters!

You can use the "%.*s" format specifier:
printf("Test: %.*s", bufSize, decrypted);
which instructs printf() to write the first bufSize characters from decrypted.

You can limit the length with the format specifier:
printf ("Test: %-20.20s", decrypted);
For a version using a variable bufSize:
printf ("Test: %-*.*s", bufSize, bufSize, decrypted);
Note that this forces the length to exactly that many characters, padded with spaces on the right if need be. If you want a shorter string to be shorter in the output (irrelebant in your case if the string is, as indicated, always longer than what you want output), you can use:
printf ("Test: %.*s", bufSize, decrypted);

If you are 'allowed' to modify the decrypted string. You can simply add a terminator to it:
decrypted[bufSize] = 0;
So printf() will only print the buffer contents.
If you are not allowed to add a custom char to the decrypted buffer you need to copy the contents to a temporary buffer and use that buffer in your printf():
unsigned char* tmp = (unsigned char *) malloc(bufSize + 1);
strncpy(tmp, decrypted, bufSize);
tmp[bufSize] = 0;

I don't like that you said the pointer contained nonsense. Its not nonsense, its residual memory. There is a good chance you expect and want this area to be set to zero. Try the following, where calloc sets the malloc bits to zero.
unsigned char* decrypted= (unsigned char *) calloc(500,sizeof(char));
bufSize = operations.RSADecrypt(newEncrypted, bufSize, key, decrypted);
printf("Test: %s", decrypted);

Related

What causes the heap corruption in my method?

So I have tracked down an annoying heap corruption to a single method.
DWORD gdwCounter = 0;
TCHAR* GetName(const TCHAR* format, size_t len)
{
len += (snprintf(NULL, 0, "%lu", gdwCounter) * sizeof(TCHAR));
TCHAR *c = (TCHAR*)malloc(len);
_stprintf_s(c, len, __TEXT("%s%lu"), format, gdwCounter);
return c;
}
To make sure I found the correct method, I tried to change it and just copy the 'format' buffer it gets passed as an parameter to the output buffer. Heap corruption went away and everything was fine again.
I decided to look at the documentations of snprintf and _stprintf_s.
snprintf is supposed to return the required characters without the null-terminating character to actually print your buffer in a second call to it.
My len parameter already contains the full size (with null-terminating character) of format.
Also I couldn't find any hints to what is wrong in the documentation of _stprintf_s.
So what am I missing?
Edit: After further testing I found out that apparently _stprintf_s causes the error as snprintf does return the correct size.
TCHAR* GetName(const TCHAR* format, size_t len)
{
len += snprintf(NULL, 0, "%lu", gdwCounter);
TCHAR *c = (TCHAR*)malloc(len*sizeof(TCHAR));
_stprintf_s(c, len, __TEXT("%s%lu"), format, gdwCounter);
return c;
}
_stprintf_s takes the "Maximum number of characters to store" instead of maximum number of bytes.

Reading buffer C/C++

There is a function, I want to call
(void) get_bytes (void * ptr, int length)
function takes two arguments
the first is buffer (by that argument data will be recieved)
second length of the data that I want to read.
The task is to reading 10 bytes using this function, and print buffer on the screen (in the form of hexadecimal).
I tried this way
char *buffer = malloc(sizeof(char) * 10);
get_bytes (buffer, sizeof(buffer));
for (int i = 0; i < 10; i++) {
printf("%s", buffer[i]);
}
but I get exception of execution bad access on printf line,
Please provide a right way of passing buffer to this function
You probably meant to write
printf("%02x", (unsigned char)buffer[i]);
As is you are passing characters as addresses for strings which won't quite work.
get_bytes (buffer, sizeof(buffer)); isn't right... instead of sizeof(buffer) which returns the size of your char pointer, you want the size of what it's pointing to, 10 in this case.

Should recv() result must be equal to buffer length?

int resp = recv(s, buf, len, flags);
if(resp == 18) {
char data[18];
strcpy(data, buf);
...
}
I expect strlen(data) to be equal 18, but it isn`t. What did I miss?
If your data contains a zero-byte \0, then strlen will only give you the length of the string up to the terminator. If data does not have a terminator, then strlen will continue searching through whatever memory it happens to be at. This is commonly used in buffer overflow attacks.
I think what Joe is trying to say is your code isn't bullet-proof, starting with the number bytes read and copying the data into the data array.
int resp = recv(s, buf, len, flags);
if(resp > 0)
{
// ! This code assumse that all the data will fit into 18 bytes.
char data[18];
memset(data, 0, sizeof(data));
// ! As Joe warned above, this code assumes there's a null terminating
// ! character in the buf you received.
strcpy(data, buf); // consider memcpy if binary data (i.e. not strings)
}

OpenSSL AES decryption change size

I detoured recv function, i trying to decrypt buffer, but decrypt function change buffer size, and i think decryotion is invalid, code:
int WINAPI OwnRecv(SOCKET s, char FAR *buff, int len, int flags)
{
if(s == GameClientSocket)
{
int received = pTrampolineRecv(s, buff, len, flags);
if(received <= 0)
{
return received;
}
// now strlen(buff) is 2!!
char * plaintext;
plaintext = (char *)aes_decrypt(&Decrypt_Context, (unsigned char*)buff, &received);
(char *) buff = plaintext; // now strlen(buff) is 5!!
return received;
}
return pTrampolineRecv(s, buff, len, flags);
}
What's wrong with my code?
Thanks!
You forgot to implement a protocol! Whatever protocol you use to encrypt and decrypt the data, you have to actually implement it. It has to define block sizes, padding, and so on. It won't just work by magic. (Note that using a stream cipher will make this much easier than using a block cipher.)
Also, don't call strlen on arbitrary binary data! The strlen function is only for C-style strings.
Also, this line of code doesn't do what you think it does:
(char *) buff = plaintext; // now strlen(buff) is 5!!
Changing the value of buff, the variable that holds a pointer to the buffer, has no effect on the contents of the buffer. That's all the caller cares about.

Why does vsnwprintf not translate normal strings to wide strings?

The following code does not produce the expected output. Why?
wchar_t* wchar_t_printf_return(wchar_t* formatstring, ...){
va_list argp;
va_start(argp, formatstring);
int templen = 256;
templen = vsnwprintf(NULL, 0, formatstring, argp)+3;
wchar_t *buffer = (wchar_t *) malloc ((templen+1)*sizeof(wchar_t));
memset(buffer, 0, (templen+1)*sizeof(*buffer));
int retval;
while ((retval = vsnwprintf(buffer, templen, formatstring, argp)) == -1 || (retval >= (templen-1))){
templen = templen &lt&lt 1;
buffer = (wchar_t *) realloc (buffer, (templen+1)*sizeof(wchar_t));
va_end(argp);
va_start(argp, formatstring);
}
va_end(argp);
buffer[templen] = L'\0';
return buffer;
}
int main(){
int i;
char *id = "2923BE84E16CD6AE529049F1F1BBE9EB";
wchar_t *val = wchar_t_printf_return(L"'%s'", id);
printf("%ls\n", val);
}
EDIT: to state more specifically, the printf in main should wrap the id in two single quotes thereby outputting: '2923BE84E16CD6AE529049F1F1BBE9EB'. The purpose of the main here is to illustrate the bug in the function, no more. The function is supposed to be an alternate of the printf family functions which return the result in a newly allocated buffer instead of a preexisting one. This is being run in cygwin compiled natively via gcc-3 with the -mno-cygwin option (aka mingw). Sorry for the confusion!
The %s specifier changes meaning depending on whether you are using a printf or wprintf family function. When used with a wprintf family function, the %s specifier indicates a wide string, but you're passing a narrow string. You need %hs to say "This is a narrow string."
(You seemed to be aware of this because you use %ls to print a wide string with a printf-family function, but you somehow forgot about it when going the other way.)
Try using %S for a translation, not %s.