在研究http://bbs.pediy.com/showthread.php?threadid=30769 里的creakme的时候,把Base64算法也研究了一下。
反汇编如下
004018A0 /$ 55 PUSH EBP
004018A1 |. 56 PUSH ESI
004018A2 |. 57 PUSH EDI
004018A3 |. 53 PUSH EBX
004018A4 |. 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14]
004018A8 |. 8B6C24 18 MOV EBP,DWORD PTR SS:[ESP+18]
004018AC |. 8B7C24 1C MOV EDI,DWORD PTR SS:[ESP+1C]
004018B0 |> 85ED /TEST EBP,EBP
004018B2 |. 74 6A |JE SHORT kiToKGNm.0040191E
004018B4 |. 8A06 |MOV AL,BYTE PTR DS:[ESI]
004018B6 |. 8A56 01 |MOV DL,BYTE PTR DS:[ESI+1]
004018B9 |. 8A5E 02 |MOV BL,BYTE PTR DS:[ESI+2]
004018BC |. 8AE0 |MOV AH,AL
004018BE |. 8AF2 |MOV DH,DL
004018C0 |. 8AFB |MOV BH,BL
004018C2 |. 80E4 03 |AND AH,3
004018C5 |. 80E6 0F |AND DH,0F
004018C8 |. 80E7 3F |AND BH,3F
004018CB |. C0E8 02 |SHR AL,2
004018CE |. C0EA 04 |SHR DL,4
004018D1 |. C0EB 06 |SHR BL,6
004018D4 |. C0E4 04 |SHL AH,4
004018D7 |. C0E6 02 |SHL DH,2
004018DA |. 0AE2 |OR AH,DL
004018DC |. 0ADE |OR BL,DH
004018DE |. 0FB6D0 |MOVZX EDX,AL
004018E1 |. 0FB6CC |MOVZX ECX,AH
004018E4 |. 8A82 60304000 |MOV AL,BYTE PTR DS:[EDX+403060]
004018EA |. 8AA1 60304000 |MOV AH,BYTE PTR DS:[ECX+403060]
004018F0 |. 0FB6D3 |MOVZX EDX,BL
004018F3 |. 0FB6CF |MOVZX ECX,BH
004018F6 |. 8A9A 60304000 |MOV BL,BYTE PTR DS:[EDX+403060]
004018FC |. 8AB9 60304000 |MOV BH,BYTE PTR DS:[ECX+403060]
00401902 |. 25 FFFF0000 |AND EAX,0FFFF
00401907 |. C1E3 10 |SHL EBX,10
0040190A |. 83C6 03 |ADD ESI,3
0040190D |. 0BC3 |OR EAX,EBX
0040190F |. AB |STOS DWORD PTR ES:[EDI]
00401910 |. 83ED 03 |SUB EBP,3
00401913 |.^ 79 9B \JNS SHORT kiToKGNm.004018B0
00401915 |. 03FD ADD EDI,EBP
00401917 |> C607 3D /MOV BYTE PTR DS:[EDI],3D
0040191A |. 47 |INC EDI
0040191B |. 45 |INC EBP
0040191C |.^ 75 F9 \JNZ SHORT kiToKGNm.00401917
0040191E |> 8BC7 MOV EAX,EDI
00401920 |. 5B POP EBX
00401921 |. 66:8928 MOV WORD PTR DS:[EAX],BP
00401924 |. 5F POP EDI
00401925 |. 5E POP ESI
00401926 |. 2B4424 10 SUB EAX,DWORD PTR SS:[ESP+10]
0040192A |. 5D POP EBP
0040192B \. C2 0C00 RETN 0C
函数有三个参数,依次是输入缓冲区首址,输入缓冲区长度,输出缓冲区首址,分别保存在寄存器esi,epb和edi中。
开始是保护现场和取参数,没什么好说的
004018A0 /$ 55 PUSH EBP
004018A1 |. 56 PUSH ESI
004018A2 |. 57 PUSH EDI
004018A3 |. 53 PUSH EBX
004018A4 |. 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14]
004018A8 |. 8B6C24 18 MOV EBP,DWORD PTR SS:[ESP+18]
004018AC |. 8B7C24 1C MOV EDI,DWORD PTR SS:[ESP+1C]
判断字符串长度是否为0,为0则恢复现场返回
004018B0 |> 85ED /TEST EBP,EBP
...
0040191E |> 8BC7 MOV EAX,EDI
00401920 |. 5B POP EBX
00401921 |. 66:8928 MOV WORD PTR DS:[EAX],BP
00401924 |. 5F POP EDI
00401925 |. 5E POP ESI
00401926 |. 2B4424 10 SUB EAX,DWORD PTR SS:[ESP+10]
0040192A |. 5D POP EBP
0040192B \. C2 0C00 RETN 0C
后面是算法的核心,将3字节凑成4字节。首先是取3个字节,分别存到寄存器al,dl和bl中,并复制一份保存到ah,dh和bh中。
004018B4 |. 8A06 |MOV AL,BYTE PTR DS:[ESI]
004018B6 |. 8A56 01 |MOV DL,BYTE PTR DS:[ESI+1]
004018B9 |. 8A5E 02 |MOV BL,BYTE PTR DS:[ESI+2]
004018BC |. 8AE0 |MOV AH,AL
004018BE |. 8AF2 |MOV DH,DL
004018C0 |. 8AFB |MOV BH,BL
经过如下操作后,al保存第一字节的高6位,ah保存第一字节的低2位,dl保存第二字节的高4位,dh保存第二字节的低4位,bl保存第三字节的高2位,bh保存第三字节的低6位
004018C2 |. 80E4 03 |AND AH,3
004018C5 |. 80E6 0F |AND DH,0F
004018C8 |. 80E7 3F |AND BH,3F
004018CB |. C0E8 02 |SHR AL,2
004018CE |. C0EA 04 |SHR DL,4
004018D1 |. C0EB 06 |SHR BL,6
004018D4 |. C0E4 04 |SHL AH,4
004018D7 |. C0E6 02 |SHL DH,2
中间两个字节拼凑一下,拼凑之后3个字节变成4个字节,al保存第1字节,ah保存第2字节,bl保存第3字节,bh保存第4字节
004018DA |. 0AE2 |OR AH,DL
004018DC |. 0ADE |OR BL,DH
从Base64索引表中取相应的数据
004018DE |. 0FB6D0 |MOVZX EDX,AL
004018E1 |. 0FB6CC |MOVZX ECX,AH
004018E4 |. 8A82 60304000 |MOV AL,BYTE PTR DS:[EDX+403060]
004018EA |. 8AA1 60304000 |MOV AH,BYTE PTR DS:[ECX+403060]
004018F0 |. 0FB6D3 |MOVZX EDX,BL
004018F3 |. 0FB6CF |MOVZX ECX,BH
004018F6 |. 8A9A 60304000 |MOV BL,BYTE PTR DS:[EDX+403060]
004018FC |. 8AB9 60304000 |MOV BH,BYTE PTR DS:[ECX+403060]
拷贝数据到目的缓冲区,再根据epb是否为0判断是否需要继续循环
00401902 |. 25 FFFF0000 |AND EAX,0FFFF
00401907 |. C1E3 10 |SHL EBX,10
0040190A |. 83C6 03 |ADD ESI,3
0040190D |. 0BC3 |OR EAX,EBX
0040190F |. AB |STOS DWORD PTR ES:[EDI]
00401910 |. 83ED 03 |SUB EBP,3
00401913 |.^ 79 9B \JNS SHORT kiToKGNm.004018B0
如果数据不是3的倍数,则在最后填充'=',直到是3的倍数
00401915 |. 03FD ADD EDI,EBP
00401917 |> C607 3D /MOV BYTE PTR DS:[EDI],3D
0040191A |. 47 |INC EDI
0040191B |. 45 |INC EBP
0040191C |.^ 75 F9 \JNZ SHORT kiToKGNm.00401917
最后将给目的缓冲区字符串结尾加'\0',恢复现场,返回目的缓冲区的长度,返回。
0040191E |> \8BC7 MOV EAX,EDI
00401920 |. 5B POP EBX
00401921 |. 66:8928 MOV WORD PTR DS:[EAX],BP
00401924 |. 5F POP EDI
00401925 |. 5E POP ESI
00401926 |. 2B4424 10 SUB EAX,DWORD PTR SS:[ESP+10]
0040192A |. 5D POP EBP
0040192B \. C2 0C00 RETN 0C
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!