-2

I'm working on a C project, the goal is to reach a web server, read the data inside a file (example.com/shellcode.bin for example) and store it inside an array.

Currently, I managed to make the necessary GET requests, i can find my shellcode, insert it into an array (mycode) but when I return it, it sends me the wrong size.

For example, if sizeof(mycode) return 270, sizeof(PE) return 8.

Is it possible to find the total size of the PE variable ?

    size_t size = sizeof(mycode);
    char* PE = (char*)malloc(size);
    for (int i = 0; i < sizeof(mycode); i++) {
        PE[i] = mycode[i];
    }

    printf("Shellcode size before return : %ld\n", sizeof(PE));

    return PE;

I tried different format string outputs (%s with strlen, %d, %ld, %zu ....) all of them returned 8.

Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23
in0tiix
  • 3
  • 4
  • Why not use `sizeof(mycode)` since that's how much space you've allocated? – Stephen Newell Oct 30 '22 at 00:33
  • @StephenNewell The code must be reused, so I must be able to get the real size of my shellcode via the return – in0tiix Oct 30 '22 at 00:35
  • Return a struct containing both the pointer and the size. – kotatsuyaki Oct 30 '22 at 00:40
  • @kotatsuyaki thanks for the the suggestion, how can I do that ? – in0tiix Oct 30 '22 at 00:42
  • The length of the data is up to you to manage. C does not do that automatically for you. If you have read the data from a file (over the network), then the length of the data is the length that you read from the file. Write your code to remember that number. – Eric Postpischil Oct 30 '22 at 00:43
  • @EricPostpischil yes but I would like to reuse my PE variable, how could I declare a new variable, having the total content of the PE variable? Because each time I declare a new variable containing PE, I don't have the whole content ... – in0tiix Oct 30 '22 at 00:47
  • 1
    If the data has embedded zeroes then you can't use `strlen` to determine the size. The right thing to do is have the server send the size of the data it is going to send. – Retired Ninja Oct 30 '22 at 01:44

2 Answers2

1

One solution is to return a struct containing both a pointer to the buffer and the length.

// outside the function
typedef struct {
  char* data;
  size_t size;
} Buffer;

// in the function
Buffer buffer;
buffer.data = PE;
buffer.size = size;
return buffer;

And also change the return type to Buffer.

kotatsuyaki
  • 1,441
  • 3
  • 10
  • 17
  • Thank you @kotatsuyaki, i tried this but i have this error : "return value type does not match the function type", my function is declared as follows : char* GET80(LPCWSTR domain, LPCWSTR path) – in0tiix Oct 30 '22 at 00:57
  • The return type has to be changed to `Buffer`, which is already written in the last sentence of my answer. If for some reason you aren't allowed change the return type, edit your question to include this requirement. In that case, I don't think there's any reasonable way (aside from using a global variable to hold the length, which is often a bad idea) to do it. – kotatsuyaki Oct 30 '22 at 02:06
1

A pointer points to a single object of the pointed-to type; given a pointer value, there's no way to know whether you're looking at the first object of a sequence or not. There's no metadata in the pointer saying "there are N more elements following the thing I point to."

sizeof PE gives you the size of the pointer variable, not the number of things in the buffer; sizeof PE == sizeof (char *). sizeof *PE gives you the size of a single char object, which is 1 by definition; sizeof *PE == sizeof (char).

You have to manually keep track of how much memory you allocated - you somehow have to persist that size variable anywhere you intend to use PE.

As others have pointed out, you can bundle that into a struct type:

struct buffer {
  size_t size;
  char *PE;
};

struct buffer newBuf( const char *mycode, size_t size )
{
  struct buffer b;
  b.PE = calloc( size, sizeof *b.PE );
  if ( b.PE )
  {
    memcpy( b.PE, mycode, size );
    b.size = size;
  }
  return b;
}

int main( void )
{
  char shellcode[] = { /* some char data here */ };
  struct buffer b = newBuf( shellcode, sizeof shellcode );
  ...
}
John Bode
  • 119,563
  • 19
  • 122
  • 198