ReverseMe-120(base64解码表) 逆向寒假生涯(21/100)
文章目錄
- 拖進(jìn)ida
- 經(jīng)過(guò)一次base解碼(`sub_E61000`)
- base64解碼表
- 注意 :
- 總結(jié)函數(shù):
- 異或0x25
- 題目總結(jié)
- base64代碼(含有解碼表)
拖進(jìn)ida
用字符串"you_know_how_to_remove_junk_code"來(lái)和輸入值加密改變后的來(lái)比較
經(jīng)過(guò)一次base解碼(sub_E61000)
base64解碼表
其實(shí)呢,它也就是作為base64表和ASCII表之間的一個(gè)橋梁作用,例如00值在這個(gè)base64解碼表第65個(gè)位置(解釋:在ASCII碼表排65,即‘A’,在base64表排00位置,也就這個(gè)對(duì)層關(guān)系)
注意:base64解碼表和base64表不是一個(gè)意思,別混淆
其實(shí)真正轉(zhuǎn)換關(guān)系應(yīng)該是這樣
注意 :
這里的base字符轉(zhuǎn)化為的字節(jié)高2位為0,補(bǔ)上去的,這里的解碼思路和如下編碼思路差不多
if (i == inlen + pad_num - 3 && pad_num != 0) {if(pad_num == 1) {*(p + 1) = base64_alphabet[(int)(cmove_bits(*indata, 6, 2) + cmove_bits(*(indata + 1), 0, 4))];*(p + 2) = base64_alphabet[(int)cmove_bits(*(indata + 1), 4, 2)];*(p + 3) = '=';} else if (pad_num == 2) { // 編碼后的數(shù)據(jù)要補(bǔ)兩個(gè) '='*(p + 1) = base64_alphabet[(int)cmove_bits(*indata, 6, 2)];*(p + 2) = '=';*(p + 3) = '=';}} else { // 處理正常的3字節(jié)的數(shù)據(jù)*(p + 1) = base64_alphabet[cmove_bits(*indata, 6, 2) + cmove_bits(*(indata + 1), 0, 4)];*(p + 2) = base64_alphabet[cmove_bits(*(indata + 1), 4, 2) + cmove_bits(*(indata + 2), 0, 6)];*(p + 3) = base64_alphabet[*(indata + 2) & 0x3f];}只不過(guò)上方用了一個(gè)base64解碼表直接作為橋梁,就解決了這個(gè)問(wèn)題。
總結(jié)函數(shù):
也就是說(shuō),這個(gè)函數(shù)作用就是一個(gè)base64解碼作用。
異或0x25
這個(gè)學(xué)過(guò)ARM的人都知道,load和store的作用,后面外加一個(gè)xor,而v5就是0x25
直接異或即可。。
下方這個(gè)for循環(huán)不滿足條件不會(huì)執(zhí)行:
題目總結(jié)
你的輸入---->base64解碼---->得到v13---->與0x25異或---->與“you_know_how_to_remove_junk_code”比較---->結(jié)果
#include <iostream> #include<Windows.h> int main() {unsigned char a[] = { "you_know_how_to_remove_junk_code" };unsigned char b[32];for (int i = 0; i < 32; ++i) {b[i] = a[i] ^ 0x25;std::cout << b[i];} } \JPzNKJRzMJRzQJzW@HJS@zOPKNzFJA@ XEpQek5LSlJ6TUpSelFKeldASEpTQHpPUEtOekZKQUA=base64代碼(含有解碼表)
// // base64.c // base64 // // Created by guofu on 2017/5/25. // Copyright ? 2017年 guofu. All rights reserved. // /*** 轉(zhuǎn)解碼過(guò)程* 3 * 8 = 4 * 6; 3字節(jié)占24位, 4*6=24* 先將要編碼的轉(zhuǎn)成對(duì)應(yīng)的ASCII值* 如編碼: s 1 3* 對(duì)應(yīng)ASCII值為: 115 49 51* 對(duì)應(yīng)二進(jìn)制為: 01110011 00110001 00110011* 將其6個(gè)分組分4組: 011100 110011 000100 110011* 而計(jì)算機(jī)是以8bit存儲(chǔ), 所以在每組的高位補(bǔ)兩個(gè)0如下:* 00011100 00110011 00000100 00110011對(duì)應(yīng):28 51 4 51* 查找base64 轉(zhuǎn)換表 對(duì)應(yīng) c z E z* * 解碼* c z E z* 對(duì)應(yīng)ASCII值為 99 122 69 122* 對(duì)應(yīng)表base64_suffix_map的值為 28 51 4 51* 對(duì)應(yīng)二進(jìn)制值為 00011100 00110011 00000100 00110011* 依次去除每組的前兩位, 再拼接成3字節(jié)* 即: 01110011 00110001 00110011* 對(duì)應(yīng)的就是s 1 3*/#include "base64.h"#include <stdio.h> #include <stdlib.h>// base64 轉(zhuǎn)換表, 共64個(gè) static const char base64_alphabet[] = {'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','+', '/'};// 解碼時(shí)使用 static const unsigned char base64_suffix_map[256] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,255, 254, 255, 255, 255, 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, 255, 255, 255, 255, 255,255, 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, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255 };static char cmove_bits(unsigned char src, unsigned lnum, unsigned rnum) {src <<= lnum; // src = src << lnum;src >>= rnum; // src = src >> rnum;return src; }int base64_encode(const char *indata, int inlen, char *outdata, int *outlen) {int ret = 0; // return valueif (indata == NULL || inlen == 0) {return ret = -1;}int in_len = 0; // 源字符串長(zhǎng)度, 如果in_len不是3的倍數(shù), 那么需要補(bǔ)成3的倍數(shù)int pad_num = 0; // 需要補(bǔ)齊的字符個(gè)數(shù), 這樣只有2, 1, 0(0的話不需要拼接, )if (inlen % 3 != 0) {pad_num = 3 - inlen % 3;}in_len = inlen + pad_num; // 拼接后的長(zhǎng)度, 實(shí)際編碼需要的長(zhǎng)度(3的倍數(shù))int out_len = in_len * 8 / 6; // 編碼后的長(zhǎng)度char *p = outdata; // 定義指針指向傳出data的首地址//編碼, 長(zhǎng)度為調(diào)整后的長(zhǎng)度, 3字節(jié)一組for (int i = 0; i < in_len; i+=3) {int value = *indata >> 2; // 將indata第一個(gè)字符向右移動(dòng)2bit(丟棄2bit)char c = base64_alphabet[value]; // 對(duì)應(yīng)base64轉(zhuǎn)換表的字符*p = c; // 將對(duì)應(yīng)字符(編碼后字符)賦值給outdata第一字節(jié)//處理最后一組(最后3字節(jié))的數(shù)據(jù)if (i == inlen + pad_num - 3 && pad_num != 0) {if(pad_num == 1) {*(p + 1) = base64_alphabet[(int)(cmove_bits(*indata, 6, 2) + cmove_bits(*(indata + 1), 0, 4))];*(p + 2) = base64_alphabet[(int)cmove_bits(*(indata + 1), 4, 2)];*(p + 3) = '=';} else if (pad_num == 2) { // 編碼后的數(shù)據(jù)要補(bǔ)兩個(gè) '='*(p + 1) = base64_alphabet[(int)cmove_bits(*indata, 6, 2)];*(p + 2) = '=';*(p + 3) = '=';}} else { // 處理正常的3字節(jié)的數(shù)據(jù)*(p + 1) = base64_alphabet[cmove_bits(*indata, 6, 2) + cmove_bits(*(indata + 1), 0, 4)];*(p + 2) = base64_alphabet[cmove_bits(*(indata + 1), 4, 2) + cmove_bits(*(indata + 2), 0, 6)];*(p + 3) = base64_alphabet[*(indata + 2) & 0x3f];}p += 4;indata += 3;}if(outlen != NULL) {*outlen = out_len;}return ret; }int base64_decode(const char *indata, int inlen, char *outdata, int *outlen) {int ret = 0;if (indata == NULL || inlen <= 0 || outdata == NULL || outlen == NULL) {return ret = -1;}if (inlen % 4 != 0) { // 需要解碼的數(shù)據(jù)不是4字節(jié)倍數(shù)return ret = -2;}int t = 0, x = 0, y = 0, i = 0;unsigned char c = 0;int g = 3;while (indata[x] != 0) {// 需要解碼的數(shù)據(jù)對(duì)應(yīng)的ASCII值對(duì)應(yīng)base64_suffix_map的值c = base64_suffix_map[indata[x++]];if (c == 255) return -1;// 對(duì)應(yīng)的值不在轉(zhuǎn)碼表中if (c == 253) continue;// 對(duì)應(yīng)的值是換行或者回車if (c == 254) { c = 0; g--; }// 對(duì)應(yīng)的值是'='t = (t<<6) | c; // 將其依次放入一個(gè)int型中占3字節(jié)if (++y == 4) {outdata[i++] = (unsigned char)((t>>16)&0xff);if (g > 1) outdata[i++] = (unsigned char)((t>>8)&0xff);if (g > 2) outdata[i++] = (unsigned char)(t&0xff);y = t = 0;}}if (outlen != NULL) {*outlen = i;}return ret; }總結(jié)
以上是生活随笔為你收集整理的ReverseMe-120(base64解码表) 逆向寒假生涯(21/100)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: EASYHOOK逆向寒假生涯(20/10
- 下一篇: crackme 逆向寒假生涯(22/1