Code for parsing a character buffer - c

I want to parse a character buffer and store it in a data structure.
The 1st 4 bytes of the buffer specifies the name, the 2nd four bytes specifies the length (n) of the value and the next n bytes specifies the value.
eg: char *buff = "aaaa0006francebbbb0005swisscccc0013unitedkingdom"
I want to extract the name and the value from the buffer and store it a data structure.
eg: char *name = "aaaa"
char *value = "france"
char *name = "bbbb"
char *value = "swiss"
After storing, I should be able to access the value from the data structure by using the name.
What data structure should I use?
EDIT (from comment):
I tried the following:
struct sample {
char string[4];
int length[4];
char *value; };
struct sample s[100];
while ( *buf ) {
memcpy(s[i].string, buf, 4);
memcpy(s[i].length, buf+4, 4);
memcpy(s[i].value, buf+8, s.length);
buf += (8+s.length);
}
Should I call memcpy thrice? Is there a way to do it by calling memcpy only once?

How about not using memcpy at all?
typedef struct sample {
char name[4];
union
{
char length_data[4];
unsigned int length;
};
char value[];
} sample_t;
const char * sample_data = "aaaa\6\0\0\0francebbbb\5\0\0\0swisscccc\15\0\0\0unitedkingdom";
void main()
{
sample_t * s[10];
const char * current = sample_data;
int i = 0;
while (*current)
{
s[i] = (sample_t *) current;
current += (s[i])->length + 8;
i++;
}
// Here, s[0], s[1] and s[2] should be set properly
return;
}
Now, you never specify clearly whether the 4 bytes representing the length contain the string representation or the actual binary data; if it's four characters that needs to run through atoi() or similar then you need to do some post-processing like
s[i]->length = atoi(s[i]->length_data)
before the struct is usable, which in turn means that the source data must be writeable and probably copied locally. But even then you should be able to copy the whole input buffer at once instead of chopping it up.
Also, please note that this relies on anything using this struct honors the length field rather than treating the value field as a null-terminated string.
Finally, using binary integer data like this is obviously architecture-dependent with all the implications that follows.

To expand on your newly provided info, this will work better:
struct sample {
char string[4];
int length;
char *value; };
struct sample s[100];
while ( *buf && i < 100) {
memcpy(s[i].string, buf, 4);
s[i].length = atoi(buf+4);
s[i].value = malloc(s[i].length);
if (s[i].value)
{
memcpy(s[i].value, buf+8, s[i].length);
}
buf += (8+s[i].length);
i++;
}

I would do something like that:
I will define a variable length structure, like this:
typedef struct {
char string[4];
int length[4];
char value[0] } sample;
now , while parsing, read the string and length into temporary variables.
then, allocate enough memory for the structure.
uint32_t string = * ( ( uint32_t * ) buffer );
uint32_t length = * ( ( uint32_t * ) buffer + 4);
sample * = malloc(sizeof(sample) + length);
// Check here for malloc errors...
* ( (uint32_t *) sample->string) = string;
* ( (uint32_t *) sample->length) = length;
memcpy(sample->value, ( buffer + 8 ), length);
This approach, keeps the entire context of the buffer in one continuous memory structure.
I use it all the time.

Related

Printing the complete size of char*

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.
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.
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 );
...
}

Convert *char or char to bits

How do I convert * char or char to bits ?
For example:
Here 's my declarations
uint64_t blocks[64];
char * word = "hello";
How do I store the word hello in bytes inside blocks[0] ?
I tried this
int e;
int a = strlen(word);
for (e = 0; e < a; e++) {
blocks[0] |= !!word[e] >> 8;
}
Also, how will I reverse the process?
"I want to copy the bits in a char into a uint64_t."
Try using memcpy:
void * memcpy(void * dst, const void * src, size_t n)
e.g.
memcpy(blocks, word, strlen(word));
More than one string
Regarding your comment which I interpret to be about copying more than one string:
memcpy copies n bytes from src to dst, so if we want to copy several strings in succession, we need to make sure calls to memcpy have src set to the end of the last string we copied, assuming we want to copy "hello" and then "world" into blocks and end up with the bytes that represent "helloworld".
// if you have a char** words and uint64_t blocks[64]; or similar
uint64_t blocks[64];
const char *words[2] = { "hello", "world" };
size_t offset = 0, len;
int num_words = sizeof words / sizeof words[0], n;
for (n = 0; n < num_words && offset < sizeof blocks; ++n) {
len = strlen(words[n]);
memcpy(((void *)blocks) + offset, words[n], len); // note the void * cast
offset += len;
}
This should be easily adaptable to a situation where you are reading in the strings rather than having an array of array of chars.
Getting a string back again
To take blocks and get a char * with all the bytes in it, we need to remember that strings in C are null terminated, so if we want to treat the result as a string, it needs a null on the end. The last offset you have once you are done copying (from above) could be used to add this.
char new_word[100];
memcpy(new_word, blocks, sizeof new_word);
new_word[offset] = 0;
We don't have to copy the data to treat this as a char *, by the way; We could just cast...
char * new_word = (char *)blocks;
...but remember that if you do this, modifying new_word will also modify blocks.

allocate dynamic memory for char array

I have to print some values stored in the struct to single char array , I am not getting an simple method to allocate a memory for a variable array values .
below snnipet of the code which I need to do
struct types {
char *name;
char *address;
char * descrption;
};
int main ()
{
int numberofUser = 10;
struct types allUsers[numberofUser];
//Assume here I filled all the user details by allocation memory.
// now I need to print these values in the formated string like below
char* outputString;
int i ;
for(i =0 ; i<numberofUser;i++)
{
sprintf(outputString,"<start>name=%s,add=%s,des=%s",allUsers[i].name,allUsers[i].address,allUsers[i].descrption);
}
}
How to allocate memory for the output string which can hold all structure values
Define the format string and store it in a variable of its own.
char const* formatString = "<start>name=%s,add=%s,des=%s";
Get the length of the format string.
size_t formatStringLen = strlen(formatString);
Get the lengths of the members of the struct.
size_t nameLen = strlen(allUser[i].name);
size_t addLen = strlen(allUser[i].address);
size_t desLen = strlen(allUser[i].description);
Allocate enough memory to hold the format string as well as the members of the struct.
// This will be more than the exact space you need but certainly
// not less than what you need and not too much more than what you
// need.
size_t totalLen = formatStringLen + nameLen + addLen + desLen;
outputString = malloc(totalLen);
Use sprintf
sprintf(outputString, formatString,
allUsers[i].name, allUsers[i].address, allUsers[i].descrption);
You need to calculate length of strings involved and allocate that much memory to it. Something like
int len = 0;
len = strlen(allUsers[i].name)
+ strlen(allUsers[i].address)
+ strlen(allUsers[i].descrption);
len += strlen("<start>name=")
+ strlen(",add=")
+ strlen(",des=");
len ++ // for '\0'
outputString = malloc(sizeof(char) * len);
Note: this is for 1 record in allUsers as strings may change in other elements.
You should check for valid pointers and should free memory after used.
The members of your structure are pointers to characters, i.e. of type char * but you need a character array to store the strings. The size of the array must be one more than the maximum length the string can have to accommodate the terminating null byte which marks the end of the string. I suggest the following changes -
#include <stdio.h>
#include <string.h>
#define NAMELEN 20+1 // max length of name + 1
#define ADDRLEN 40+1 // max length of address + 1
#define DESCLEN 80+1 // max length of description + 1
struct types {
char name[NAMELEN];
char address[ADDRLEN];
char descrption[DESCLEN];
};
int main(void) {
int numberofUser = 10;
struct types allUsers[numberofUser];
// assign values to array elements
// format string for sprintf
const char *fstr = "<start>name=%s,add=%s,des=%s";
// strlen doesn't count the null byte. macros include null byte
// so get space for 2 extra null bytes which is not needed.
int outlen = strlen(fstr) + NAMELEN + ADDRLEN + DESCLEN - 2;
// variable-length to store the output string
char outputString[outlen];
for(int i = 0; i < numberofUser; i++) {
sprintf(outputString, "<start>name=%s,add=%s,des=%s",
allUsers[i].name,
allUsers[i].address,
allUsers[i].descrption);
// print the string
printf("%s\n", outputString);
}
return 0;
}
If your compiler supports C99 then it shall contain function snprintf. To allocate and set your string, you can use the following code:
char *outputString;
int len;
outputString = NULL;
len = 0;
for(;;) {
// this loop is executed only two times
len = 1 + snprintf(outputString, len, "<start>name=%s,add=%s,des=%s",allUsers[i].name,allUsers[i].address,allUsers[i].descrption);
if (outputString != NULL) break; // success
outputString = realloc(outputString, len);
if (outputString == NULL) break; // fail
}

Dynamic Memory Allocation to a Struct's array. Program Closing [C]

I checked Google but I cannot find any solution. I'm making a program and I need to use dynamic memory allocation. This is the struct I use
struct profile {
char *item;
int lala;
char *lolo;
} members[];
I want to allocate memory for members Array using dynamic memory allocation, on the internet in every sample it allocates memory for pointers, I cannot represent my array as a pointer too.
I cannot represent my array as a pointer too.
There's no other way in C than to represent a dynamically allocated array of memory through a pointer.
I think your mental roadblock stems from the conception, that the data of the structure should be arranged in the order as defined in the structure. I'm sorry to tell, you, but this is not possible to do in C in a straightforward way.
Sure it's perfectly possible to have a data structure of the from
size_t length;
char data[];
size_t length2
char data2[];
somewhere in memory. But there's no built-in support in C for this kind of binary data stream.
The best thing you can do, is have a number of helper pack/unpack functions that take an opaque pointer to some memory and can pack and unpack to C structures to work with.
Note that if you're looking for using that as a way to parse the contents of a file: DON'T! There lie only monsters and fear that way.
EDIT code sample
For example assume the following structure
typedef struct Foo {
size_t name_len;
char * name; /* since we know len, this doesn't need to be '\0' terminated */
size_t bar_len;
char * bar; /* same as for name */
} Foo; /* typedef for the lazy */
You can pack that into a binary stream with the following function
/* returns a pointer to memory dynamically allocated and filled
* with a packed representation of the contents of a Foo struct.
* Once no longer needed release the memory allocated using free()
*
* returns NULL in case of an error.
*/
void * fooPack(Foo const * const foo_data)
{
assert( NULL != foo_data );
size_t const foo_data_lenth =
foo_data->name_len
+ foo_data->bar_len
+ 2 * sizeof(size_t);
char * const packed = malloc( foo_data_length );
if( NULL == packed ) {
return NULL;
}
char * p = packed;
*((size_t*)p) = foo_data->name_len;
p += sizeof(size_t);
memcpy(p, foo_data->name, foo_data->name_len);
p += foo_data->name_len;
*((size_t*)p) = foo_data->bar_len;
p += sizeof(size_t);
memcpy(p, foo_data->bar, foo_data->bar_len);
return p;
}
Unpacking is straightforward
/* Unpacks a struct Foo with memory for name and bar allocated
* to match the data found in the packed data buffer.
*
* returns 0 on success and a negative value on error
*/
int fooUnpack(Foo * const foo_data, void const * const packed)
{
if( NULL == foo_data ) {
return -1;
}
if( NULL == packed ) {
return -2;
}
char const * p = packed;
/* unpack name */
size_t const name_len = *((size_t*)p);
p += sizeof(size_t);
char * name = malloc(name_len);
if( NULL == name ) {
return -3;
}
memcpy(name, p, name_len);
p += name_len;
/* unpack bar */
size_t const bar_len = *((size_t*)p);
p += sizeof(size_t);
char * bar = malloc(bar_len);
if( NULL == bar ) {
free( name );
return -4;
}
memcpy(bar, p, bar_len);
/* fill in foo_data */
foo_data->name_len = name_len;
foo_data->name = name;
foo_data->bar_len = bar_len;
foo_data->bar = bar;
return 0;
}
Exercise left for the reader: Write a function that frees a Foo structure.

how to malloc for this structure

typedef struct testMsg_ {
unsigned char opCode;
unsigned int Count;
char *macsStrList[MAC_ADDR_STR_LEN];
} testMsg_t;
Number of elements in macsStrList is m_Count.
I know following is not correct:
testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) );
This is correct, given the structure you have done
testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) );
However you are probably confused to the meaning of *arr[dimension] -- which is an array length dimension of pointers to chars -- reading between the lines,
MAC_ADDR_STR_LEN
Is probably ment to the legth of the string representation of a mac address (say <20 bytes?)
However your struct gives you 20 char pointers, and the character pointers still have to be initializaed to point to valid memory.
testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) );
pInput->macsStrList[0] = (char *) malloc( MAC_ADDR_STR_LEN+1 );
pInput->macsStrList[1] = (char *) malloc( MAC_ADDR_STR_LEN+1 );
pInput->macsStrList[2] = (char *) malloc( MAC_ADDR_STR_LEN+1 );
...
or redefine your struct to
typedef struct testMsg_ {
unsigned char opCode;
unsigned int Count;
char macsStrList[NUMBER_OF_MAC_ADDRESSES][MAC_ADDR_STR_LEN];
} testMsg_t;
To avoid having to deal with multiple number of allocations.
ADDITION;
As per comments, given that the number of mac addresses are dynamically determined, you could also define the struct as;
typedef struct testMsg_ {
unsigned char opCode;
unsigned int Count;
char macsStrList[1][MAC_ADDR_STR_LEN];
} testMsg_t;
and then allocate it using
testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) + (countOfMacsAddresses * MAC_ADDR_STR_LEN) );
That would have the added over a solution with pointers of that you could use realloc to resize the array dynamically if you needed to do that as well.....
I think what you're looking for is maybe (ok, Soren got in first, but I'll show a way to allocate a single contiguous chunk):
/* assuming we only need macStrList[0] ... [Count-1] */
struct testMsg
{
unsigned char opCode;
unsigned int Count;
char *macsStrList[];
};
struct testMsg *allocate_testMsg(int count)
{
char *string_storage;
struct testMsg *msg;
size_t size = sizeof(struct testMsg) /* base object */
+ (count * sizeof(char *)) /* char* array */
+ (count * (MAC_ADDR_STR_LEN+1)) /* char storage */
;
msg = malloc(size);
msg->Count = count;
string_storage = (char *)&(msg->macStrList[count]);
/* note msg->macStrList points to UNINITIALIZED but allocated storage.
it might be sensible to zero-fill string_storage, depending on how you'll
initialize it
*/
for (count=0; count < msg->Count;
++count, string_storage += (MAC_ADDR_STR_LEN+1))
{
msg->macStrList[count] = string_storage;
}
return msg;
}
Of course it is. You allocate a pointer to a testMsg_t which is an alias for struct testMsg_. However you need to initialize this object yourself.
(And you don't need to cast the allocated pointer in C).

Resources