好友
阅读权限40
听众
最后登录1970-1-1
|
Emil
发表于 2015-11-14 10:58
本帖最后由 丶纯情小强 于 2015-11-14 11:23 编辑
目标:易语言程序511 源码加密算法
平台: windows xp
工具:OllyDbg.exe WinHex
找到以前写的一个源码,发现加密了,然后密码又忘记了,所以有了分析加密算法的想法
嗯,大半夜的,也没事情做,说干就干,看看能不能追出密码来
1.首先定位关键
od载入e.exe(没有的话,自己装一个易语言程序),载入完毕后,程序,打开一个加密了源码的易语言,显示如下:
现在我们随便输入错误的密码,错误3次后会提示如下:
又或者直接esc,取消输入密码,提示如下:
这样我们可以通过上述图中提示的错误信息进行定位.
2.初步分析
定位了关键位置后,解析下来,就是简单分析加密算法,通过步骤1,我最终定位在这个位置,我输入了假码:52pojie.cn
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 0044800D . 83F8 01 cmp eax,0x1 //判断是否终止输入密码或有没有输入密码[/size]
[size=4] 00448010 . 74 0A je short e.0044801C[/size]
[size=4] 00448012 . 68 30915800 push e.00589130 ; 您中止了密码输入,因此无法访问被密码保护的指定源程序![/size]
[size=4] 00448017 . E9 D9000000 jmp e.004480F5[/size]
[size=4] 0044801C > 8B85 00FFFFFF mov eax,dword ptr ss:[ebp-0x100] //如果输入了密码,则会跳转到这里,eax的值即输入的密码[/size]
[size=4] 00448022 . 6A 08 push 0x8[/size]
[size=4] 00448024 . 50 push eax[/size]
[size=4] 00448025 . 6A 0A push 0xA[/size]
[size=4] 00448027 . 8BF8 mov edi,eax[/size]
[size=4]
然后F8往下跟
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 00448029 . FF53 78 call dword ptr ds:[ebx+0x78] ; 对密码进行计算【功能1】[/size]
[size=4] . [/size]
[size=4] 00448047 . 6A 00 push 0x0[/size]
[size=4] 00448049 . 6A 20 push 0x20[/size]
[size=4] 0044804B . 50 push eax[/size]
[size=4] 0044804C . 8BCE mov ecx,esi[/size]
[size=4] 0044804E . FF52 20 call dword ptr ds:[edx+0x20] ; 打开源码文件[/size]
[size=4] 00448051 . 8B16 mov edx,dword ptr ds:[esi][/size]
[size=4] 00448053 . 6A 00 push 0x0[/size]
[size=4] 00448055 . 6A 08 push 0x8[/size]
[size=4] 00448057 . 8BCE mov ecx,esi[/size]
[size=4] 00448059 . FF52 28 call dword ptr ds:[edx+0x28] ; 设置读取文件的位置,文件偏移+8[/size]
[size=4] 0044805C . 8B06 mov eax,dword ptr ds:[esi][/size]
[size=4] 0044805E . 8D8D 04FFFFFF lea ecx,dword ptr ss:[ebp-0xFC][/size]
[size=4] 00448064 . 6A 20 push 0x20[/size]
[size=4] 00448066 . 51 push ecx[/size]
[size=4] 00448067 . 8BCE mov ecx,esi[/size]
[size=4] 00448069 . FF50 34 call dword ptr ds:[eax+0x34] ; 接着就是读取源码文件的内容,会有算法[/size]
[size=4] 0044806C . 83F8 20 cmp eax,0x20[/size]
[size=4] 0044806F . 0F85 88000000 jnz e.004480FD[/size]
[size=4] 00448075 . 8D95 28FFFFFF lea edx,dword ptr ss:[ebp-0xD8][/size]
[size=4] 0044807B . 52 push edx[/size]
[size=4] 0044807C . 57 push edi[/size]
[size=4] 0044807D . 6A 0C push 0xC[/size]
[size=4] 0044807F . FF53 78 call dword ptr ds:[ebx+0x78] ; 经过一系列算法[/size]
[size=4]
F8一直到这里
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 00448082 . 8D85 28FFFFFF lea eax,dword ptr ss:[ebp-0xD8] //eax的内容是根据假码算出的一串字符[/size]
[size=4] 00448088 . 8D8D 04FFFFFF lea ecx,dword ptr ss:[ebp-0xFC] //ecx的内容,是根据源码经过算法出现的(用正确的码比较下就懂了)[/size]
[size=4] 0044808E . 50 push eax //如果eax=ecx表示解密成功 [/size]
[size=4] 0044808F . 51 push ecx //不要尝试爆破,要不然你会失望的 [/size]
[size=4] 00448090 . E8 389D0B00 call e.00501DCD [/size]
[size=4]
3.针对分析
3.1 针对功能1,进行分析
call dword ptr ds:[ebx+0x78] ; 对密码进行计算【功能1】
主要功能:
1.对输入的密码进行md5计算,并且按照1234=3412进行逆序,得到一组32长度字符串
2.用输入的密码作为key进行算法3(key),得到一组加密密文模版,具体见3.2分析
3.2 通过上述2步,我们对流程已经有了个大概的了解,接着我们继续细致的分析,首先看下读取了源码那些内容
通过下ReadFile断点,可以发现读取了源码文件
偏移位置+8 读取大小 0x20(32)长度大小,们用winhex打开源码,看下到底读取了什么
这个是OD读取的内容
这个是winhex查看的内容
嗯,很好,和我们想象中的一模一样,那么我们分析是对的了,我们继续单补走,看看读取了之后,他搞了什么鬼,走到了这个Call
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065C82 6A 01 push 0x1[/size]
[size=4] 01065C84 57 push edi[/size]
[size=4] 01065C85 55 push ebp[/size]
[size=4] 01065C86 53 push ebx[/size]
[size=4] 01065C87 8BCE mov ecx,esi[/size]
[size=4] 01065C89 E8 E2020000 call krnln.01065F70 //F7 进入 【功能2】[/size]
[size=4] 01065C8E 8BC7 mov eax,edi[/size]
[size=4] 01065C90 5F pop edi[/size]
[size=4] 01065C91 5D pop ebp[/size]
[size=4] 01065C92 5B pop ebx[/size]
[size=4] 01065C93 5E pop esi[/size]
[size=4] 01065C94 C2 0800 retn 0x8[/size]
[size=4]
F7进入后,来到这里,重要,需要仔细分析(我们标记下,记录为 【功能2】)
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065F70 55 push ebp [/size]
[size=4] 01065F71 8BEC mov ebp,esp[/size]
[size=4] 01065F73 81EC 2C010000 sub esp,0x12C[/size]
[size=4] 01065F79 8B45 14 mov eax,dword ptr ss:[ebp+0x14][/size]
[size=4] 01065F7C 53 push ebx[/size]
[size=4] 01065F7D 56 push esi[/size]
[size=4] 01065F7E 57 push edi[/size]
[size=4] 01065F7F 85C0 test eax,eax[/size]
[size=4] .[/size]
[size=4] .[/size]
[size=4] .[/size]
[size=4] 01066160 5F pop edi[/size]
[size=4] 01066161 5E pop esi[/size]
[size=4] 01066162 5B pop ebx[/size]
[size=4] 01066163 8BE5 mov esp,ebp[/size]
[size=4] 01066165 5D pop ebp[/size]
[size=4] 01066166 C2 1000 retn 0x10[/size]
[size=4]
ret 10 有4个参数,我们去看看堆栈窗口,如图,看到了,读取的内容也被当作参数传递进来了,我们看看,到底做了什么
我们继续看这个call里面做了什么,F8一直单步走,遇到第一个call,停止
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065FF1 8D0C9D 00000000 lea ecx,dword ptr ds:[ebx*4][/size]
[size=4] 01065FF8 51 push ecx[/size]
[size=4] 01065FF9 66:A5 movs word ptr es:[edi],word ptr ds:[esi][/size]
[size=4] 01065FFB E8 80FEFFFF call krnln.01065E80 //call 标记1[/size]
[size=4] 01066000 8B45 10 mov eax,dword ptr ss:[ebp+0x10][/size]
[size=4] 01066003 83C4 08 add esp,0x8[/size]
[size=4] 01066006 99 cdq[/size]
[size=4] 01066007 81E2 FF0F0000 and edx,0xFFF[/size]
[size=4]
中间有个call,没什么作用,我们继续走,到这里第三个call停止
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01066046 50 push eax[/size]
[size=4] 01066047 51 push ecx[/size]
[size=4] 01066048 56 push esi[/size]
[size=4] 01066049 E8 A2FEFFFF call krnln.01065EF0 //call 标记2[/size]
[size=4] 0106604E 8B7D 08 mov edi,dword ptr ss:[ebp+0x8][/size]
[size=4] 01066051 83C4 0C add esp,0xC[/size]
[size=4] 01066054 81E7 FF0F0080 and edi,0x80000FFF[/size]
[size=4]
以及第四个call,仔细看,发现【功能2】这段程序,里面的call,主要都是我们标记的3个call,所以,我们需要分析这3个call都做了什么
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01066081 43 inc ebx[/size]
[size=4] 01066082 83C6 04 add esi,0x4[/size]
[size=4] 01066085 E8 36FDFFFF call krnln.01065DC0 //call 标记3[/size]
[size=4] 0106608A 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-0x12C][/size]
[size=4] 01066090 8D4F 24 lea ecx,dword ptr ds:[edi+0x24][/size]
[size=4]
call 1 的核心算法
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065EAE 8B4D 08 mov ecx,dword ptr ss:[ebp+0x8][/size]
[size=4] 01065EB1 85C9 test ecx,ecx //第一个参数不为0的时候进行算法操作[/size]
[size=4] 01065EB3 7E 10 jle short krnln.01065EC5[/size]
[size=4] 01065EB5 FEC3 inc bl[/size]
[size=4] 01065EB7 8A041E mov al,byte ptr ds:[esi+ebx][/size]
[size=4] 01065EBA 02D0 add dl,al[/size]
[size=4] 01065EBC 860416 xchg byte ptr ds:[esi+edx],al[/size]
[size=4] 01065EBF 88041E mov byte ptr ds:[esi+ebx],al[/size]
[size=4] 01065EC2 49 dec ecx[/size]
[size=4] 01065EC3 ^ 75 F0 jnz short krnln.01065EB5 //根据传入的值,进行算法操作[/size]
[size=4]
call 2 的核心算法 和算法1有点类似,但是又不一样 3个参数
参数1 加密后,返回的内容
参数2 控制循环次数
参数3 循环的时候,需要操作的数据
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065F23 8B4D 0C mov ecx,dword ptr ss:[ebp+0xC][/size]
[size=4] 01065F26 85C9 test ecx,ecx[/size]
[size=4] 01065F28 7E 19 jle short krnln.01065F43[/size]
[size=4] 01065F2A FEC3 inc bl[/size]
[size=4] 01065F2C 8A041E mov al,byte ptr ds:[esi+ebx][/size]
[size=4] 01065F2F 02D0 add dl,al[/size]
[size=4] 01065F31 860416 xchg byte ptr ds:[esi+edx],al[/size]
[size=4] 01065F34 88041E mov byte ptr ds:[esi+ebx],al[/size]
[size=4] 01065F37 020416 add al,byte ptr ds:[esi+edx][/size]
[size=4] 01065F3A 8A0406 mov al,byte ptr ds:[esi+eax][/size]
[size=4] 01065F3D 3007 xor byte ptr ds:[edi],al[/size]
[size=4] 01065F3F 47 inc edi[/size]
[size=4] 01065F40 49 dec ecx[/size]
[size=4] 01065F41 ^ 75 E7 jnz short krnln.01065F2A[/size]
[size=4]
call 3的核心算法,算是3个里面最复杂一个了 3个参数,根据参数1,和00-ff进行算法运算
参数1 类似密钥
参数2 参数1大小,或者说长度
参数3 返回数据用
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065DF1 B9 40000000 mov ecx,0x40[/size]
[size=4] 01065DF6 BE 30D51901 mov esi,krnln.0119D530 //这个地址的内容是00-FF[/size]
[size=4] 01065DFB 8BFB mov edi,ebx[/size]
[size=4] 01065DFD F3:A5 rep movs dword ptr es:[edi],dword ptr ds> [/size]
[size=4] 01065DFF 3BC2 cmp eax,edx[/size]
[size=4]
算法核心代码
[Asm] 纯文本查看 复制代码 [/size]
[size=4] 01065E0D /7E 68 jle short krnln.01065E77[/size]
[size=4] 01065E0F |33F6 xor esi,esi[/size]
[size=4] 01065E11 |55 push ebp[/size]
[size=4] 01065E12 |885424 20 mov byte ptr ss:[esp+0x20],dl[/size]
[size=4] 01065E16 |33C9 xor ecx,ecx[/size]
[size=4] 01065E18 |8B7C24 20 mov edi,dword ptr ss:[esp+0x20][/size]
[size=4] 01065E1C |8B6C24 18 mov ebp,dword ptr ss:[esp+0x18][/size]
[size=4] 01065E20 |8A041E mov al,byte ptr ds:[esi+ebx][/size]
[size=4] 01065E23 |81E7 FF000000 and edi,0xFF[/size]
[size=4] 01065E29 |33D2 xor edx,edx[/size]
[size=4] 01065E2B |8A142F mov dl,byte ptr ds:[edi+ebp][/size]
[size=4] 01065E2E |8BE8 mov ebp,eax[/size]
[size=4] 01065E30 |81E5 FF000000 and ebp,0xFF[/size]
[size=4] 01065E36 |03CA add ecx,edx[/size]
[size=4] 01065E38 |03CD add ecx,ebp[/size]
[size=4] 01065E3A |81E1 FF000080 and ecx,0x800000FF[/size]
[size=4] 01065E40 |79 08 jns short krnln.01065E4A[/size]
[size=4] 01065E42 |49 dec ecx[/size]
[size=4] 01065E43 |81C9 00FFFFFF or ecx,0xFFFFFF00[/size]
[size=4] 01065E49 |41 inc ecx[/size]
[size=4] 01065E4A |884C24 10 mov byte ptr ss:[esp+0x10],cl[/size]
[size=4] 01065E4E |8B4C24 10 mov ecx,dword ptr ss:[esp+0x10][/size]
[size=4] 01065E52 |81E1 FF000000 and ecx,0xFF[/size]
[size=4] 01065E58 |8A1419 mov dl,byte ptr ds:[ecx+ebx][/size]
[size=4] 01065E5B |88141E mov byte ptr ds:[esi+ebx],dl[/size]
[size=4] 01065E5E |880419 mov byte ptr ds:[ecx+ebx],al[/size]
[size=4] 01065E61 |8D47 01 lea eax,dword ptr ds:[edi+0x1][/size]
[size=4] 01065E64 |99 cdq[/size]
[size=4] 01065E65 |F77C24 1C idiv dword ptr ss:[esp+0x1C][/size]
[size=4] 01065E69 |46 inc esi[/size]
[size=4] 01065E6A |81FE 00010000 cmp esi,0x100[/size]
[size=4] 01065E70 |885424 20 mov byte ptr ss:[esp+0x20],dl[/size]
[size=4] 01065E74 ^|7C A2 jl short krnln.01065E18[/size]
[size=4]
接着又是算法 1 2 进行运算
简单来说 算法大概思路是:(经过转换后的)
输入的密码→MD5运算→按照1234<>3412逆序得到的结果 结果1
根据输入的密码→进行算法3运算,得到一个256大小的key 结果2
算法1(固定8,结果2) 得到 结果3
结果3前4个内容+结果1+结果3前4个内容 得到 结果4
结果4经过算法3 得到 结果5
算法1(固定44,结果5 ) 得到 结果6
算法2(结果1,结果6) 得到 结果7
接着源码32长度的内容 === 结果7
4.总结:
通过上面分析,算法不是很难,主要是算法1 算法2 算法3,虽然算法是跟出来了,不过,想要追回密码发现还是不可能了,只能通过暴力枚举了.
PS:第一次发分析贴,希望大家能支持下,哪里有不足的地方,大家多多提意见
算法源码:打开密码 www.52pojie.cn
算法.txt
(9.58 KB, 下载次数: 97)
|
免费评分
-
查看全部评分
|