I have a buffer of points that I want to send off to be processed by a function. It is an array of unsigned shorts. Currently I'm trying the following:
void ftn(unsigned short **buffer, int size)
{
for (int i = 0; i < size; i++)
{
*(buffer[i]) = 0; //test
}
}
Outside of the function, it's defined as unsigned short buffer[size]; Does this not make sense? Where am I going wrong? Thanks
When you pass an array to a function, you don't actually pass the array by value. Rather, you actually pass a reference to the original array.
Therefore, you simply need to do:
void ftn(unsigned short buffer[], int size)
{
for (int i = 0; i < size; i++)
{
buffer[i] = 0; //test
}
}
Note that if you change the actual value of buffer, you don't actually change the original array. An example of this could be:
void ftn(unsigned short buffer[], int size)
{
buffer = new unsigned short[20];
}
If you wish to change the original array, your construct will work, but with a little modification:
void ftn(unsigned short **buffer, int size)
{
for (int i = 0; i < size; i++)
{
(*buffer)[i] = 0; //test
}
}
This is very C-like, mind you, and less C++-like.
buffer is a pointer to a pointer to an unsigned short. (That is, a pointer to the variable you use to refer to the array.)
If you dereference buffer, you get a pointer to an unsigned short, which can be treated as an array of unsigned shorts.
With this you also have the ability to reassign the value of the original variable, for instance like this:
void ftn(unsigned short **buffer, int size)
{
*buffer = new unsigned short[20];
}
See also:
Arrays as parameters
No that doesn't make sense, because buffer[i] "returns" an array of shorts, and the
*(buffer[i]) tries to dereference that array of shorts, and then, you try to set a memory address for that (i.e. NULL or 0), and that results in a seg fault.
The answer is very quick, I don't know why people wrote so much:
#define SIZE_ARRAY 10
void ftn(unsigned short * buffer, int size)
{
for (int i = 0; i < size; i++)
{
buffer[i] = 0; // test
}
}
void main()
{
unsigned short buffer[SIZE_ARRAY];
ftn(&buffer[0], SIZE_ARRAY);
}
I wouldn't take Sebastian's answer he still uses unsigned short **buffer which is just too complication.
Related
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.
Im facing a serious problem and I need your help please!
what Im facing is that Im getting value from another function as integer
which they are : {5,1,2,3,4,5}
so those value exactly I want to copy them to an array type uint8_t.
this means the array that I want to get is
uint8_t arr={5,1,2,3,4,5};
what actually the problem?
the problem is this if I want to initialize and array type uint8_t with those values then I write immediately in the compiler:
uint8_t arr={5,1,2,4,5} (I mean by intilizing immediately ..once I write my syntax uint8_t arr in my compiler I write immediately [code]{5,1,2,3,4,5}[/code] )
the problem that those values I'm getting them from other function ..and I want those values to be entered as it's in an array type uint8_t this means my array would be the same with those value but type uint8_t => uint8_t arr={5,1,2,3,4,5};
how can I do that ? I tried to use unsigned int and starting filling it with values {5,1,2,3,4,5} but it didn't work!
any help how can I implement that? thanks a lot.
what I tried by code is this:
int array2={5,1,2,3,4,5};
unit8_t array1[6]={0};
for(int i=0;i<(sizeof(array2)/sizeof(array2[0]));i++)
{
array1[i]=array2[i];} /*I want the same values of array2 to enter to array1 but the type of array to be uint8_t*/
}
for(int i=0;i<6;i++)
{
cout<<array2[i];
}
}
so what I expect to get once I print output is the array1 which it should be : [code] {5,1,2,3,4,5} and array1 type uint8_t with the same values that I copied them to it.
but the output is wrong answer, it's ���a��ߙ��I��
my purpose is to get an array type uint8_t with the same values copied, this means my output is an array like this uint8_t array1={5,1,2,3,4,5} , same values with type uint8_t.
I don't know what you want to do with your array1, But if you just want result on output screen then you have to convert it into integer value first before pushing it into stream to see the values i.e
int array2[] = {5,1,2,3,4,5};
uint8_t array1[6];
for(int i=0;i<6;i++)
{
array1[i]= (array2[i]);
}
for(int i=0; i<6; i++){
cout << int(array1[i]) << ' '; //This line here
}
Compare your code with this
#include <stdint.h>
int main(void)
{
int array_int[6] = { 5,1,2,3,4,5 };
uint8_t array_byte[6] = { 0 };
for (int i = 0; i < sizeof(array_byte); i+=1)
array_byte[i] = (uint8_t) array_int[i];
return;
};
Maybe you typed here directly and not from a code you compiled before. You must use sizeof() the array of bytes, or use sizeof(array_int)/sizeof(int) to control the loop.
The cast (uint8_t) array_int is just for clarity and can be omitted.
You are just printing it wrong, likely as chars, print using formatting instead:
typedef unsigned char uint8_t;
#include<iostream>
template <typename T, unsigned N>
constexpr unsigned countof(T const (&)[N]) noexcept
{
return N;
}
int main()
{
int array2[]={5,1,2,3,4,5};
uint8_t array1[countof(array2)];
for(int i=0;i<countof(array2);i++)
{
array1[i]=array2[i];
}
for(auto x : array1)
{
printf("%u", x);
}
return 0;
}
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.
I'm eradicating std::string in favor of C-strings, which I'm new to. How do I get the following to compile? g++ complains: cannot convert char(*)[16] to char**
#include <iostream>
void print(char** s, int n)
{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << '\n';
}
}
int main()
{
constexpr int n = 3;
char s[n][16]{ "Hello", "Bye", "Sky"};
print(s, n);
}
You created a multidimensional array, not an array of pointers. Usually an array can be said to be equivalent to a pointer, however in this case c++ needs to know the size of the second dimension of your array. The function would be as follows
void print(char s[][16], int n)`{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << std::endl;
}
}
Understandably you may want to pass the function using pointers as to not make an entire copy of the 2-d array. I saw you mentioned you were okay with variable length strings. That functionality is supported in the string library. You are dealing with c-strings which are not strings at all but static arrays of type character. Defining these c-strings using dynamic memory happens to give you the desired behavior as you create in the simplest terms an array of pointers.
void print(char** s, int n)
{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << std::endl;
}
}
int main()
{
int n = 3, i;
char** s = new char*[n];
for (i = 0; i < 3; i++) {
s[i] = new char[16];
}
s[0] = "Hello";
s[1] = "Bye";
s[2] = "Sky";
print(s, n);
for (i = 0; i < 3; i++) {
delete [] s[i];
}
delete [] s;
s = NULL;
return 0;
}
Since you are using dynamic memory now you need to free your memory which is what the last loop serves to do. As you can see using all this dynamic memory is quite taxing and it would be easier to use the string library that has been optimized to do a much better job then you can. If you're still not convinced you should at least make your own string class to handle the dynamic memory that contains a char * as its private member. In either case you avoid this mess and just make an array of zed class objects and not deal at all with multidimensional nonsense. No one likes seg faults and memory leaks.
Given any type T, T arr[N]; declares a variable arr of type T[N], which is an array and not a pointer. When you use arr in almost all contexts, array to pointer conversions happen, giving the incorrect illusion that arr is a pointer of type T*.
char s[n][16] = { "Hello", "Bye", "Sky" };
declares s as an array of n elements of type char[16]. Now, when array to pointer conversion happens, s decays into a pointer of type char (*)[16]. Hence, your function needs to have the signature
void print(char (*s)[16], int n);
Which is equivalent to
void print(char s[][16], int n);
the [] is interpreted as a pointer by the compiler.
To make these complex types more readable, a type alias may be used.
using T = char[16];
void print(T s[], int n);
Addressing some concerns
As pointed out in the comments, std::string should almost always be preferred over a char array. If you have performance concerns, benchmark before doing this. I really doubt much performance gains can be observed in most cases.
Declaring an array with length n which is an int is not standard C++. It is an extension provided by your compiler, it is not portable and in most cases not necessary.
int n = 3;
char vla[n]; // this is a variable length array
char arr[3]; // this is just an array
char* darr = new char[3]; // this is a pointer pointing to dynamically allocated memory
std::string str; // but instead, this is just better
The compiler cannot extract from char ** the infomation about char[16]. You need to define a type char[16] and pass the pointer to this type to your print function.
#include <iostream>
typedef char str_t[16];
void print(str_t* s, int n)
{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << std::endl;
}
}
int main()
{
int n = 3;
char s[n][16]{ "Hello", "Bye", "Sky"};
print(s, 3);
}
#include<stdio.h>
#include<conio.h>
unsigned * bin(unsigned n) {
unsigned a[16];
int i = 0, j = 0;
for (i = 0; i < 16; i++) {
a[i] = n & 0x1;
n = n >> 1;
}
return a;
}
void main() {
unsigned n = 5;
int i = 0;
unsigned * a = bin(n);
for (i = 15; i >= 0; i--) {
printf("%d\n", (*(a + i)));
}
getch();
}
Please help this binary conversion does not work. I'm trying to calculate x^n using binary conversion.
can anybode help??
You are returning a pointer to a local variable. This variable is stored on the stack, and will not be valid after the function returns.
Dereferencing this pointer will lead to undefined behavior.
The solution is to either make the variable static, or pass in the array as an argument to the function, or (as noted in a comment by James Kanze) use a type that copies the contents.
you can not return a local array defined in the function in this way.
The content of the array will be erased when the function finish the execution.
instead of using
unsigned a[16];
you can use the following:
unsigned *a =malloc(16 * (sizeof *a));
And do not forget in your main to free the memory allocated for a when the a array become useless in your program. you can free the array with:
free(a);
Actually, this is a typical case where using new (or malloc) is a pretty bad choice. However, as others have said, returning a pointer to a local array is bad.
Instead, pass in an array:
void bin(unsigned n, unsigned a[]) {
int i = 0;
for (i = 0; i < 16; i++) {
a[i] = n & 0x1;
n = n >> 1;
}
}
and in main:
unsigned a[16];
bin(n, a);
Now you have no need to allocate or return an array from bin.