I am maintaining a multimap to store pointer variables, code compiles fine but throws exception. please review my code below and provide suggestion
multimap<const char*, int **> myMap1;
int *myVals = new int[3];
myVals[0] = 1;
myVals[1] = 1;
myVals[2] = 1;
myMap1.insert(pair<const char*, int **>("val1", &myVals));
std::multimap<const char*, int **>::iterator it = myMap1.find("val1");
int *storedVals = reinterpret_cast<int *>(it->second);
for(int ii = 0; ii< 2; ii++)
{
printf("\n Value %d", storedVals[ii]); //Exception thrown here..
}
delete myVals;
You should update your code as below, and refer to this link if you wanna know why.
multimap<const char*, int **> myMap1;
int *myVals = new int[3];
myVals[0] = 1;
myVals[1] = 1;
myVals[2] = 1;
char * temp = "val1";
myMap1.insert(pair<const char*, int **>(temp, &myVals));
std::multimap<const char*, int **>::iterator it = myMap1.find(temp);
int *storedVals = *(it->second);
for(int ii = 0; ii<= 2; ii++)
{
printf("\n Value %d", storedVals[ii]); //Exception thrown here..
}
delete [] myVals;
Also prefer to use auto it for iterators instead of std::multimap<const char*, int **>::iterator it. Also you cant use 'reinterpret_cast' here.
I am not sure of the reason why you are using a reinterpret_cast here:
Your value (second) in the map is holding a pointer to a int*
If you change this line with the following. It would work:
int *storedVals = *(it->second); //it->second is a int**
Also you should not do myVals[2] = 1; your array size is 2. Alternatively you can increase the size of your array to 3.
Related
I have
int some_var = 5;
int* ref_on_var = &a;
char arr[8];
char* to_write = reinterpret_cast<char*>(&ref_on_var);
I want to write ref_on_var to arr so i write this
for(size_t i = 0; i < sizeof(int*); ++i)
{
arr[i] = to_write[i];
}
This writes some bytes to array but when I try to get pointer back by
int* get = reinterpret_cast<int*>(arr);
I get incorrect address.
So what do I do wrong?
arr
This evaluates to a pointer to arr, that's the result of using the name of an array in a C++ expression.
This char buffer contains an int *, therefore this must be an int **. So:
int* get = *reinterpret_cast<int**>(arr);
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.
I have made struct and now I need to create an array for the corresponding struct. Could anyone help me how to go about that? I have looked at stuff online and couldn't really understand it, so could anyone give me an example and explanation on how to create an array of a struct.
struct CANDIDATE{
string candiFN;
string candiLN;
int partyID;
int votes;
};
The same way you make any array. The following makes an array of length 5.
CANDIDATE foo [5];
Then you can fill it however you'd like
for (unsigned int i = 0; i < 5; ++i)
{
CANDIDATE temp("first", "second", 1, 2);
foo[i] = temp;
}
Or
for (unsigned int i = 0; i < 5; ++i)
{
CANDIDATE temp;
temp.candiFN = "first";
temp.candiLN = "second";
temp.partyID = 1;
temp.votes = 2;
foo[i] = temp;
}
Note that in C++ using a std::vector introduces more safety and flexibility to most applications.
std::vector<CANDIDATE> bar;
for (unsigned int i = 0; i < 5; ++i)
{
CANDIDATE temp("first", "second", 1, 2);
bar.push_back(temp);
}
You can simply do this:
struct CANDIDATE{
string candiFN;
string candiLN;
int partyID;
int votes;
}array[5];
//just add an array between } and ;
You can make an array of values
CANDIDATE foo[5];
or a pointer array
CANDIDATE* foo = new CANDIDATE[5];
The first goes in the stack, the second in the heap and need manual delete
Anyway consider of use std::vector
Ok, so I'm quite new to C++ and I'm sure this question is already answered somewhere, and also is quite simple, but I can't seem to find the answer....
I have a custom array class, which I am using just as an exercise to try and get the hang of how things work which is defined as follows:
Header:
class Array {
private:
// Private variables
unsigned int mCapacity;
unsigned int mLength;
void **mData;
public:
// Public constructor/destructor
Array(unsigned int initialCapacity = 10);
// Public methods
void addObject(void *obj);
void removeObject(void *obj);
void *objectAtIndex(unsigned int index);
void *operator[](unsigned int index);
int indexOfObject(void *obj);
unsigned int getSize();
};
}
Implementation:
GG::Array::Array(unsigned int initialCapacity) : mCapacity(initialCapacity) {
// Allocate a buffer that is the required size
mData = new void*[initialCapacity];
// Set the length to 0
mLength = 0;
}
void GG::Array::addObject(void *obj) {
// Check if there is space for the new object on the end of the array
if (mLength == mCapacity) {
// There is not enough space so create a large array
unsigned int newCapacity = mCapacity + 10;
void **newArray = new void*[newCapacity];
mCapacity = newCapacity;
// Copy over the data from the old array
for (unsigned int i = 0; i < mLength; i++) {
newArray[i] = mData[i];
}
// Delete the old array
delete[] mData;
// Set the new array as mData
mData = newArray;
}
// Now insert the object at the end of the array
mData[mLength] = obj;
mLength++;
}
void GG::Array::removeObject(void *obj) {
// Attempt to find the object in the array
int index = this->indexOfObject(obj);
if (index >= 0) {
// Remove the object
mData[index] = nullptr;
// Move any object after it down in the array
for (unsigned int i = index + 1; i < mLength; i++) {
mData[i - 1] = mData[i];
}
// Decrement the length of the array
mLength--;
}
}
void *GG::Array::objectAtIndex(unsigned int index) {
if (index < mLength) return mData[index];
return nullptr;
}
void *GG::Array::operator[](unsigned int index) {
return this->objectAtIndex(index);
}
int GG::Array::indexOfObject(void *obj) {
// Iterate through the array and try to find the object
for (int i = 0; i < mLength; i++) {
if (mData[i] == obj) return i;
}
return -1;
}
unsigned int GG::Array::getSize() {
return mLength;
}
I'm trying to create an array of pointers to integers, a simplified version of this is as follows:
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
Now the problem is that the same pointer is used for j in every iteration. So after the loop:
array[0] == array[1] == array[2];
I'm sure that this is expected behaviour, but it isn't quite what I want to happen, I want an array of different pointers to different ints. If anyone could point me in the right direction here it would be greatly appreciated! :) (I'm clearly misunderstanding how to use pointers!)
P.s. Thanks everyone for your responses. I have accepted the one that solved the problem that I was having!
I'm guessing you mean:
array[i] = &j;
In which case you're storing a pointer to a temporary. On each loop repitition j is allocated in the stack address on the stack, so &j yeilds the same value. Even if you were getting back different addresses your code would cause problems down the line as you're storing a pointer to a temporary.
Also, why use a void* array. If you actually just want 3 unique integers then just do:
std::vector<int> array(3);
It's much more C++'esque and removes all manner of bugs.
First of all this does not allocate an array of pointers to int
void *array = new void*[2];
It allocates an array of pointers to void.
You may not dereference a pointer to void as type void is incomplete type, It has an empty set of values. So this code is invalid
array[i] = *j;
And moreover instead of *j shall be &j Though in this case pointers have invalid values because would point memory that was destroyed because j is a local variable.
The loop is also wrong. Instead of
for (int i = 0; i < 3; i++) {
there should be
for (int i = 0; i < 2; i++) {
What you want is the following
int **array = new int *[2];
for ( int i = 0; i < 2; i++ )
{
int j = i + 1;
array[i] = new int( j );
}
And you can output objects it points to
for ( int i = 0; i < 2; i++ )
{
std::cout << *array[i] << std::endl;
}
To delete the pointers you can use the following code snippet
for ( int i = 0; i < 2; i++ )
{
delete array[i];
}
delete []array;
EDIT: As you changed your original post then I also will append in turn my post.
Instead of
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
there should be
Array array;
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject( new int( j ) );
}
Take into account that either you should define copy/move constructors and assignment operators or define them as deleted.
There are lots of problems with this code.
The declaration void* array = new void*[2] creates an array of 2 pointers-to-pointer-to-void, indexed 0 and 1. You then try to write into elements 0, 1 and 2. This is undefined behaviour
You almost certainly don't want a void pointer to an array of pointer-to-pointer-to-void. If you really want an array of pointer-to-integer, then you want int** array = new int*[2];. Or probably just int *array[2]; unless you really need the array on the heap.
j is the probably in the same place each time through the loop - it will likely be allocated in the same place on the stack - so &j is the same address each time. In any case, j will go out of scope when the loop's finished, and the address(es) will be invalid.
What are you actually trying to do? There may well be a better way.
if you simply do
int *array[10];
your array variable can decay to a pointer to the first element of the list, you can reference the i-th integer pointer just by doing:
int *myPtr = *(array + i);
which is in fact just another way to write the more common form:
int *myPtr = array[i];
void* is not the same as int*. void* represent a void pointer which is a pointer to a specific memory area without any additional interpretation or assuption about the data you are referencing to
There are some problems:
1) void *array = new void*[2]; is wrong because you want an array of pointers: void *array[2];
2)for (int i = 0; i < 3; i++) { : is wrong because your array is from 0 to 1;
3)int j = i + 1; array[i] = *j; j is an automatic variable, and the content is destroyed at each iteration. This is why you got always the same address. And also, to take the address of a variable you need to use &
I am trying to allocate memory in a function and I am not sure what I am doing wrong.
I want this:
int main()
{
int* test= 0;
initialize(test, 10);
int test2 = test[2];
delete[] test;
}
void initialize(int* test, int count)
{
test = new int[count];
for (int i = 0; i < count; i++)
{
test[i] = i;
}
}
But I receive this error: Unhandled exception at 0x770d15de in Robust Simulation.exe: 0xC0000005: Access violation reading location 0x00000008.
It breaks on line: int test2 = test[2];
but this works:
int main()
{
int* test=0;
test = new int[10];
for (int i = 0; i < 10; i++)
{
test[i] = i;
}
int test2 = test[2];
delete[] test;
}
Is there a scoping problem? I thought since I pass it a pointer it would be allocated and I would be able to access it outside of the initialize function.
Thanks for your help
Do following changes:-
initialize(&test, 10);
....
void initialize(int** test, int count)
{
*test = new int[count];
for (int i = 0; i < count; i++)
{ (*test)[i] = i; }
}
C++ has another feature called references if you want as it is :-
void initialize(int*& test, int count)
{
test = new int[count];
for (int i = 0; i < count; i++)
{ test[i] = i; }
}
what you are doing is passing the test[from main](address will pass) and storing in another local pointer variable named test.This new variable has lifetime of function scope and will get soon deleted leaving garbage after the completion of function.
Another option is
int* test= initialize(test, 10);
and change initialize as
int* initialize(int* test, int count)
{
test = new int[count];
for (int i = 0; i < count; i++)
{ test[i] = i; }
return test;
}
Pointers are also passed by value. You need:
void initialize(int*& test, int count)
Your version doesn't change the original pointer:
void initialize(int* test, int count)
{
//test is a copy of the pointer because it was passed by value
//...
}
After this, it's obvious why the delete[] fails - because the original pointer in main is never initialized.
You need to pass a reference to a pointer into your initialise function. Change the prototype to
void initialize(int* &test, int count)
The return value of new is assigned to that copy of the pointer that gets created when passing by value. So when the function exits, that address is lost as the copy goes out of scope and so you have a memory leak. Thus your test pointer never actually points to any allocated memory and so deleting it gives you an access violation.
Passing by reference allows the test pointer to be modified by the function