作者:yulongying
声明:献给想我一样的新手们
日期:18:03 2011-4-1
前天在qq群里灌水的时候,一个网友求助,说是使用一个文件夹加密的东东忘了密码了,
于是就分析了一下那个程序,一方面是练习,一方面是助人为乐 呵呵。
程序比较小所以比较容易。希望对像我一样的新手们有所帮助。
这个程序文件夹加密信息在放在一个.XX2文件里面的,安装这个程序之后这个文件会变图标默认一文件夹加密这个程序打开。
这个文件我用UE打开看了下:
绝大多数都是用A9来填充的有些地方有其他数据填充。
0000032eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000033eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000034eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000035eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000036eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000037eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000038eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000039eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
000003aeh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
000003beh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
000003ceh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
000003deh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
000003eeh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
000003feh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000040eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000041eh: BA 9A CA A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; 施┅┅┅┅┅┅
0000042eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000043eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000044eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000045eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000046eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000047eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000048eh: A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 A9 ; ┅┅┅┅┅┅┅┅
0000049eh: 99 A9 ;
首先打开程序,点击添加将.XX2文件添加进来,然后点击解密,随便输入一个密码,居然出现了提示信息“密码不匹配!请重新输入。” 呵呵。
于是用OD打开这个程序,找到这个字符串的位置
00407F08 |> /8A8C04 880100>|/mov cl, byte ptr ss:[esp+eax+188] ; 将加密后的输入字符与内存中的密码进行比较过程
00407F0F |. |8A9404 000C00>||mov dl, byte ptr ss:[esp+eax+C00]
00407F16 |. |3ACA ||cmp cl, dl
00407F18 |75 0E ||jnz short HideFold.00407F28
00407F1A |. |40 ||inc eax
00407F1B |. |3D 80000000 ||cmp eax, 80
00407F20 |. |0F8D 15010000 ||jge HideFold.0040803B
00407F26 |.^\EB E0 |\jmp short HideFold.00407F08
00407F28 |> 6A 10 |push 10
00407F2A 68 B8954100 push HideFold.004195B8 ; 密码错误
00407F2F |. 68 9C954100 |push HideFold.0041959C ; 密码不匹配!请重新输入。
很紧接着上面有一个循环比较的过程而且这个一句就是关键跳了
cmp eax, 80
00407F20 |. |0F8D 15010000 ||jge HideFold.0040803B
循环了80此就跳走了。
继续还往上翻
有一个明显的特征出来了
00407E78 |. /0F84 55050000 |je HideFold.004083D3
00407E7E |. |8D9424 E40700>|lea edx, dword ptr ss:[esp+7E4]
00407E85 |. |68 A0040000 |push 4A0
00407E8A |. |52 |push edx
00407E8B |. |8D4C24 74 |lea ecx, dword ptr ss:[esp+74]
00407E8F |. |FF15 A8344100 |call near dword ptr ds:[<&MSVCP60.st>; MSVCP60.std::basic_istream<char,std::char_traits<char> >::read
这就是读取.xx2文件了 放在ss:[esp+7E4],就断在这里开始分析了 呵呵
00407E8A |. 52 |push edx ; 读取.xx2文件
00407E8B |. 8D4C24 74 |lea ecx, dword ptr ss:[esp+74]
00407E8F |. FF15 A8344100 |call near dword ptr ds:[<&MSVCP60.std::basic_istre>; MSVCP60.std::basic_istream<char,std::char_traits<char> >::read
00407E95 |. 8B4424 6C |mov eax, dword ptr ss:[esp+6C]
00407E99 |. 8B48 04 |mov ecx, dword ptr ds:[eax+4]
00407E9C |. F6440C 70 01 |test byte ptr ss:[esp+ecx+70], 1
00407EA1 |. 0F85 20020000 |jnz HideFold.004080C7
00407EA7 |. B9 1F000000 |mov ecx, 1F
00407EAC |. 33C0 |xor eax, eax
00407EAE |. 8DBC24 890100>|lea edi, dword ptr ss:[esp+189]
00407EB5 |. C68424 880100>|mov byte ptr ss:[esp+188], 0
00407EBD |. F3:AB |rep stos dword ptr es:[edi]
00407EBF |. 66:AB |stos word ptr es:[edi]
00407EC1 |. AA |stos byte ptr es:[edi]
00407EC2 |. B9 20000000 |mov ecx, 20
00407EC7 |. 33C0 |xor eax, eax
00407EC9 |. 8DBC24 880100>|lea edi, dword ptr ss:[esp+188]
00407ED0 |. 8D9424 000100>|lea edx, dword ptr ss:[esp+100] ; 输入的信息放到edx中
00407ED7 |. F3:AB |rep stos dword ptr es:[edi]
00407ED9 |. 68 80000000 |push 80
00407EDE |. 8D8424 8C0100>|lea eax, dword ptr ss:[esp+18C]
00407EE5 |. 52 |push edx
00407EE6 |. 50 |push eax
00407EE7 |. FFD5 |call near ebp ; msvcrt.memmove
00407EE9 |. 8D8C24 0C0100>|lea ecx, dword ptr ss:[esp+10C]
00407EF0 |. 8D9424 940100>|lea edx, dword ptr ss:[esp+194]
00407EF7 |. 51 |push ecx ; 输入的信息
00407EF8 |. 68 80000000 |push 80
00407EFD |. 52 |push edx ; 也是输入的信息
00407EFE |. E8 4DA3FFFF |call HideFold.00402250 ; 加密关键函数 跟了进去
00407F03 |. 83C4 18 |add esp, 18
00407F06 |. 33C0 |xor eax, eax
00407F08 |> 8A8C04 880100>|/mov cl, byte ptr ss:[esp+eax+188] ; 将加密后的输入字符与内存中的密码进行比较过程
00407F0F |. 8A9404 000C00>||mov dl, byte ptr ss:[esp+eax+C00]
00407F16 |. 3ACA ||cmp cl, dl
00407F18 75 0E ||jnz short HideFold.00407F28
00407F1A |. 40 ||inc eax
00407F1B |. 3D 80000000 ||cmp eax, 80
00407F20 |. 0F8D 15010000 ||jge HideFold.0040803B
00407F26 |.^ EB E0 |\jmp short HideFold.00407F08
00407F28 |> 6A 10 |push 10
00407F2A 68 B8954100 push HideFold.004195B8 ; 密码错误
00407F2F |. 68 9C954100 |push HideFold.0041959C ; 密码不匹配!请重新输入。
00407F34 |. 8BCB |mov ecx, ebx
00407F36 |. E8 F38F0000 |call <jmp.&MFC42.#4224_CWnd::MessageBoxA> ; (初始 cpu 选择)
跟进去
00407EFE |. E8 4DA3FFFF |call HideFold.00402250 ; 加密关键函数 跟了进去
设输入的字符串变量名为Input
关键代码段1:
00402275 |> /0FBE3C32 /movsx edi, byte ptr ds:[edx+esi]
00402279 |. |03C7 |add eax, edi
0040227B |. |42 |inc edx
0040227C |. |3BD1 |cmp edx, ecx
0040227E |.^\7C F5 \jl short HideFold.00402275 ; 循环》输入的字符串所有ascii码相加
00402280 |> 33D2 xor edx, edx
00402282 |. B9 FF000000 mov ecx, 0FF
00402287 |. F7F1 div ecx ; ascii码之和除以FF 余数放到bl中 就是取模运算
00402289 |. 8ADA mov bl, dl ; bl=sum(Input[0,1,..]) mod 0xFF(等于sum(Input[0,1,..])本身,为啥要这么做?求解释)
0040228B |. 84DB test bl, bl
0040228D |. 75 2B jnz short HideFold.004022BA
运算后跳转到关键代码2:
004022C2 |. 8B7424 10 mov esi, dword ptr ss:[esp+10]
004022C6 |> 8A0E /mov cl, byte ptr ds:[esi]
004022C8 |. 56 |push esi
004022C9 |. 32CB |xor cl, bl ; bl(bl=sum(Input[0,1,..])) xor Input[i]
004022CB |. 880E |mov byte ptr ds:[esi], cl
004022CD |. E8 5EFFFFFF |call HideFold.00402230 ; 将运算结果的高四位与低四位 互换
004022D2 |. 83C4 04 |add esp, 4
004022D5 |. 46 |inc esi
004022D6 |. 4F |dec edi
004022D7 |.^ 75 ED \jnz short HideFold.004022C6 ; 循环80h次
高地位互换的方法是
00402236 |. 8AC8 mov cl, al
00402238 |. C0E9 04 shr cl, 4
0040223B |. C0E0 04 shl al, 4
0040223E |. 0AC1 or al, cl
00402240 |. 8802 mov byte ptr ds:[edx], al
当input[i]=0的时候就等于将sum(Input[0,1,..])的值高地位互换放到剩余字节填充 补齐80h
00407F08 |> /8A8C04 880100>|/mov cl, byte ptr ss:[esp+eax+188] ; 将加密后的输入字符与内存中的密码进行比较过程
00407F0F |. |8A9404 000C00>||mov dl, byte ptr ss:[esp+eax+C00] ; .xx2文件中数据BA 9A CA A9 A9 A9 A9 A9 A9 施┅┅┅
00407F16 |. |3ACA ||cmp cl, dl
00407F18 |75 0E ||jnz short HideFold.00407F28 ; 不等就跳转 弹出密码验证错误提示
00407F1A |. |40 ||inc eax
00407F1B |. |3D 80000000 ||cmp eax, 80
00407F20 |. |0F8D 15010000 ||jge HideFold.0040803B ; 比较完所有80h 密码验证正确
00407F26 |.^\EB E0 |\jmp short HideFold.00407F08
总结出验证算法
s[i] = sum(Input[0,1,...]) xor Input[i] , i=0,1,2,....,0x80-1
然后将s[i]高四位与低四位 互换
最后与文件中数据
BA 9A CA A9 A9 A9 A9 A9 A9 施┅┅┅
高地位互换
AB A9 AC 9A 9A 9A.....
后面一大串都是A9 A9 A9
所以推出9A=sum(Input[0,1,...])
AB A9 AC 分别再与9A异或密码就还原了
分别是1 3 6的ascii码值
.xx2文件 和那个文件夹加密工具在附件里面
有兴趣的自己可以分析下 呵呵。
- 标 题:文件夹加密宝密码验证过程分析
- 作 者:yulongying
- 时 间:2011-04-01 18:05:43
- 链 接:http://bbs.pediy.com/showthread.php?t=131714