Base64

终于体验到什么叫一杯茶,一包烟,一个bug改一天了

  • 下面总结一下base64:


    百度百科上面讲 “Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法”。在ASCII码中规定,0126这95个字符属于可打印字符。base64索引表: 直接上两张图就能看懂base64的编码方式。Base64
    Base64
    Base643个字符一组,高位补0,"="填充


    下面直接上该两天bug的成果,应该还有其他没发现的bug。写的比较麻烦:
#include<stdio.h>
#include<string.h>
const char* base64_index = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
void encode(unsigned char* encodeStr){
    unsigned char decode[1001] = {0}, exc;
    int yu, len, i = 0, j = 0;
    len = strlen(encodeStr);
    yu = len % 3;
    while(j < len - 3){
        decode[0 + i] = encodeStr[0 + j] >> 2;
        exc = (encodeStr[0 + j] << 4) & 0x30;
        decode[1 + i] = (encodeStr[1 + j] >> 4) | exc;
        exc = (encodeStr[1 + j] << 2) & 0x3c;
        decode[2 + i] = encodeStr[2 + j] >> 6 | exc;
        decode[3 + i] = encodeStr[2 + j] & 0x3f;
        i += 4;
        j = i - (i/4);
    }
    //最后三位单独处理
    if(yu == 0){
        decode[0 + i] = encodeStr[0 + j] >> 2;
        exc = (encodeStr[0 + j] << 4) & 0x30;
        decode[1 + i] = (encodeStr[1 + j] >> 4) | exc;
        exc = (encodeStr[1 + j] << 2) & 0x3c;
        decode[2 + i] = encodeStr[2 + j] >> 6 | exc;
        decode[3 + i] = encodeStr[2 + j] & 0x3f;
    }
    else if(yu == 1){
        decode[0 + i] = encodeStr[0 + j] >> 2;
        exc = (encodeStr[0 + j] << 4) & 0x30;
        decode[1 + i] = exc;
        decode[2 + i] = 64;
        decode[3 + i] = 64;
    }
    else if(yu == 2){
        decode[0 + i] = encodeStr[0 + j] >> 2;
        exc = (encodeStr[0 + j] << 4) & 0x30;
        decode[1 + i] = (encodeStr[1 + j] >> 4) | exc;
        exc = (encodeStr[1 + j] << 2) & 0x3c;
        decode[2 + i] = exc;
        decode[3 + i] = 64;
    }
    i = 0;
    while(decode[i] || decode[i + 1]){   //这里针对形如0、4、8这种特殊字符
        printf("%c", base64_index[decode[i]]);
        i++;
    }
    puts("");
    return ;
}
void decode(unsigned char* decodeStr){
    unsigned char* decode[1001] = {0}, exc;
    int len, i = 0, j;
    len = strlen(decodeStr);
    while(i < len){
        for(j = 0; j < 65; j++)
            if(decodeStr[i] == base64_index[j]){
                decodeStr[i] = j;
                break;
            }
        i++;
    }
    i = 0; j = 0;
    while(i < len - 4){
        decode[j + 0] = (decodeStr[i + 0] << 2) | ((decodeStr[i + 1] >> 4) & 0x3);
        decode[j + 1] = (decodeStr[i + 1] << 4) | ((decodeStr[i + 2] >> 2) & 0xf);
        decode[j + 2] = (decodeStr[i + 2] << 6) | (decodeStr[i + 3] & 0x3f);
        i += 4;
        j += 3;
    }
    decode[j + 0] = (decodeStr[i + 0] << 2) | ((decodeStr[i + 1] >> 4) & 0x3);
    if(decodeStr[i + 2] != 64)
        decode[j + 1] = (decodeStr[i + 1] << 4) | ((decodeStr[i + 2] >> 2) & 0xf);
    if(decodeStr[i + 3] != 64)
        decode[j + 2] = (decodeStr[i + 2] << 6) | (decodeStr[i + 3] & 0x3f);
    i = 0;
    while(decode[i]){
    printf("%c", decode[i++]);
    }
    puts("");
    return ;
}
int main()
{
    int flag;
    unsigned char encodeStr[1001] = {0};
    unsigned char decodeStr[1001] = {0};
    while(1){
        printf("1.加密\n2.解密\n");
        scanf("%d", &flag);
        if(flag == 1){
        printf("输入明文: ");
        scanf("%s", decodeStr);
        printf("密文: ");
        encode(decodeStr);
        }
        if(flag == 2){
            printf("输入密文: ");
            scanf("%s", encodeStr);
            printf("明文: ");
            decode(encodeStr);
        }
    }
}

拖进ida中伪代码相差不大。锻炼一下自己的汇编功底。根据源代码再看汇编会容易很多,这里只挑了主要的加密算法分析,解密算法类似。

.text:004013C8                 mov     edx, [ebp+j]
.text:004013CB                 mov     eax, [ebp+unk]  ; 相当于encodeStr[0 + j]
.text:004013CE                 add     eax, edx
.text:004013D0                 movzx   eax, byte ptr [eax] ; 将eax高位用0填充,后面同理
.text:004013D3                 shr     al, 2           ; 右移两位
.text:004013D6                 mov     edx, eax
.text:004013D8                 lea     ecx, [ebp+var_402] ; 取明文数组地址
.text:004013DE                 mov     eax, [ebp+i]
.text:004013E1                 add     eax, ecx        ; 这里eax存的是数组的地址
.text:004013E3                 mov     [eax], dl
.text:004013E5                 mov     edx, [ebp+j]
.text:004013E8                 mov     eax, [ebp+unk]
.text:004013EB                 add     eax, edx
.text:004013ED                 movzx   eax, byte ptr [eax]
.text:004013F0                 movzx   eax, al
.text:004013F3                 shl     eax, 4          ; 左移四位与0x30与运算
.text:004013F6                 and     eax, 30h
.text:004013F9                 mov     [ebp+exc], al
.text:004013FC                 mov     eax, [ebp+i]
.text:004013FF                 lea     edx, [eax+1]
.text:00401402                 mov     eax, [ebp+j]
.text:00401405                 add     eax, 1          ; encodeStr[1 + j]
.text:00401408                 mov     ecx, eax
.text:0040140A                 mov     eax, [ebp+unk]
.text:0040140D                 add     eax, ecx
.text:0040140F                 movzx   eax, byte ptr [eax]
.text:00401412                 shr     al, 4           ; 右移4位,或运算
.text:00401415                 or      al, [ebp+exc]
.text:00401418                 mov     byte ptr [ebp+edx+var_402], al ; decode[1 + i]
.text:0040141F                 mov     eax, [ebp+j]
.text:00401422                 add     eax, 1
.text:00401425                 mov     edx, eax
.text:00401427                 mov     eax, [ebp+unk]  ; encodeStr[1 + j]
.text:0040142A                 add     eax, edx
.text:0040142C                 movzx   eax, byte ptr [eax]
.text:0040142F                 movzx   eax, al
.text:00401432                 shl     eax, 2
.text:00401435                 and     eax, 3Ch        ; 左移2位,与运算,保存到exc中
.text:00401438                 mov     [ebp+exc], al
.text:0040143B                 mov     eax, [ebp+i]
.text:0040143E                 lea     edx, [eax+2]
.text:00401441                 mov     eax, [ebp+j]
.text:00401444                 add     eax, 2          ; encodeStr[2 + j]
.text:00401447                 mov     ecx, eax
.text:00401449                 mov     eax, [ebp+unk]
.text:0040144C                 add     eax, ecx
.text:0040144E                 movzx   eax, byte ptr [eax]
.text:00401451                 shr     al, 6           ; 右移6位,或运算
.text:00401454                 or      al, [ebp+exc]
.text:00401457                 mov     byte ptr [ebp+edx+var_402], al ; decode[2 + i]
.text:0040145E                 mov     eax, [ebp+i]
.text:00401461                 add     eax, 3          ; decode[3 + i]
.text:00401464                 mov     edx, [ebp+j]
.text:00401467                 add     edx, 2          ; encodeStr[2 + j]
.text:0040146A                 mov     ecx, edx
.text:0040146C                 mov     edx, [ebp+unk]
.text:0040146F                 add     edx, ecx
.text:00401471                 movzx   edx, byte ptr [edx]
.text:00401474                 and     edx, 3Fh        ; &0x3f
.text:00401477                 mov     byte ptr [ebp+eax+var_402], dl
.text:0040147E                 add     [ebp+i], 4      ; i + 4
.text:00401482                 mov     eax, [ebp+i]
.text:00401485                 lea     edx, [eax+3]
.text:00401488                 test    eax, eax
.text:0040148A                 cmovs   eax, edx
.text:0040148D                 sar     eax, 2
.text:00401490                 mov     edx, eax        ; i / 4
.text:00401492                 mov     eax, [ebp+i]
.text:00401495                 sub     eax, edx
.text:00401497                 mov     [ebp+j], eax
.text:0040149A
.text:0040149A loc_40149A:                             ; CODE XREF: _encode+73↑j
.text:0040149A                 mov     eax, [ebp+var_14]
.text:0040149D                 sub     eax, 3
.text:004014A0                 cmp     eax, [ebp+j]    ; while(j < len - 3)
.text:004014A3                 jg      loc_4013C8