Last active
June 25, 2019 05:27
-
-
Save UplinkCoder/3c397d75fc90e7e5a844bdab00dbd000 to your computer and use it in GitHub Desktop.
base64decode_bugged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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