一个RC4加密程序的分析
快雪时晴
2009-2-25
目标程序Secure PE V1.6
=============================================================================================
0040A000 > /EB 02 JMP SHORT 0.0040A004
0040A002 |C606 E8 MOV BYTE PTR DS:[ESI],0E8
0040A005 0000 ADD BYTE PTR DS:[EAX],AL
0040A007 0000 ADD BYTE PTR DS:[EAX],AL
0040A009 5D POP EBP ; kernel32.7C816FD7
0040A00A 81ED D3314000 SUB EBP,0.004031D3
0040A010 8D9D E2314000 LEA EBX,DWORD PTR SS:[EBP+4031E2]
0040A016 53 PUSH EBX
0040A017 C3 RETN
0040A018 8DB5 37324000 LEA ESI,DWORD PTR SS:[EBP+403237]
0040A01E 8BFE MOV EDI,ESI ; ntdll.7C910738
0040A020 BB E2314000 MOV EBX,0.004031E2
0040A025 B9 C3010000 MOV ECX,1C3
0040A02A AD LODS DWORD PTR DS:[ESI]
0040A02B 2BC3 SUB EAX,EBX
0040A02D C1C0 03 ROL EAX,3
0040A030 33C3 XOR EAX,EBX
0040A032 AB STOS DWORD PTR ES:[EDI]
0040A033 43 INC EBX
0040A034 81FB 0B324000 CMP EBX,0.0040320B
0040A03A 75 05 JNZ SHORT 0.0040A041
0040A03C BB E2314000 MOV EBX,0.004031E2
0040A041 ^ E2 E7 LOOPD SHORT 0.0040A02A
0040A043 89AD 92334000 MOV DWORD PTR SS:[EBP+403392],EBP
0040A049 89AD C6364000 MOV DWORD PTR SS:[EBP+4036C6],EBP
0040A04F 89AD D9364000 MOV DWORD PTR SS:[EBP+4036D9],EBP
0040A055 8D85 37324000 LEA EAX,DWORD PTR SS:[EBP+403237]
0040A05B 50 PUSH EAX
0040A05C C3 RETN
//EAX中就是壳自身解码完后要跳转的地址,这里用RETN到达。
0040A118 55 PUSH EBP
0040A119 68 00040000 PUSH 400
0040A11E 52 PUSH EDX ; 1msgbox.0040A1C1
//参照
HWND CreateDialogIndirectParam(
HINSTANCE hInstance, // handle of application instance
LPCDLGTEMPLATE lpTemplate, // address of dialog box template
HWND hWndParent, // handle of owner window
DLGPROC lpDialogFunc, // address of dialog box procedure
LPARAM lParamInit // initialization value
);
这里是PASSWORD验证对话框的lpDialogFunc
0040A11F 6A 00 PUSH 0
0040A121 51 PUSH ECX ; 1msgbox.0040A238
0040A122 50 PUSH EAX ; 1msgbox.00400000
0040A123 FF95 52364000 CALL DWORD PTR SS:[EBP+403652] ; user32.CreateDialogIndirectParamA
0040A1C1 53 PUSH EBX
0040A1C2 56 PUSH ESI ; 1msgbox.0040A27E
0040A1C3 57 PUSH EDI
0040A1C4 55 PUSH EBP
0040A1C5 8BEC MOV EBP,ESP
0040A1C7 BF 366E0000 MOV EDI,6E36
0040A1CC 817D 18 11010000 CMP DWORD PTR SS:[EBP+18],111
//经查VC6自带的头库WINUSER.H:
//#define WM_COMMAND 0x0111
0040A1D3 75 49 JNZ SHORT 1msgbox.0040A21E
0040A1D5 66:817D 1E 0003 CMP WORD PTR SS:[EBP+1E],300
0040A1DB 75 41 JNZ SHORT 1msgbox.0040A21E
0040A1DD 8D8F 48344000 LEA ECX,DWORD PTR DS:[EDI+403448]
//在该行F2下断点,当按键时会断下
0040A1E3 51 PUSH ECX
0040A1E4 51 PUSH ECX
0040A1E5 6A 1A PUSH 1A
0040A1E7 6A 0D PUSH 0D
0040A1E9 FF75 20 PUSH DWORD PTR SS:[EBP+20]
0040A1EC FF97 66364000 CALL DWORD PTR DS:[EDI+403666] ; user32.SendMessageA
0040A1F2 5E POP ESI ; 1msgbox.0040A27E
//执行完后
Stack [0012FB30]=00006E36
ESI=0040A27E (1msgbox.0040A27E)
//
0040A27E 31 00 00 00 00 00 00 00 1.......
即指向我刚才输入的字符“1”
//
该处应该是发送GETTEXT消息,以获取输入文本
查参考
#define WM_GETTEXT 0x000D
//
那么就是获取最长1A(26.)字符长的输入文本
0040A1F3 57 PUSH EDI
0040A1F4 BF 26000000 MOV EDI,26
0040A1F9 E8 F8010000 CALL 1msgbox.0040A3F6
//对输入文本进行计算,哈希算法CALL
0040A1FE 5F POP EDI
0040A1FF 3D 3BFCC4A8 CMP EAX,A8C4FC3B
//比较计算值,下一句不能强制不跳,RC4不能正确解压出原程序
//注意这里该常数是A8C4FC3B,加密密码不一样,该值也会不一样。
//比如我用0000作加密密码,值为
//0040A1FF 3D FA01A713 CMP EAX,13A701FA
0040A204 75 11 JNZ SHORT 1msgbox.0040A217
0040A206 FE87 46344000 INC BYTE PTR DS:[EDI+403446]
//如果验证成功,这里INC 0-->1,强制跳到该处修改无效!
0040A20C 6A 00 PUSH 0
0040A20E FF75 14 PUSH DWORD PTR SS:[EBP+14]
0040A211 FF97 5A364000 CALL DWORD PTR DS:[EDI+40365A] ; user32.EndDialog
0040A217 5D POP EBP
0040A218 5F POP EDI
0040A219 5E POP ESI ; 1msgbox.0040A27E
0040A21A 5B POP EBX
0040A21B 33C0 XOR EAX,EAX
0040A21D C3 RETN
0040A3F6 FC CLD
0040A3F7 33C9 XOR ECX,ECX
0040A3F9 49 DEC ECX
0040A3FA 8BD1 MOV EDX,ECX
0040A3FC 33C0 XOR EAX,EAX
0040A3FE 33DB XOR EBX,EBX
0040A400 AC LODS BYTE PTR DS:[ESI]
//按字节读入输入PASSWORD
0040A401 32C1 XOR AL,CL
0040A403 8ACD MOV CL,CH
0040A405 8AEA MOV CH,DL
0040A407 8AD6 MOV DL,DH
0040A409 B6 08 MOV DH,8
0040A40B 66:D1EB SHR BX,1
0040A40E 66:D1D8 RCR AX,1
0040A411 73 09 JNB SHORT 1msgbox.0040A41C
0040A413 66:35 2083 XOR AX,8320
0040A417 66:81F3 B8ED XOR BX,0EDB8
0040A41C FECE DEC DH
0040A41E ^ 75 EB JNZ SHORT 1msgbox.0040A40B
0040A420 33C8 XOR ECX,EAX
0040A422 33D3 XOR EDX,EBX
0040A424 4F DEC EDI
0040A425 ^ 75 D5 JNZ SHORT 1msgbox.0040A3FC
0040A427 F7D2 NOT EDX
0040A429 F7D1 NOT ECX
0040A42B 8BC2 MOV EAX,EDX
0040A42D C1C0 10 ROL EAX,10
0040A430 66:8BC1 MOV AX,CX
0040A433 C3 RETN
0040A193 AC LODS BYTE PTR DS:[ESI]
//第一次时,DS:[ESI]=[00401001]=A5
//果然!!
0040A194 8D9D 36374000 LEA EBX,DWORD PTR SS:[EBP+403736]
0040A19A 53 PUSH EBX ; 1msgbox.0040A56C
0040A19B 50 PUSH EAX
0040A19C E8 B5030000 CALL 1msgbox.0040A556
//代码解密函数
0040A1A1 AA STOS BYTE PTR ES:[EDI]
0040A1A2 ^ E2 EF LOOPD SHORT 1msgbox.0040A193
0040A1A4 33DB XOR EBX,EBX ; 1msgbox.00401350
0040A1A6 64:8F03 POP DWORD PTR FS:[EBX] ; kernel32.7C816FD7
0040A1A9 58 POP EAX ; kernel32.7C816FD7
0040A1AA BB 50130000 MOV EBX,1350
0040A1AF 81C3 00004000 ADD EBX,1msgbox.00400000
0040A1B5 53 PUSH EBX ; 1msgbox.00401350
0040A1B6 C3 RETN
//还记得未加壳前程序OEP吗,RVA就是00001350,这里就是跳转到原程序执行!
0040A1FF 3D 3BFCC4A8 CMP EAX,A8C4FC3B
0040A204 75 11 JNZ SHORT 1msgbox.0040A217
//强制不跳
0040A206 FE87 46344000 INC BYTE PTR DS:[EDI+403446]
//然后在DS:[EDI+403446]上下硬件读中断
F9继续,中断
0040A14F 80BD 46344000 00 CMP BYTE PTR SS:[EBP+403446],0
0040A156 ^ 74 D8 JE SHORT 1msgbox.0040A130
//中断于此,看上一行,SS:[EBP+403446]正是刚才下硬件读中断的地址
0040A158 BE 00104000 MOV ESI,1msgbox.00401000
0040A15D 8BFE MOV EDI,ESI ; 1msgbox.00401000
0040A15F B9 00100000 MOV ECX,1000
0040A164 60 PUSHAD
0040A165 8D85 48344000 LEA EAX,DWORD PTR SS:[EBP+403448]
//SS:[EBP+403448]存放的就是我们输入的PASSWORD首地址,找到联系了
//Address=0040A27E, (ASCII "1234")
0040A16B 8D9D 36384000 LEA EBX,DWORD PTR SS:[EBP+403836]
0040A171 50 PUSH EAX ; 1msgbox.0040A66C
0040A172 53 PUSH EBX ; 1msgbox.0040A56C
0040A173 E8 66030000 CALL 1msgbox.0040A4DE
//用输入的PASSWORD填充FF个空间
0040A178 8D85 36384000 LEA EAX,DWORD PTR SS:[EBP+403836]
//Address=0040A66C, (ASCII //"12341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341//234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123//4)
//EAX=0040A27E (1msgbox.0040A27E), ASCII "1234"
0040A17E 8D9D 36374000 LEA EBX,DWORD PTR SS:[EBP+403736]
//Address=0040A56C
0040A184 50 PUSH EAX ; 1msgbox.0040A66C
0040A185 53 PUSH EBX ; 1msgbox.0040A56C
0040A186 E8 1B030000 CALL 1msgbox.0040A4A6
//RC4初始化
0040A18B E8 69030000 CALL 1msgbox.0040A4F9
0040A190 61 POPAD
0040A191 33C0 XOR EAX,EAX ; 1msgbox.0040A66C
//下面开始还原原程序(昨晚其实就是找到了这里,我自己没再往上看)
0040A193 AC LODS BYTE PTR DS:[ESI]
0040A194 8D9D 36374000 LEA EBX,DWORD PTR SS:[EBP+403736]
0040A19A 53 PUSH EBX ; 1msgbox.0040A56C
0040A19B 50 PUSH EAX ; 1msgbox.0040A66C
0040A19C E8 B5030000 CALL 1msgbox.0040A556
0040A1A1 AA STOS BYTE PTR ES:[EDI]
0040A1A2 ^ E2 EF LOOPD SHORT 1msgbox.0040A193
0040A1A4 33DB XOR EBX,EBX ; 1msgbox.0040A56C
0040A1A6 64:8F03 POP DWORD PTR FS:[EBX] ; 1msgbox.00401000
0040A1A9 58 POP EAX ; 1msgbox.00401000
0040A1AA BB 50130000 MOV EBX,1350
0040A1AF 81C3 00004000 ADD EBX,1msgbox.00400000
0040A1B5 53 PUSH EBX ; 1msgbox.0040A56C
0040A1B6 C3 RETN
0040A4DE 60 PUSHAD
0040A4DF 8B7C24 24 MOV EDI,DWORD PTR SS:[ESP+24]
0040A4E3 B9 FF000000 MOV ECX,0FF
0040A4E8 8B7424 28 MOV ESI,DWORD PTR SS:[ESP+28]
0040A4EC AC LODS BYTE PTR DS:[ESI]
0040A4ED 84C0 TEST AL,AL
0040A4EF ^ 74 F7 JE SHORT 1msgbox.0040A4E8
0040A4F1 AA STOS BYTE PTR ES:[EDI]
0040A4F2 49 DEC ECX
0040A4F3 ^ 79 F7 JNS SHORT 1msgbox.0040A4EC
0040A4F5 61 POPAD
0040A4F6 C2 0800 RETN 8
0040A66C 31 32 33 34 31 32 33 34 12341234
0040A674 31 32 33 34 31 32 33 34 12341234
0040A67C 31 32 33 34 31 32 33 34 12341234
0040A684 31 32 33 34 31 32 33 34 12341234
0040A68C 31 32 33 34 31 32 33 34 12341234
0040A694 31 32 33 34 31 32 33 34 12341234
0040A69C 31 32 33 34 31 32 33 34 12341234
0040A6A4 31 32 33 34 31 32 33 34 12341234
0040A6AC 31 32 33 34 31 32 33 34 12341234
0040A6B4 31 32 33 34 31 32 33 34 12341234
0040A6BC 31 32 33 34 31 32 33 34 12341234
0040A6C4 31 32 33 34 31 32 33 34 12341234
0040A6CC 31 32 33 34 31 32 33 34 12341234
0040A6D4 31 32 33 34 31 32 33 34 12341234
0040A6DC 31 32 33 34 31 32 33 34 12341234
0040A6E4 31 32 33 34 31 32 33 34 12341234
0040A6EC 31 32 33 34 31 32 33 34 12341234
0040A6F4 31 32 33 34 31 32 33 34 12341234
0040A6FC 31 32 33 34 31 32 33 34 12341234
0040A704 31 32 33 34 31 32 33 34 12341234
0040A70C 31 32 33 34 31 32 33 34 12341234
0040A714 31 32 33 34 31 32 33 34 12341234
0040A71C 31 32 33 34 31 32 33 34 12341234
0040A724 31 32 33 34 31 32 33 34 12341234
0040A72C 31 32 33 34 31 32 33 34 12341234
0040A734 31 32 33 34 31 32 33 34 12341234
0040A73C 31 32 33 34 31 32 33 34 12341234
0040A744 31 32 33 34 31 32 33 34 12341234
0040A74C 31 32 33 34 31 32 33 34 12341234
0040A754 31 32 33 34 31 32 33 34 12341234
0040A75C 31 32 33 34 31 32 33 34 12341234
0040A764 31 32 33 34 31 32 33 34 12341234
0040A76C 00 00 00 00 00 00 00 00 ........
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!