Can't delete an unsigned char* after inserting data - c++

I have this code
unsigned char _binary[] = {'1','1','1','0','0','0','1','0',NULL};
int length = 0;
for(length=0;_binary[length];length++);
unsigned char *_hexaActual = new unsigned char;
ConvertBinaryToHexaDecimal(_binary, length, _hexaActual);
string _actual((char*)_hexaActual);
delete[] _hexaActual; // crashes here
Now the ConvertBinaryToHexaDecimal is
void ConvertBinaryToHexaDecimal(const unsigned char* _inputBinary, unsigned int _intputLength, unsigned char* _outputHexaDecimal)
{
const unsigned char _hexaDecimalSymbols[16] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
char* _binary =(char*) malloc(sizeof(char));
int _binaryIndex,_inputIndex;
for(_binaryIndex=0; _binaryIndex < _intputLength%4 ;_binaryIndex++) // padding extra 0's to make the length multiple of 4
_binary[_binaryIndex] = '0';
for(_inputIndex=0; _inputIndex < _intputLength ;_inputIndex++)
_binary[_inputIndex + _binaryIndex] = _inputBinary[_inputIndex];
_binary[_inputIndex + _binaryIndex] = NULL;
_intputLength = _inputIndex + _binaryIndex;
for( _inputIndex=0; _inputIndex < _intputLength; _inputIndex +=4)
{
int _binaryValue = _binary[_inputIndex] - 48;
int _binaryValue1 = _binary[_inputIndex+1] - 48;
int _binaryValue2 = _binary[_inputIndex+2] - 48;
int _binaryValue3 = _binary[_inputIndex+3] - 48;
int _hexValue = _binaryValue3 * 1;
_hexValue += _binaryValue2 * 2;
_hexValue += _binaryValue1 * 4;
_hexValue += _binaryValue * 8;
_outputHexaDecimal[_inputIndex/4] = _hexaDecimalSymbols[_hexValue];
}
_outputHexaDecimal[_inputIndex/4] = NULL;
}
It outputs corretly a hexa decimal value. But when I try to delete it the program crashes.
EDIT: The crash message says HEAP CORRUPTION DETECTED.

You allocated a single unsigned char with new, so you should call delete, not delete []. The latter is for arrays allocated with new [].
You need
delete _hexaActual;
Note that this type of manual allocations and de-allocations are error prone and exception unsafe. It is likely that you can implement your code using standard library containers and algorithms.
Edit: besides that error, you have a few more: The most important one, in the function ConvertBinaryToHexaDecimal, you are passing a pointer to a single unsigned char, but you are treating it like an array:
_outputHexaDecimal[_inputIndex/4] = ....
Next, you hve a memory leak. You allocate here:
char* _binary =(char*) malloc(sizeof(char));
and never call free.

You only allocated one char for _hexaActual, but you are writing many values to it inside ConvertBinaryToHexaDecimal. You need allocate enough space for the characters you are going to put in there. length/4 + 2 should do it.
unsigned char *_hexaActual = new unsigned char[length/4 + 2];

Related

Error: Initialization with '{...}' expected for aggregate object

below is my code which processes the payload[] array and store it's result on myFinalShellcode[] array.
#include <windows.h>
#include <stdio.h>
unsigned char payload[] = { 0xf0,0xe8,0xc8,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31 };
constexpr int length = 891;
constexpr int number_of_chunks = 5;
constexpr int chunk_size = length / number_of_chunks;
constexpr int remaining_bytes = length % number_of_chunks;
constexpr int size_after = length * 2;
unsigned char* restore_original(unsigned char* high_ent_payload)
{
constexpr int payload_size = (size_after + 1) / 2;
unsigned char low_entropy_payload_holder[size_after] = { 0 };
memcpy_s(low_entropy_payload_holder, sizeof low_entropy_payload_holder, high_ent_payload, size_after);
unsigned char restored_payload[payload_size] = { 0 };
int offset_payload_after = 0;
int offset_payload = 0;
for (size_t i = 0; i < number_of_chunks; i++)
{
for (size_t j = 0; j < chunk_size; j++)
{
restored_payload[offset_payload] = low_entropy_payload_holder[offset_payload_after];
offset_payload_after++;
offset_payload++;
}
for (size_t k = 0; k < chunk_size; k++)
{
offset_payload_after++;
}
}
if (remaining_bytes)
{
for (size_t i = 0; i < sizeof remaining_bytes; i++)
{
restored_payload[offset_payload++] = high_ent_payload[offset_payload_after++];
}
}
return restored_payload;
}
int main() {
unsigned char shellcode[] = restore_original(payload);
}
I get the following error on the last code line (inside main function):
Error: Initialization with '{...}' expected for aggregate object
I tried to change anything on the array itself (seems like they might be the problem). I would highly appreciate your help as this is a part of my personal research :)
In order to initialize an array defined with [], you must supply a list of values enclosed with {}, exactly as the error message says.
E.g.:
unsigned char shellcode[] = {1,2,3};
You can change shellcode to be a pointer if you want to assign it the output from restore_original:
unsigned char* shellcode = restore_original(payload);
Update:
As you can see in #heapunderrun's comment, there is another problem in your code. restore_original returns a pointer to a local variable, which is not valid when the function returns (a dangling pointer).
In order to fix this, restore_original should allocate memory on the heap using new. This allocation has to be freed eventually, when you are done with shellcode.
However - although you can make it work this way, I highly recomend you to use std::vector for dynamic arrays allocated on the heap. It will save you the need to manually manage the memory allocations/deallocations, as well as other advantages.
You can't assign a char * to a char []. You can probably do something with constexpr but I'm suspecting an XY problem here.

c (arduino) misc function returning char pointer

i found function in some code. Looks like that function generates some random number with variable length and returns char*
char* result = (char*)malloc(sizeof(char)*length);
randomSeed(analogRead(A0));
for (int i = 0; i < length; ++i)
{
result[i] = 48 + random(9);
}
result[length] = '\0';
When i tested it, i was surprised that this code works
But in theory char* is read only data, so this accessing to the elements should be incorrect.
Could someone explain it to me?
I think it will be better that the creator will use char array and then copy that memory to the char*
(i do not have link to code)
first of all your code does not work. You write outside the array in this line
result[length] = '\0';
the code shuold look like:
for (int i = 0; i < length - 1; ++i)
{
result[i] = 48 + random(9);
}
result[length - 1] = '\0';
char is just an integer type and it can be read or written.
if you want make it not writable (at least from the C++ point of view) you need to declare it as const.
const char a;
const char *ptr1;
char * const ptr2;
const char * const ptr3;
where:
ptr1 is a pointer to const char
ptr2 is a const pointer to char
ptr2 is a const pointer to const char

Generate random char/digit

I`m trying to found fastest way to generate random digit/char array.
char *randomGet(int num) {
srand(time(NULL));
const char ab[37] = { "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ" };//Alphabet&Digit
char *targ = new char[num];
for (int i = 0; i < num; i++) {
strcat(targ, ab[rand() % 38]);
}
return targ;
}
So far I've come up with this, but it does not work (argument of type char is incompatible with parameter of type const char *).
Help me find the best solution to my problem. Ty.
strcat() takes a char* as input, but you are giving it a single char instead, thus the compiler error.
Also, the buffer that strcat() writes to must be null terminated, but your targ buffer is not null terminated initially, and you are not allocating enough space for a final null terminator anyway.
You don't need to use strcat() at all. Since you are looping anyway, just use the loop counter as the index where to write in the buffer:
Also, you are using the wrong integer value when modulo the return value of rand(). You are producing a random index that may go out of bounds of your ab[] array.
Try this instead:
char *randomGet(int num)
{
srand(time(NULL));
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ"; //Alphabet&Digit
char *targ = new char[num+1];
for (int i = 0; i < num; ++i) {
targ[i] = ab[rand() % 36];
}
targ[num] = '\0';
return targ;
}
I'd make two changes. First, make the internal source array static:
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
Note that this version does not specify the array size; the compiler will figure it out from the initializer.
Second, pass in a pointer to the target array:
void randomGet(char* targ, int num) {
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
for (int i = 0; i < num - 1; ++i)
targ[i] = ab[rand() % (sizeof ab - 1)];
targ[num - 1] = '\0';
}
This way, the caller decides how to allocate memory for the string.

How to set quantity of elements of the char array of a variable

How to set quantity of elements of the char array of a variable?
This is my code:
long int len = strlen(qq);
//char buff[10];
//sprintf(buff, "%d", len);
//MessageBoxA(0,buff,0,0);
char key[len] = "12345678901234567890123456789..";//error
char crypt[len];//error
for (int i = 0; i < len; i++) {
crypt[i] = text[i] ^ key[i];
}
In C++ an array can only be staticly sized using a constant variable that is known at compile time, which your len is not. Note that some compiler extensions DO allow this, as it's allowed in C. But for pure C++ you instead can use dynamic memory allocation (this allocates on the heap instead of the stack):
char* key = new char[len];
char* crypt = new char[len];
Note that a char* can be used the same as a char[] (you can still use array indexing, the rest of your code remains unchanged).
Because the array is now allocated on the heap, to avoid memory leaks you must manually free the memory when you no longer need it using delete e.g. at the end of the function after you loop:
delete[] key;
delete[] crypt;
Since you specified the winapi tag, it may be that the CString class would be a viable solution.
For your key though, you don't even need to allocate an array dynamically. You could use the modulo operator:
static const char key[] = "1234567890";
const size_t keyLength = strlen(key);
CString crypt(0, len);
for (int i = 0; i < len; i++) {
crypt[i] = text[i] ^ key[i & keyLength];
}

Flaws in algorithm and algorithm performance

char *stringmult(int n)
{
char *x = "hello ";
for (int i=0; i<n; ++i)
{
char *y = new char[strlen(x) * 2];
strcpy(y,x);
strcat(y,x);
delete[] x;
x=y;
}
return x;
}
I'm trying to figure out what the flaws of this segment is. For one, it deletes x and then tries to copy it's values over to y. Another is that y is twice the size of x and that y never gets deleted. Is there anything that I'm missing? And also, I need to figure out how to get algorithm performance. If you've got a quick link where you learned how, I'd appreciate it.
y needs one more byte than strlen(x) * 2 to make space for the terminating nul character -- just for starters.
Anyway, as you're returning a newed memory area, it's up to the caller to delete it (eek).
What you're missing, it seems to me, is std::string...!-)
As for performance, copying N characters with strcpy is O(N); concatenating N1 characters to a char array with a previous strlen of N2 is O(N1+N2) (std::string is faster as it keeps the length of the string in an O(1)-accessible attribute!-). So just sum N+N**2 for N up to whatever your limit of interest is (you can ignore the N+ part if all you want is a big-O estimate since it's clearly going to drop away for larger and larger values of N!-).
For starters delete[] x; operates for the first time round the loop on some static memory. Not good.
It looks like an attempt to return a buffer containing 2^n copies of the string "hello ". So the fastest way to do that would be to figure out the number of copies, then allocate a big enough buffer for the whole result, then fill it with the content and return it.
void repeat_string(const std::string &str, int count, std::vector<char> &result)
{
result.resize(str.size() * count);
for (int n = 0; n < count; n++)
str.copy(&result[n * s.size()], s.size());
}
void foo(int power, std::vector<char> &result)
{
repeat_string("hello ", 1 << (power + 1), result);
}
no need to call strlen() in a loop - only call it once;
when new is called no space is requested for the null-character - will cause undefined behaviour;
should use strcpy instead of strcat - you already know where to copy the second string and findig the end of string by strcat requires extra computation;
delete[] is used on a statically allocated string literal - will cause undefined behaviour;
memory is constantly reallocated although you know the result length well in advance - memory reallocation is quite expensive
You should instead compute the result length at once and allocate memory at once and pass the char* as an in-parameter:
char* stringMult(const char* what, int n)
{
const size_t sourceLen = strlen( what );
int i;
size_t resultLen = sourceLen;
// this computation can be done more cleverly and faster
for( i = 0; i < n; i++ ) {
resultLen *= 2;
}
const int numberOfCopies = resultLen / sourceLen;
char* result = new char[resultLen + 1];
char* whereToWrite = result;
for( i = 0; i < numberOfCopies; i++ ) {
strcpy( whereToWrite, what );
whereToWrite += sourceLen;
}
return result;
}
Certain parts of my implementation can be optimized but still it is much better and (I hope) contains no undefined-behaviour class errors.
you have to add one while allocating space for Y for NULL terminating string
Check the code at below location http://codepad.org/tkGhuUDn
char * stringmult (int n)
{
int i;
size_t m;
for (i = 0, m = 1; i < n; ++i; m *= 2);
char * source = "hello ";
int source_len = strlen(source);
char * target = malloc(source_len*m+1) * sizeof(char));
char * tmp = target;
for (i = 0; i < m; ++i) {
strcpy(tmp, source);
tmp += source_len;
}
*tmp = '\0';
return target;
}
Here a better version in plain C. Most of the drawbacks of your code have been eliminated, i.e. deleting a non-allocated pointer, too many uses of strlen and new.
Nonetheless, my version may imply the same memory leak as your version, as the caller is responsible to free the string afterwards.
Edit: corrected my code, thanks to sharptooth.
char* string_mult(int n)
{
const char* x = "hello ";
char* y;
int i;
for (i = 0; i < n; i++)
{
if ( i == 0)
{
y = (char*) malloc(strlen(x)*sizeof(char));
strcpy(y, x);
}
else
{
y = (char*)realloc(y, strlen(x)*(i+1));
strcat(y, x);
}
}
return y;
}
Nobody is going to point out that "y" is in fact being deleted?
Not even one reference to Schlmeiel the Painter?
But the first thing I'd do with this algorithm is:
int l = strlen(x);
int log2l = 0;
int log2n = 0;
int ncopy = n;
while (log2l++, l >>= 1);
while (log2n++, n >>= 1);
if (log2l+log2n >= 8*(sizeof(void*)-1)) {
cout << "don't even bother trying, you'll run out of virtual memory first";
}