Store a 2byte value in memory location in C - c

I am in need of your help in this problem:
I want to store a 2 byte number in a char array I have tried the below 2 logics but both have failed
char buff[10];
char* ptr = buff;
/*
I want to store a 2 byte value say 750
Method 1 */
short a = 750;
*(++ptr)=a; //Did not work got these values in first 2 bytes in buffer: 0xffffffc8 0xffffffef
/* Method 2 */
short *a=750;
memcpy(++ptr,a,2) // Got segmentation fault
I know I can do this by dividing by 256 but I want to use a simpler method
*ptr++=750/256;
*ptr=750%256;

The easiest way is simply:
uint16_t u16 = 12345;
memcpy(&buff[i], &u16, 2);
memcpy will place the data according to your CPU endianess.
Alternatively you can bit shift, but since bit shifts themselves are endianess-independent, you need to manually pick the correct indices for buff according to endianess.
Memory layout like Little Endian:
buff[i] = u16 & 0xFFu;
buff[i+1] = (u16 >> 8) & 0xFFu;
Memory layout like Big Endian:
buff[i] = (u16 >> 8) & 0xFFu;
buff[i+1] = u16 & 0xFFu;

char buff[10];
short a=1023;
//To store in char array
buff[0] = a & 0xff;
buff[1] = (a >> 8) & 0xff;
// To get original value.
short b = ((buff[1] << 8) & 0xff00) | (buff[0] & 0x00ff);

Related

How to take to nibbles from a byte of data that are chars into two bytes stored in another variable in order to unmask

I have two uint_16ts that I've gotten from the nibbles of my data as seen in the code below. I need to put that into mask set so that each of the nibbles are now in its own byte. The code I got is below I can't for the life of me figure it out. I need to do this cause this will create the mask I will use to unmask mildly encrypted data.
uint16_t length = *(offset+start) - 3;
uint16_t mask = length;
if(Fmt == ENCRYPTED) {
char frstDig = (length & 0x000F)
char scndDig = (length & 0x00F0) >> 4;
mask =
Shift one of the digits by 8 bits, and OR them together.
mask = (scndDig << 8) | frstDig;

what does a[0] = addr & 0xff?

i'm currently learning from the book "the shellcoder's handbook", I have a strong understanding of c but recently I came across a piece of code that I can't grasp.
Here is the piece of code:
char a[4];
unsigned int addr = 0x0806d3b0;
a[0] = addr & 0xff;
a[1] = (addr & 0xff00) >> 8;
a[2] = (addr & 0xff0000) >> 16;
a[3] = (addr) >> 24;
So the question is what does this, what is addr & 0xff (and the three lines below it) and what makes >> 8 to it (I know that it divides it 8 times by 2)?
Ps: don't hesitate to tell me if you have ideas for the tags that I should use.
The variable addr is 32 bits of data, while each element in the array a is 8 bits. What the code does is copy the 32 bits of addr into the array a, one byte at a time.
Lets take this line:
a[1] = (addr & 0xff00) >> 8;
And then do it step by step.
addr & 0xff00 This gets the bits 8 to 15 of the value in addr, the result after the operation is 0x0000d300.
>> 8 This shifts the bits to the right, so 0x0000d300 becomes 0x000000d3.
Assign the resulting value of the mask and shift to a[1].
The code is trying to enforce endianness on the data input. Specifically, it is trying to enforce little endian behavior on the data. Here is the explaination:
a[0] = addr & 0xff; /* gets the LSB 0xb0 */
a[1] = (addr & 0xff00) >> 8; /* gets the 2nd LSB 0xd3 */
a[2] = (addr & 0xff0000) >> 16; /* gets 2nd MSB 0x06 */
a[3] = (addr) >> 24; /* gets the MSB 0x08 */
So basically, the code is masking and separating out every byte of data and storing it in the array "a" in the little endian format.
unsigned char a[4]; /* I think using unsigned char is better in this case */
unsigned int addr = 0x0806d3b0;
a[0] = addr & 0xff; /* get the least significant byte 0xb0 */
a[1] = (addr & 0xff00) >> 8; /* get the second least significant byte 0xd3 */
a[2] = (addr & 0xff0000) >> 16; /* get the second most significant byte 0x06 */
a[3] = (addr) >> 24; /* get the most significant byte 0x08 */
Apparently, the code isolates the individual bytes from addr to store them in the array a so they can be indexed. The first line
a[0] = addr & 0xff;
masks out the byte of lowest value by using 0xff as a bit mask; the subsequent lines do the same, but in addition shift the result to the rightmost position. Finally, the the last line
a[3] = (addr) >> 24;
no masking is necessary anymore, as all unneccesary information is discarded by the shift.
The code is effectively storing a 32 bit adress in a 4 chars long array. As you may know, a char has a byte (8 bit). It first copies the first byte of the adress, then shifts, copies the second byte, then shifts, etc. You get the gist.
It enforces endianness, and stores the integer in little-endian format in a.
See the illustration on wikipedia.
also, why not visualize the bit shifting results..
char a[4];
unsigned int addr = 0x0806d3b0;
a[0] = addr & 0xff;
a[1] = (addr & 0xff00) >> 8;
a[2] = (addr & 0xff0000) >> 16;
a[3] = (addr) >> 24;
int i = 0;
for( ; i < 4; i++ )
{
printf( "a[%d] = %02x\t", i, (unsigned char)a[i] );
}
printf("\n" );
Output:
a[0] = b0 a[1] = d3 a[2] = 06 a[3] = 08
I addition to the multiple answers given, the code has some flaws that need to be fixed to make the code portable. In particular, the char type is very dangerous to use for storing values, because of its implementation-defined signedness. Very classic C bug. If the code was taken from a book, then you should read that book sceptically.
While we are at it, we can also tidy up the code, make it overly explicit to avoid potential future maintenance bugs, remove some implicit type promotions of integer literals etc.
#include <stdint.h>
uint8_t a[4];
uint32_t addr = 0x0806d3b0UL;
a[0] = addr & 0xFFu;
a[1] = (addr >> 8) & 0xFFu;
a[2] = (addr >> 16) & 0xFFu;
a[3] = (addr >> 24) & 0xFFu;
The masks & 0xFFu are strictly speaking not needed, but they might save you from some false positive compiler warnings about wrong integer types. Alternatively, each shift result could be cast to uint8_t and that would have been fine too.

How to extract 2 bytes from a word, and how to make a word from 2 bytes (in C)?

I am trying to extract two bytes from a 16-bit word, and to make a 16-bit word from two bytes. This is what I have tried (byte = unsigned char, word = unsigned short):
Split grpix word into 2 bytes:
word grpix; // Assume that the value has been initialized
byte grpixl = grpix & 0x00FF;
byte grpixh = grpix & 0xFF00;
Make grpix word from 2 bytes
byte grpixh; // Assume that the value has been initialized
byte grpixl; // Assume that the value has been initialized
word grpix = grpixh;
grpix <<= 8;
grpix += grpixl;
For some reason, my code doesn't work as expected, and now I'm not sure if the "splitting" of the word is wrong, if the "making" of the word is wrong, or both... Could you give me some advice?
You're not shifting when you split the word. So if grpix is 0x1234, then grpixl gets the expected 0x34 but grpixh ends up as 0x1200. You should say
byte grpixh = grpix >> 8;
Of course, you're also ignoring any endianness concerns that may be present. You should probably convert your word to a known endian (with something like htons()) before attempting to split (and do the reverse conversion when joining).
Get to know: http://graphics.stanford.edu/~seander/bithacks.html for doing all manner of operations.
right_byte = short_val & 0xFF;
left_byte = ( short_val >> 8 ) & 0xFF
short_val = ( ( left_byte & 0xFF ) << 8 ) | ( right_byte & 0xFF );
I always do a &0xFF mask to assure I have no sign problems.
The simple code that I use to solve this, is:
word=(msb<<8)+lsb;
The following routines have proved very reliable for me:-
unsigned short get16int(a) char *a;{
unsigned short hi,lo;
hi = *a++ << 8;
lo = *a & 0x00ff; /* Needed to cater for sign extending when msb bit is set */
return (hi | lo);
}
put16int(a,i) char *a; int i;{
*a++ = i >> 8;
*a = i;
}
When you mask out the high byte, you need to also shift down by 8 bits, otherwise you just end up with a 16bit number with the bottom eight bits cleared.
byte grpixh = (grpix & 0xFF00) >> 8
Also your composition can be more efficient by using or-equals instead of plus-equals:
grpix |= grpixh << 8
word grpix = grpixl+256*grpixh;

Store an integer in an array where the elements represent 1 byte of the value

I'm using AES to encrypt some data that I'm going to send in a packet. I need to store an integer in an array of 8 bit elements. To make this clear, my array is declared as:
uint8_t in[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00};
I need to be able to store an integer in this array and then easily retrieve the data in the receiving client. Is there an easy way to accomplish this?
This is usually achieved via bit-shifting:
int i = 42;
in[0] = i & 0xff;
in[1] = (i >> 8) & 0xff;
in[2] = (i >> 16) & 0xff;
in[3] = (i >> 24) & 0xff;
Note that you cannot always be guaranteed that an int is four bytes. However, it's easy enough to turn the above code into a loop, based on sizeof i.
Retrieving the integer works as follows:
int i = in[0] | (in[1] << 8) | (in[2] << 16) | (in[3] << 24);
Of course, if you are about to encrypt this with AES, you need to give some thought to a sensible padding algorithm. Currently you look like you're heading towards zero-padding, which is far from optimal.

is it possible to bit mask a char array

Let's say I have the following char array
char array[32];
I want to use only the 10 most significant bits of this array as a hash value.
Is it possible to use bitwise operation on this char array?
If so, how should i do it?
Assuming your implementation has 8-bit char, and that you have a 256-bit number stored in big endian in this array, here how to access the 10 msb of the 256-bit number.
uint16_t a;
a = (array[0] << 2 | (array[1] & 0xC0) >> 6) & 0x3FF;
I'm pretty sure you want something like this (again assuming 8-bit chars stored big endian in array):
uint16_t a = (((uint16_t)array[0] & 0xFF) << 2 | ((uint16_t)array[1] & 0xFF) >> 6) & 0x3FF;
To break that down a bit:
uint16_t byte0 = (uint16_t)array[0] & 0xFF;
uint16_t byte1 = (uint16_t)array[1] & 0xFF;
uint16_t a = (byte0 << 2 | byte1 >> 6) & 0x3FF;

Resources