Skip to content

Instantly share code, notes, and snippets.

@UplinkCoder
Last active June 25, 2019 05:27
Show Gist options
  • Select an option

  • Save UplinkCoder/3c397d75fc90e7e5a844bdab00dbd000 to your computer and use it in GitHub Desktop.

Select an option

Save UplinkCoder/3c397d75fc90e7e5a844bdab00dbd000 to your computer and use it in GitHub Desktop.
base64decode_bugged
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifdef _WIN32
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
#endif;
#define cast(X) (X)
int min_(int a, int b)
{
return a < b ? a : b;
}
int max_(int a, int b)
{
return a > b ? a : b;
}
char b64_enc_table[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6',
'7', '8', '9',
'+', '/'
};
const unsigned char b64_dec_table[79] =
{
62, -1, -1, -1, 63, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, -1, -1, -1,
-1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
-1, -1, -1, -1, -1, -1, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50,
};
unsigned char decodeTo6Bit(unsigned char c)
{
if (c >= 43 && c <= 43 + 79)
{
return b64_dec_table[c - 43];
}
else
{
return -1;
}
}
const unsigned char decodeByte(const unsigned char c);
const unsigned char encodeByte(const uint32_t v, const unsigned int place);
void encode4Byte(unsigned char src[3], unsigned char *dst[4])
{
char result[4] = {0};
uint32_t tmp = *cast(uint32_t*) src;
result[0] = encodeByte(tmp, 0);
result[1] = encodeByte(tmp, 1);
result[2] = encodeByte(tmp, 2);
result[3] = encodeByte(tmp, 3);
*dst = result;
}
//const unsigned char conversionTable[64] = genConvTable();
const unsigned char encodeByte(const uint32_t v, const unsigned int place)
{
const unsigned char _6bit = (v >> (place * 6)) & 63;
return b64_enc_table[_6bit];
}
void decode4Byte(unsigned char src[4], unsigned char *dst[3])
{
char result[3];
uint32_t tmp = 0;
tmp = decodeTo6Bit(src[0])
| (decodeTo6Bit(src[1]) << 6)
| (decodeTo6Bit(src[2]) << 12)
| (decodeTo6Bit(src[3]) << 18);
printf("'Q'.to6Bit, 'U'.to6Bit = 0x%x, 0x%x, %x\n",
decodeTo6Bit('Q'),
decodeTo6Bit('U'),
(0x10 | 0x14 << 6) & 0xFF
);
printf("src = %c%c%c%c", src[0], src[1], src[2], src[3]);
printf("To6Bit(src) = %x %x %x %x", decodeTo6Bit(src[0]),
decodeTo6Bit(src[1]),
decodeTo6Bit(src[2]),
decodeTo6Bit(src[3]));
printf("tmp = %x\n", tmp);
printf("s_c1, s_c2 = %c, %c\n", src[0], src[1]);
printf("c1, c2 = %d, %d\n", tmp & 0xFF, (tmp & 0xFF00) >> 8);
result[0] = tmp & 0xFF;
result[1] = tmp & 0xFF00;
result[2] = tmp & 0xFF;
printf("dst = %x, %x, %x\n", result[0], result[1], result[2]);
(*dst) = result;
}
void genDecodeTable()
{
FILE* f = fopen("b64_dec_table.h", "wb+");
char c = 0;
char begin_char = min_(min_('0', min('a', min('/', '+'))), 'A');
char end_char = max_(max('Z', max_('/', '+')), max_('9', 'z'));
char cbuf[16] = {0};
#define writeString(S) fwrite(S, strlen(S), 1, f);
writeString("//Table starts at ");
itoa(begin_char, cbuf, 10);
writeString(cbuf);
writeString("\n");
writeString("char b64_enc_table[");
itoa(end_char - begin_char, cbuf, 10);
writeString(cbuf);
writeString("] = \n{");
writeString(" ");
int ctr;
for(c = begin_char; c < end_char; c++)
{
ctr++;
char d = decodeByte(c);
itoa(d, cbuf, 10);
writeString("");
writeString(cbuf);
writeString(", ");
if (ctr % 10 == 0)
{
writeString("\n ");
}
}
fclose(f);
}
const unsigned char decodeByte(const unsigned char c)
{
unsigned char result = 0xFF;
if (c >= 'A' && c <= 'Z')
{
result = (c - 'A');
}
else if (c >= 'a' && c <= 'z')
{
result = ((c - 'a') + 26);
}
else if (c >= '0' && c <= '9')
{
result = ((c - '0') + 52);
}
else if (c == '+')
{
result = (62);
}
else if (c == '/')
{
result = (63);
}
return result;
}
/// NOTE: this function stores the string on the stack
/// do not try to save the pointer without copying
char* Bin32(uint32_t c)
{
int ctr = 0;
char buf[32 + 3 + 4] = "0b\0";
for(int i = 0; i < 32; i++)
{
const bitpos = (31 - i);
const bit = (c & (1 << bitpos));
if (!ctr && !bit)
{
continue;
}
if (i && (i % 4 == 0))
buf[2+ctr++] = '_';
buf[2 + ctr++] = bit ? '1' : '0';
}
buf[2 + ctr] = '\0';
char* tmp_alloc =
malloc(3 + ctr);
memcpy(tmp_alloc, buf, 3 + ctr);
return tmp_alloc;
}
int main(int argc, char* argv[])
{
char enc[4] = "QUJD";
printf("EncodeByte(%c, 0) = '%c'\n\n", 'Q', encodeByte('Q', 0));
printf("EncodeByte(%c, 1) = '%c'\n\n", 'U', encodeByte('U', 1));
printf("EncodeByte(%c, 2) = '%c'\n\n", 'J', encodeByte('J', 2));
printf("EncodeByte(%c, 3) = '%c'\n\n", 'D', encodeByte('D', 3));
unsigned long x = 'R' | ('B' << 6);
printf("Bin32('R') == %s\n", Bin32('R'));
printf("decodeTo6Bit('Q'), decodeTo6Bit('g') == %s, %s\n", Bin32(decodeTo6Bit('Q')), Bin32(decodeTo6Bit('g')));
printf("Bin32('B') == %s\n", Bin32('B'));
printf("Bin32('C') == %s\n", Bin32('C'));
char dec[3] = {0};
decode4Byte(enc, &dec);
printf("x(enc) = %x\n", *(uint32_t*)enc);
char abc[3] = "ABC";
printf("x('ABC') = %x\n", *(uint32_t*)abc);
printf("%.*s\n\n", 3, dec);
if (argc != 2)
{
printf("wrong number of arguements supplied.\n"
"%s expects one FILE path for the FILE to be decoded",
argv[0]
);
return 1;
}
char* FILE_name = argv[1];
FILE* f = fopen(FILE_name, "rb");
fseek(f, 0, SEEK_END);
int FILE_size = ftell(f);
fseek(f, 0, SEEK_SET);
char * FILE_buffer = malloc(FILE_size);
int dest_offset = 0;
int bytes_read =
fread(FILE_buffer, 1, FILE_size, f);
printf("read %d of %d bytes\n", bytes_read, FILE_size);
char c = FILE_buffer[0];
for(int i = 0; i < FILE_size && c; i += 4)
{
c = FILE_buffer[i];
printf("FILE_buffer[%d] = %c\n", i, c);
if (c == '=')
break;
unsigned long acc;
acc = 0;
for (int j = 0; j < 4; j++)
{
c = FILE_buffer[i + j];
printf("%d ", 6 * j);
printf("%c ", c);
acc |= decodeByte(c);
acc >>= 6;
if (c == 0xFF)
{
fprintf(stderr, "Some error occured while decoding byte %d (c = %c)\n", i, c);
return 1;
}
}
{
printf("acc: %x");
FILE_buffer[dest_offset++] = acc & 0xFF0000;
FILE_buffer[dest_offset++] = acc & 0x00FF00;
FILE_buffer[dest_offset++] = acc & 0x0000FF;
}
if (dest_offset - 3 != ((i / 4) * 3))
{
fprintf(stderr, "Some error occured while decoding byte %d\n", i);
return 1;
}
}
char* dest_name;
dest_name = strcat(FILE_name, ".dec");
f = fopen(dest_name, "w+b");
//FILE_buffer = "Hello you marry people.";
int bytes_written =
fwrite(FILE_buffer, 1, dest_offset, f);
fprintf(stderr, "%d of %d bytes were written\n", bytes_written, dest_offset);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment