-
-
[转帖]PARASOFT软件的加密方法与IDAPRO FLAIR
-
发表于: 2006-11-9 11:15 6764
-
PARASOFT软件的加密方法与IDAPRO FLAIR
64bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4c8W2j5h3@1#2x3o6W2Q4x3X3g2U0L8$3#2Q4x3V1k6E0L8$3c8#2L8r3g2K6i4K6u0W2M7r3S2H3i4K6y4r3L8X3q4E0k6g2)9K6c8p5&6W2N6%4y4Q4x3U0k6X3K9h3I4W2i4K6y4p5j5i4u0@1K9h3y4D9k6g2)9J5y4Y4y4A6k6q4)9K6c8o6x3J5
wooshi@gmail.com
最近一位朋友要linux下的debug工具,我推荐了parasoft的insure++,
在网上找了找,发现linux下的insure++没人破解,而我和doublelee在去年研究了一下这个软件,在研究的过程中,发现了IDAPRO flair的妙用,在这里记录一下。
我和doublelee用了大概两三天时间,把注册码生成的关键的代码部分找到了,并根据我们的判断,对某些函数的作用作了猜想,如下:
chekpoint proc near ; CODE XREF: m_check_li+177 p
………………
.text:0042EE32 call choose_the_key
.text:0042EE37 mov esi, eax
.text:0042EE39 add esp, 8
.text:0042EE3C cmp esi, ebx
.text:0042EE3E jz loc_42F105
.text:0042EE44 mov ecx, 200h
.text:0042EE49 xor eax, eax
.text:0042EE4B lea edi, [ebp+var_8AC]
.text:0042EE51 push 1Ch
.text:0042EE53 rep stosd
.text:0042EE55 mov byte ptr [ebp+var_4], 1
.text:0042EE59 call ??2@YAPAXI@Z ; operator new(uint)
.text:0042EE5E mov ecx, eax
.text:0042EE60 add esp, 4
.text:0042EE63 mov [ebp+var_14], ecx
.text:0042EE66 cmp ecx, ebx
.text:0042EE68 mov byte ptr [ebp+var_4], 2
.text:0042EE6C jz short loc_42EE78
.text:0042EE6E push 1
.text:0042EE70 push ebx
.text:0042EE71 call sub_442B90
.text:0042EE76 jmp short loc_42EE7A
.text:0042EE78 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0042EE78
.text:0042EE78 loc_42EE78: ; CODE XREF: chekpoint+6C j
.text:0042EE78 xor eax, eax
.text:0042EE7A
.text:0042EE7A loc_42EE7A: ; CODE XREF: chekpoint+76 j
.text:0042EE7A cmp eax, ebx
.text:0042EE7C mov byte ptr [ebp+var_4], 1
.text:0042EE80 jz short loc_42EE8C
.text:0042EE82 mov ecx, [eax+4]
.text:0042EE85 mov edx, [ecx+4]
.text:0042EE88 lea ebx, [edx+eax+4]
.text:0042EE8C
.text:0042EE8C loc_42EE8C: ; CODE XREF: chekpoint+80 j
.text:0042EE8C mov al, [ebp+arg_13]
.text:0042EE8F mov esi, [esi+0Ch]
.text:0042EE92 push 0
.text:0042EE94 lea ecx, [ebp+var_88]
.text:0042EE9A mov byte ptr [ebp+var_88], al
.text:0042EEA0 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042EEA6 mov edi, esi
.text:0042EEA8 or ecx, 0FFFFFFFFh
.text:0042EEAB xor eax, eax
.text:0042EEAD repne scasb
.text:0042EEAF not ecx
.text:0042EEB1 dec ecx
.text:0042EEB2 push ecx
.text:0042EEB3 push esi
.text:0042EEB4 lea ecx, [ebp+var_88]
.text:0042EEBA call ds:?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::assign(char const *,uint)
.text:0042EEC0 mov esi, offset off_454FA8 ; eax= string of priv key
.text:0042EEC5 mov [ebp+var_74], offset unk_454FA0
.text:0042EECC mov [ebp+var_48], esi
.text:0042EECF mov [ebp+var_14], 1
.text:0042EED6 push 0
.text:0042EED8 push ebx
.text:0042EED9 lea ecx, [ebp+var_78]
.text:0042EEDC mov byte ptr [ebp+var_4], 4
.text:0042EEE0 call sub_42F1B0
.text:0042EEE5 lea ecx, [ebp+var_88]
.text:0042EEEB push 1
.text:0042EEED push ecx
.text:0042EEEE lea ecx, [ebp+var_6C]
.text:0042EEF1 mov [ebp+var_4], 5
.text:0042EEF8 call sub_42F500 ; arg0 = address of priv key,arg1=0
.text:0042EEFD mov edx, [ebp+var_74]
.text:0042EF00 mov [ebp+var_78], offset off_454F94
.text:0042EF07 mov byte ptr [ebp+var_4], 6
.text:0042EF0B mov eax, [edx+4]
.text:0042EF0E mov [ebp+eax+var_74], offset off_454EF4
.text:0042EF16 mov ecx, [ebp+var_74]
.text:0042EF19 mov eax, [ecx+4]
.text:0042EF1C lea ecx, [ebp+var_78]
.text:0042EF1F lea edx, [eax-2Ch]
.text:0042EF22 mov [ebp+eax+var_78], edx
.text:0042EF26 call sub_442630 ; gen the hex priv key
.text:0042EF2B push 1
.text:0042EF2D lea ecx, [ebp+var_88]
.text:0042EF33 mov byte ptr [ebp+var_4], 8
.text:0042EF37 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042EF3D lea eax, [ebp+var_78]
.text:0042EF40 test eax, eax
.text:0042EF42 jz short loc_42EF4E
.text:0042EF44 mov ecx, [ebp+var_74]
.text:0042EF47 mov edx, [ecx+4]
.text:0042EF4A lea eax, [ebp+edx+var_74]
.text:0042EF4E
.text:0042EF4E loc_42EF4E: ; CODE XREF: chekpoint+142 j
.text:0042EF4E push 1
.text:0042EF50 push eax
.text:0042EF51 lea ecx, [ebp+var_AC]
.text:0042EF57 call sub_43F720 ; edi = priv key address
.text:0042EF5C mov [ebp+var_28], offset unk_454EEC
.text:0042EF63 mov [ebp+var_18], esi
.text:0042EF66 mov [ebp+var_14], 3
.text:0042EF6D push 0
.text:0042EF6F push 0
.text:0042EF71 lea ecx, [ebp+var_2C]
.text:0042EF74 mov byte ptr [ebp+var_4], 0Ah
.text:0042EF78 call sub_442390
.text:0042EF7D mov eax, [ebp+var_28]
.text:0042EF80 mov [ebp+var_2C], offset off_454EE8
.text:0042EF87 or esi, 0FFFFFFFFh
.text:0042EF8A mov ecx, [eax+4]
.text:0042EF8D mov [ebp+ecx+var_28], offset off_454E48
.text:0042EF95 mov edx, [ebp+var_28]
.text:0042EF98 mov eax, [edx+4]
.text:0042EF9B lea ecx, [eax-10h]
.text:0042EF9E mov [ebp+eax+var_2C], ecx
.text:0042EFA2 mov [ebp+var_20], esi
.text:0042EFA5 mov eax, [ebp+arg_4]
.text:0042EFA8 mov [ebp+var_4], 0Bh
.text:0042EFAF test eax, eax
.text:0042EFB1 jnz short loc_42EFB8
.text:0042EFB3 mov eax, ds:?_C@?1??_Nullstr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@CAPBDXZ@4DB ; char const `std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Nullstr(void)'::`2'::_C
.text:0042EFB8
.text:0042EFB8 loc_42EFB8: ; CODE XREF: chekpoint+1B1 j
.text:0042EFB8 mov edx, [ebp+arg_8]
.text:0042EFBB lea ecx, [ebp+var_18]
.text:0042EFBE push edx
.text:0042EFBF push eax
.text:0042EFC0 call sub_4421F0
.text:0042EFC5 push esi
.text:0042EFC6 lea ecx, [ebp+var_18]
.text:0042EFC9 call sub_4422B0
.text:0042EFCE mov ecx, [ebp+var_28]
.text:0042EFD1 lea eax, [ebp+var_8AC]
.text:0042EFD7 push 800h
.text:0042EFDC push eax
.text:0042EFDD mov edx, [ecx+4]
.text:0042EFE0 lea ecx, [ebp+edx+var_28]
.text:0042EFE4 call sub_434A60
.text:0042EFE9 push 0
.text:0042EFEB push eax
.text:0042EFEC lea eax, [ebp+var_8AC]
.text:0042EFF2 lea ecx, [ebp+var_38]
.text:0042EFF5 push eax
.text:0042EFF6 call Decode ; arg0 = integer of entered code
.text:0042EFFB lea ecx, [ebp+var_38]
.text:0042EFFE lea edx, [ebp+var_44]
.text:0042F001 push ecx
.text:0042F002 push edx
.text:0042F003 lea ecx, [ebp+var_8C]
.text:0042F009 mov byte ptr [ebp+var_4], 0Ch
.text:0042F00D call sub_43FE00 ; 003aa2c0 is the decrypt address
.text:0042F012 mov edi, [ebp+18h]
.text:0042F015 push 0
.text:0042F017 push 40h
.text:0042F019 push edi
.text:0042F01A lea ecx, [ebp+var_44]
.text:0042F01D mov byte ptr [ebp+var_4], 0Dh
.text:0042F021 call sub_439240
.text:0042F026 mov ecx, edi
.text:0042F028 call sub_426220
.text:0042F02D mov edx, [edi+24h]
.text:0042F030 mov ecx, [ebp+var_44]
.text:0042F033 mov edi, [ebp+var_40]
.text:0042F036 cmp edx, 0FACADEh
.text:0042F03C setz bl
.text:0042F03F xor eax, eax
.text:0042F041 rep stosd
.text:0042F043 mov eax, [ebp+var_40]
.text:0042F046 push eax
.text:0042F047 call ??3@YAXPAX@Z ; operator delete(void *)
.text:0042F04C mov ecx, [ebp+var_38]
.text:0042F04F mov edi, [ebp+var_34]
.text:0042F052 xor eax, eax
.text:0042F054 rep stosd
.text:0042F056 mov ecx, [ebp+var_34]
.text:0042F059 push ecx
.text:0042F05A call ??3@YAXPAX@Z ; operator delete(void *)
.text:0042F05F add esp, 8
.text:0042F062 lea ecx, [ebp+var_24]
.text:0042F065 mov byte ptr [ebp+var_4], 9
.text:0042F069 call sub_42F4F0
.text:0042F06E mov edi, offset off_454FA8
.text:0042F073 lea edx, [ebp+var_8C]
.text:0042F079 mov [ebp+var_18], edi
.text:0042F07C mov [ebp+18h], edx
.text:0042F07F lea ecx, [ebp+var_9C]
.text:0042F085 mov byte ptr [ebp+var_4], 0Eh
.text:0042F089 call sub_42F4C0
.text:0042F08E lea ecx, [ebp+var_A8]
.text:0042F094 mov byte ptr [ebp+var_4], 8
.text:0042F098 call sub_42F4C0
.text:0042F09D lea eax, [ebp+var_48]
.text:0042F0A0 mov [ebp+var_8C], offset off_454E30
.text:0042F0AA mov [ebp+18h], eax
.text:0042F0AD lea ecx, [ebp+var_6C]
.text:0042F0B0 mov byte ptr [ebp+var_4], 0Fh
.text:0042F0B4 call sub_42F190
.text:0042F0B9 lea ecx, [ebp+var_70]
.text:0042F0BC mov byte ptr [ebp+var_4], 1
.text:0042F0C0 call sub_42F4F0
.text:0042F0C5 push 1
.text:0042F0C7 lea ecx, [ebp+arg_0]
.text:0042F0CA mov [ebp+var_48], edi
.text:0042F0CD mov [ebp+var_4], esi
.text:0042F0D0 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042F0D6 mov al, bl
.text:0042F0D8 mov ecx, [ebp+var_C]
.text:0042F0DB mov large fs:0, ecx
.text:0042F0E2 pop edi
.text:0042F0E3 pop esi
.text:0042F0E4 pop ebx
.text:0042F0E5 mov esp, ebp
.text:0042F0E7 pop ebp
.text:0042F0E8 retn 14h
.text:0042F0EB
怎么样,工作还比较有成绩吧?我们知道他用了blowfish和RSA算法,但由于这个函数用了比较高深的C++技术,比如模版拉,重载拉等等,看得我等晕头转向,不知道具体的操作与操作数了,呵呵。直到有一天,我学会了使用flair,大概花了1个小时,生成的同一函数(由于使用的insure++版本不同,稍有差别)如下:
sub_42E150 proc near ; CODE XREF: my_check_point+18D p
……………………..
.text:0042E182 call sub_42E130
.text:0042E187 mov esi, eax
.text:0042E189 add esp, 8
.text:0042E18C cmp esi, ebx
.text:0042E18E jz loc_42E455
.text:0042E194 mov ecx, 200h
.text:0042E199 xor eax, eax
.text:0042E19B lea edi, [ebp+var_8AC]
.text:0042E1A1 push 1Ch
.text:0042E1A3 rep stosd
.text:0042E1A5 mov byte ptr [ebp+var_4], 1
.text:0042E1A9 call ??2@YAPAXI@Z ; operator new(uint)
.text:0042E1AE mov ecx, eax
.text:0042E1B0 add esp, 4
.text:0042E1B3 mov [ebp+var_14], ecx
.text:0042E1B6 cmp ecx, ebx
.text:0042E1B8 mov byte ptr [ebp+var_4], 2
.text:0042E1BC jz short loc_42E1C8
.text:0042E1BE push 1
.text:0042E1C0 push ebx
.text:0042E1C1 call ??0Base64Decoder@CryptoPP@@QAE@PAVBufferedTransformation@1@@Z ; CryptoPP::Base64Decoder::Base64Decoder(Base64Decoder::BufferedTransformation *)
.text:0042E1C6 jmp short loc_42E1CA
.text:0042E1C8
.text:0042E1C8 loc_42E1C8: ; CODE XREF: sub_42E150+6C j
.text:0042E1C8 xor eax, eax
.text:0042E1CA
.text:0042E1CA loc_42E1CA: ; CODE XREF: sub_42E150+76 j
.text:0042E1CA cmp eax, ebx
.text:0042E1CC mov byte ptr [ebp+var_4], 1
.text:0042E1D0 jz short loc_42E1DC
.text:0042E1D2 mov ecx, [eax+4]
.text:0042E1D5 mov edx, [ecx+4]
.text:0042E1D8 lea ebx, [edx+eax+4]
.text:0042E1DC
.text:0042E1DC loc_42E1DC: ; CODE XREF: sub_42E150+80 j
.text:0042E1DC mov al, [ebp+arg_13]
.text:0042E1DF mov esi, [esi+0Ch]
.text:0042E1E2 push 0
.text:0042E1E4 lea ecx, [ebp+var_88]
.text:0042E1EA mov byte ptr [ebp+var_88], al
.text:0042E1F0 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042E1F6 mov edi, esi
.text:0042E1F8 or ecx, 0FFFFFFFFh
.text:0042E1FB xor eax, eax
.text:0042E1FD repne scasb
.text:0042E1FF not ecx
.text:0042E201 dec ecx
.text:0042E202 push ecx
.text:0042E203 push esi
.text:0042E204 lea ecx, [ebp+var_88]
.text:0042E20A call ds:?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::assign(char const *,uint)
.text:0042E210 mov esi, offset off_45732C
.text:0042E215 mov [ebp+var_74], offset unk_457324
.text:0042E21C mov [ebp+var_48], esi
.text:0042E21F mov [ebp+var_14], 1
.text:0042E226 push 0
.text:0042E228 push ebx
.text:0042E229 lea ecx, [ebp+var_78]
.text:0042E22C mov byte ptr [ebp+var_4], 4
.text:0042E230 call ??0HexDecoder@CryptoPP@@QAE@PAVBufferedTransformation@1@@Z ; CryptoPP::HexDecoder::HexDecoder(HexDecoder::BufferedTransformation *)
.text:0042E235 lea ecx, [ebp+var_88]
.text:0042E23B push 1
.text:0042E23D push ecx
.text:0042E23E lea ecx, [ebp+var_6C]
.text:0042E241 mov [ebp+var_4], 5
.text:0042E248 call sub_42E820
.text:0042E24D mov edx, [ebp+var_74]
.text:0042E250 mov [ebp+var_78], offset off_457318
.text:0042E257 mov byte ptr [ebp+var_4], 6
.text:0042E25B mov eax, [edx+4]
.text:0042E25E mov [ebp+eax+var_74], offset off_457278
.text:0042E266 mov ecx, [ebp+var_74]
.text:0042E269 mov eax, [ecx+4]
.text:0042E26C lea ecx, [ebp+var_78]
.text:0042E26F lea edx, [eax-2Ch]
.text:0042E272 mov [ebp+eax+var_78], edx
.text:0042E276 call ?PumpAll@Source@CryptoPP@@QAEXXZ ; CryptoPP::Source::PumpAll(void)
.text:0042E27B push 1
.text:0042E27D lea ecx, [ebp+var_88]
.text:0042E283 mov byte ptr [ebp+var_4], 8
.text:0042E287 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042E28D lea eax, [ebp+var_78]
.text:0042E290 test eax, eax
.text:0042E292 jz short loc_42E29E
.text:0042E294 mov ecx, [ebp+var_74]
.text:0042E297 mov edx, [ecx+4]
.text:0042E29A lea eax, [ebp+edx+var_74]
.text:0042E29E
.text:0042E29E loc_42E29E: ; CODE XREF: sub_42E150+142 j
.text:0042E29E push 1
.text:0042E2A0 push eax
.text:0042E2A1 lea ecx, [ebp+var_AC]
.text:0042E2A7 call ??0RSAFunction@CryptoPP@@QAE@AAVBufferedTransformation@1@@Z ; CryptoPP::RSAFunction::RSAFunction(RSAFunction::BufferedTransformation &)
.text:0042E2AC mov [ebp+var_28], offset unk_457270
.text:0042E2B3 mov [ebp+var_18], esi
.text:0042E2B6 mov [ebp+var_14], 3
.text:0042E2BD push 0
.text:0042E2BF push 0
.text:0042E2C1 lea ecx, [ebp+var_2C]
.text:0042E2C4 mov byte ptr [ebp+var_4], 0Ah
.text:0042E2C8 call ??0Filter@CryptoPP@@QAE@PAVBufferedTransformation@1@@Z ; CryptoPP::Filter::Filter(Filter::BufferedTransformation *)
.text:0042E2CD mov eax, [ebp+var_28]
.text:0042E2D0 mov [ebp+var_2C], offset off_45726C
.text:0042E2D7 or esi, 0FFFFFFFFh
.text:0042E2DA mov ecx, [eax+4]
.text:0042E2DD mov [ebp+ecx+var_28], offset off_4571CC
.text:0042E2E5 mov edx, [ebp+var_28]
.text:0042E2E8 mov eax, [edx+4]
.text:0042E2EB lea ecx, [eax-10h]
.text:0042E2EE mov [ebp+eax+var_2C], ecx
.text:0042E2F2 mov [ebp+var_20], esi
.text:0042E2F5 mov eax, [ebp+arg_4]
.text:0042E2F8 mov [ebp+var_4], 0Bh
.text:0042E2FF test eax, eax
.text:0042E301 jnz short loc_42E308
.text:0042E303 mov eax, ds:?_C@?1??_Nullstr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@CAPBDXZ@4DB ; char const `std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Nullstr(void)'::`2'::_C
.text:0042E308
.text:0042E308 loc_42E308: ; CODE XREF: sub_42E150+1B1 j
.text:0042E308 mov edx, [ebp+arg_8]
.text:0042E30B lea ecx, [ebp+var_18]
.text:0042E30E push edx
.text:0042E30F push eax
.text:0042E310 call ?Put@HexDecoder@CryptoPP@@UAEXPBEI@Z ; CryptoPP::HexDecoder::Put(uchar const *,uint)
.text:0042E315 push esi
.text:0042E316 lea ecx, [ebp+var_18]
.text:0042E319 call ?MessageEnd@HexDecoder@CryptoPP@@UAEXH@Z ; CryptoPP::HexDecoder::MessageEnd(int)
.text:0042E31E mov ecx, [ebp+var_28]
.text:0042E321 lea eax, [ebp+var_8AC]
.text:0042E327 push 800h
.text:0042E32C push eax
.text:0042E32D mov edx, [ecx+4]
.text:0042E330 lea ecx, [ebp+edx+var_28]
.text:0042E334 call ?Get@BufferedTransformation@CryptoPP@@UAEIPAEI@Z ; CryptoPP::BufferedTransformation::Get(uchar *,uint)
.text:0042E339 push 0
.text:0042E33B push eax
.text:0042E33C lea eax, [ebp+var_8AC]
.text:0042E342 lea ecx, [ebp+var_38]
.text:0042E345 push eax
.text:0042E346 call ??0Integer@CryptoPP@@QAE@PBEIW4Signedness@01@@Z ; CryptoPP::Integer::Integer(uchar const *,uint,Integer::Integer::Signedness)
.text:0042E34B lea ecx, [ebp+var_38]
.text:0042E34E lea edx, [ebp+var_44]
.text:0042E351 push ecx
.text:0042E352 push edx
.text:0042E353 lea ecx, [ebp+var_8C]
.text:0042E359 mov byte ptr [ebp+var_4], 0Ch
.text:0042E35D call ?ApplyFunction@RSAFunction@CryptoPP@@UBE?AVInteger@2@ABV32@@Z ; CryptoPP::RSAFunction::ApplyFunction(CryptoPP::Integer const &)
.text:0042E362 mov edi, [ebp+18h]
.text:0042E365 push 0
.text:0042E367 push 40h
.text:0042E369 push edi
.text:0042E36A lea ecx, [ebp+var_44]
.text:0042E36D mov byte ptr [ebp+var_4], 0Dh
.text:0042E371 call ?Encode@Integer@CryptoPP@@QBEIPAEIW4Signedness@12@@Z ; CryptoPP::Integer::Encode(uchar *,uint,CryptoPP::Integer::Signedness)
…………………...
如何?这个函数简直太清楚了,一切都摆在了眼前。那么,flair/flirt怎么用呢?当初我认为可能非常复杂,在网上四处找教程,结果没找到,后来我仔细了解了flair后,才知道没有教程是因为这个东西太简单了,呵呵。
flair/flirt是IDA的独有的快速分辨库函数的方法,如果用IDA而不用flair的话,IDA的功能会损失大半。
下面我们以insure++为例来说明一下用法:
首先,我们要辨别insure++是用什么函数库来生成key的,这个不难找到,在关键函数的周围,充斥着”cryptpp”之类的字符串,上网搜一下,发现其用的是crypto++函数库,基本上,现在软件都用的是现成的函数库,如果不是,恭喜你,这意味着这个软件的加密实现可能有问题。
下载crypto++,编译得到一个静态的库cryptlib.lib,然后用IDA flair的应用程序pcf(或plb)生成cryptlib.pat:
pcf cryptlib.lib cryptlib.pat
打开cryptlib.pat,你会看到像这样的东西:
C3909090909090909090909090909090................................ 11 1234 0010 :0000 ?NotifyAttachmentChange@Filter@CryptoPP@@MAEXXZ
前面这个“C3909090909090909090909090909090................................”是函数NotifyAttachmentChange@Filter@CryptoPP@@MAEXXZ的最前面的32个字节,其中”…..”代表任意,因为这些可以与编译器有关。11代表后面那个1234是函数的33字节到43字节(11字节)的crc16的结果,那个0010:0000代表函数的44字节加上0x10的偏移(这个奇怪,有的用10进制,有的用16进制),那个地方(60)的值是0000,这个表达式这个复杂,就是为了给世界上的每一个函数都确定一个唯一的值,这样IDA就可以快速的分辨出已知的函数了。同时,你也可以全凭手工而不用pcf.exe来生成pat文件,这个在你知道一些关键函数在一些相关的应用程序中使用时,来同时在这些应用程序中标记这些函数比较有用。
生成pat文件了,下一步就是应用sigmake来生成sig了:
sigmake cryptlib.pat cryptlib.sig
可能这时候,会出现“cryptlib.pat (1066): bad pattern”这样的提示信息,我的解决方法是在cryptlib.pat文件中找到那一行1066,删掉它,呵呵。
在这个过程中,重要的问题就是解决冲突问题,就是自动生成的pat文件里,有很多函数的特征值一样了,需要手工来解决区分,如果你嫌太麻烦得话,可以简单的把生成的cryptlib.exc文件的前3行去掉就可。
运行: sigmake -xcryptlib.exc cryptlib.pat cryptlib.sig
OK,把生成的cryptlib.sig扔到IDA的sig目录下,再点IDA菜单上的那朵花来载入我们的sig,如果都没有出错的话,OK,你会看到奇迹发生了,呵呵。如果出错的话,IDA会提示你是那一行,在sig里找到它的函数名,在pat里删掉,在生成一遍,呵呵,直到没错误发生。
通过flair的帮助,我们很快了解了insure++的算法,流程是这样的:
你要输入的serials(k), k**17 mod ( n ) 的结果某些位要等于一个固定值,同时k的前16字节在以”donut”为key的blowfish的解密运算后,一半是等于你的machine key,另一半满足一点点条件就可以了,呵呵。
注:欢迎各位把使用IDA pro的心得体会与大家分享。
感谢 team509 的各位牛牛
64bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4c8W2j5h3@1#2x3o6W2Q4x3X3g2U0L8$3#2Q4x3V1k6E0L8$3c8#2L8r3g2K6i4K6u0W2M7r3S2H3i4K6y4r3L8X3q4E0k6g2)9K6c8p5&6W2N6%4y4Q4x3U0k6X3K9h3I4W2i4K6y4p5j5i4u0@1K9h3y4D9k6g2)9J5y4Y4y4A6k6q4)9K6c8o6x3J5
wooshi@gmail.com
最近一位朋友要linux下的debug工具,我推荐了parasoft的insure++,
在网上找了找,发现linux下的insure++没人破解,而我和doublelee在去年研究了一下这个软件,在研究的过程中,发现了IDAPRO flair的妙用,在这里记录一下。
我和doublelee用了大概两三天时间,把注册码生成的关键的代码部分找到了,并根据我们的判断,对某些函数的作用作了猜想,如下:
chekpoint proc near ; CODE XREF: m_check_li+177 p
………………
.text:0042EE32 call choose_the_key
.text:0042EE37 mov esi, eax
.text:0042EE39 add esp, 8
.text:0042EE3C cmp esi, ebx
.text:0042EE3E jz loc_42F105
.text:0042EE44 mov ecx, 200h
.text:0042EE49 xor eax, eax
.text:0042EE4B lea edi, [ebp+var_8AC]
.text:0042EE51 push 1Ch
.text:0042EE53 rep stosd
.text:0042EE55 mov byte ptr [ebp+var_4], 1
.text:0042EE59 call ??2@YAPAXI@Z ; operator new(uint)
.text:0042EE5E mov ecx, eax
.text:0042EE60 add esp, 4
.text:0042EE63 mov [ebp+var_14], ecx
.text:0042EE66 cmp ecx, ebx
.text:0042EE68 mov byte ptr [ebp+var_4], 2
.text:0042EE6C jz short loc_42EE78
.text:0042EE6E push 1
.text:0042EE70 push ebx
.text:0042EE71 call sub_442B90
.text:0042EE76 jmp short loc_42EE7A
.text:0042EE78 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0042EE78
.text:0042EE78 loc_42EE78: ; CODE XREF: chekpoint+6C j
.text:0042EE78 xor eax, eax
.text:0042EE7A
.text:0042EE7A loc_42EE7A: ; CODE XREF: chekpoint+76 j
.text:0042EE7A cmp eax, ebx
.text:0042EE7C mov byte ptr [ebp+var_4], 1
.text:0042EE80 jz short loc_42EE8C
.text:0042EE82 mov ecx, [eax+4]
.text:0042EE85 mov edx, [ecx+4]
.text:0042EE88 lea ebx, [edx+eax+4]
.text:0042EE8C
.text:0042EE8C loc_42EE8C: ; CODE XREF: chekpoint+80 j
.text:0042EE8C mov al, [ebp+arg_13]
.text:0042EE8F mov esi, [esi+0Ch]
.text:0042EE92 push 0
.text:0042EE94 lea ecx, [ebp+var_88]
.text:0042EE9A mov byte ptr [ebp+var_88], al
.text:0042EEA0 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042EEA6 mov edi, esi
.text:0042EEA8 or ecx, 0FFFFFFFFh
.text:0042EEAB xor eax, eax
.text:0042EEAD repne scasb
.text:0042EEAF not ecx
.text:0042EEB1 dec ecx
.text:0042EEB2 push ecx
.text:0042EEB3 push esi
.text:0042EEB4 lea ecx, [ebp+var_88]
.text:0042EEBA call ds:?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::assign(char const *,uint)
.text:0042EEC0 mov esi, offset off_454FA8 ; eax= string of priv key
.text:0042EEC5 mov [ebp+var_74], offset unk_454FA0
.text:0042EECC mov [ebp+var_48], esi
.text:0042EECF mov [ebp+var_14], 1
.text:0042EED6 push 0
.text:0042EED8 push ebx
.text:0042EED9 lea ecx, [ebp+var_78]
.text:0042EEDC mov byte ptr [ebp+var_4], 4
.text:0042EEE0 call sub_42F1B0
.text:0042EEE5 lea ecx, [ebp+var_88]
.text:0042EEEB push 1
.text:0042EEED push ecx
.text:0042EEEE lea ecx, [ebp+var_6C]
.text:0042EEF1 mov [ebp+var_4], 5
.text:0042EEF8 call sub_42F500 ; arg0 = address of priv key,arg1=0
.text:0042EEFD mov edx, [ebp+var_74]
.text:0042EF00 mov [ebp+var_78], offset off_454F94
.text:0042EF07 mov byte ptr [ebp+var_4], 6
.text:0042EF0B mov eax, [edx+4]
.text:0042EF0E mov [ebp+eax+var_74], offset off_454EF4
.text:0042EF16 mov ecx, [ebp+var_74]
.text:0042EF19 mov eax, [ecx+4]
.text:0042EF1C lea ecx, [ebp+var_78]
.text:0042EF1F lea edx, [eax-2Ch]
.text:0042EF22 mov [ebp+eax+var_78], edx
.text:0042EF26 call sub_442630 ; gen the hex priv key
.text:0042EF2B push 1
.text:0042EF2D lea ecx, [ebp+var_88]
.text:0042EF33 mov byte ptr [ebp+var_4], 8
.text:0042EF37 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042EF3D lea eax, [ebp+var_78]
.text:0042EF40 test eax, eax
.text:0042EF42 jz short loc_42EF4E
.text:0042EF44 mov ecx, [ebp+var_74]
.text:0042EF47 mov edx, [ecx+4]
.text:0042EF4A lea eax, [ebp+edx+var_74]
.text:0042EF4E
.text:0042EF4E loc_42EF4E: ; CODE XREF: chekpoint+142 j
.text:0042EF4E push 1
.text:0042EF50 push eax
.text:0042EF51 lea ecx, [ebp+var_AC]
.text:0042EF57 call sub_43F720 ; edi = priv key address
.text:0042EF5C mov [ebp+var_28], offset unk_454EEC
.text:0042EF63 mov [ebp+var_18], esi
.text:0042EF66 mov [ebp+var_14], 3
.text:0042EF6D push 0
.text:0042EF6F push 0
.text:0042EF71 lea ecx, [ebp+var_2C]
.text:0042EF74 mov byte ptr [ebp+var_4], 0Ah
.text:0042EF78 call sub_442390
.text:0042EF7D mov eax, [ebp+var_28]
.text:0042EF80 mov [ebp+var_2C], offset off_454EE8
.text:0042EF87 or esi, 0FFFFFFFFh
.text:0042EF8A mov ecx, [eax+4]
.text:0042EF8D mov [ebp+ecx+var_28], offset off_454E48
.text:0042EF95 mov edx, [ebp+var_28]
.text:0042EF98 mov eax, [edx+4]
.text:0042EF9B lea ecx, [eax-10h]
.text:0042EF9E mov [ebp+eax+var_2C], ecx
.text:0042EFA2 mov [ebp+var_20], esi
.text:0042EFA5 mov eax, [ebp+arg_4]
.text:0042EFA8 mov [ebp+var_4], 0Bh
.text:0042EFAF test eax, eax
.text:0042EFB1 jnz short loc_42EFB8
.text:0042EFB3 mov eax, ds:?_C@?1??_Nullstr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@CAPBDXZ@4DB ; char const `std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Nullstr(void)'::`2'::_C
.text:0042EFB8
.text:0042EFB8 loc_42EFB8: ; CODE XREF: chekpoint+1B1 j
.text:0042EFB8 mov edx, [ebp+arg_8]
.text:0042EFBB lea ecx, [ebp+var_18]
.text:0042EFBE push edx
.text:0042EFBF push eax
.text:0042EFC0 call sub_4421F0
.text:0042EFC5 push esi
.text:0042EFC6 lea ecx, [ebp+var_18]
.text:0042EFC9 call sub_4422B0
.text:0042EFCE mov ecx, [ebp+var_28]
.text:0042EFD1 lea eax, [ebp+var_8AC]
.text:0042EFD7 push 800h
.text:0042EFDC push eax
.text:0042EFDD mov edx, [ecx+4]
.text:0042EFE0 lea ecx, [ebp+edx+var_28]
.text:0042EFE4 call sub_434A60
.text:0042EFE9 push 0
.text:0042EFEB push eax
.text:0042EFEC lea eax, [ebp+var_8AC]
.text:0042EFF2 lea ecx, [ebp+var_38]
.text:0042EFF5 push eax
.text:0042EFF6 call Decode ; arg0 = integer of entered code
.text:0042EFFB lea ecx, [ebp+var_38]
.text:0042EFFE lea edx, [ebp+var_44]
.text:0042F001 push ecx
.text:0042F002 push edx
.text:0042F003 lea ecx, [ebp+var_8C]
.text:0042F009 mov byte ptr [ebp+var_4], 0Ch
.text:0042F00D call sub_43FE00 ; 003aa2c0 is the decrypt address
.text:0042F012 mov edi, [ebp+18h]
.text:0042F015 push 0
.text:0042F017 push 40h
.text:0042F019 push edi
.text:0042F01A lea ecx, [ebp+var_44]
.text:0042F01D mov byte ptr [ebp+var_4], 0Dh
.text:0042F021 call sub_439240
.text:0042F026 mov ecx, edi
.text:0042F028 call sub_426220
.text:0042F02D mov edx, [edi+24h]
.text:0042F030 mov ecx, [ebp+var_44]
.text:0042F033 mov edi, [ebp+var_40]
.text:0042F036 cmp edx, 0FACADEh
.text:0042F03C setz bl
.text:0042F03F xor eax, eax
.text:0042F041 rep stosd
.text:0042F043 mov eax, [ebp+var_40]
.text:0042F046 push eax
.text:0042F047 call ??3@YAXPAX@Z ; operator delete(void *)
.text:0042F04C mov ecx, [ebp+var_38]
.text:0042F04F mov edi, [ebp+var_34]
.text:0042F052 xor eax, eax
.text:0042F054 rep stosd
.text:0042F056 mov ecx, [ebp+var_34]
.text:0042F059 push ecx
.text:0042F05A call ??3@YAXPAX@Z ; operator delete(void *)
.text:0042F05F add esp, 8
.text:0042F062 lea ecx, [ebp+var_24]
.text:0042F065 mov byte ptr [ebp+var_4], 9
.text:0042F069 call sub_42F4F0
.text:0042F06E mov edi, offset off_454FA8
.text:0042F073 lea edx, [ebp+var_8C]
.text:0042F079 mov [ebp+var_18], edi
.text:0042F07C mov [ebp+18h], edx
.text:0042F07F lea ecx, [ebp+var_9C]
.text:0042F085 mov byte ptr [ebp+var_4], 0Eh
.text:0042F089 call sub_42F4C0
.text:0042F08E lea ecx, [ebp+var_A8]
.text:0042F094 mov byte ptr [ebp+var_4], 8
.text:0042F098 call sub_42F4C0
.text:0042F09D lea eax, [ebp+var_48]
.text:0042F0A0 mov [ebp+var_8C], offset off_454E30
.text:0042F0AA mov [ebp+18h], eax
.text:0042F0AD lea ecx, [ebp+var_6C]
.text:0042F0B0 mov byte ptr [ebp+var_4], 0Fh
.text:0042F0B4 call sub_42F190
.text:0042F0B9 lea ecx, [ebp+var_70]
.text:0042F0BC mov byte ptr [ebp+var_4], 1
.text:0042F0C0 call sub_42F4F0
.text:0042F0C5 push 1
.text:0042F0C7 lea ecx, [ebp+arg_0]
.text:0042F0CA mov [ebp+var_48], edi
.text:0042F0CD mov [ebp+var_4], esi
.text:0042F0D0 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042F0D6 mov al, bl
.text:0042F0D8 mov ecx, [ebp+var_C]
.text:0042F0DB mov large fs:0, ecx
.text:0042F0E2 pop edi
.text:0042F0E3 pop esi
.text:0042F0E4 pop ebx
.text:0042F0E5 mov esp, ebp
.text:0042F0E7 pop ebp
.text:0042F0E8 retn 14h
.text:0042F0EB
怎么样,工作还比较有成绩吧?我们知道他用了blowfish和RSA算法,但由于这个函数用了比较高深的C++技术,比如模版拉,重载拉等等,看得我等晕头转向,不知道具体的操作与操作数了,呵呵。直到有一天,我学会了使用flair,大概花了1个小时,生成的同一函数(由于使用的insure++版本不同,稍有差别)如下:
sub_42E150 proc near ; CODE XREF: my_check_point+18D p
……………………..
.text:0042E182 call sub_42E130
.text:0042E187 mov esi, eax
.text:0042E189 add esp, 8
.text:0042E18C cmp esi, ebx
.text:0042E18E jz loc_42E455
.text:0042E194 mov ecx, 200h
.text:0042E199 xor eax, eax
.text:0042E19B lea edi, [ebp+var_8AC]
.text:0042E1A1 push 1Ch
.text:0042E1A3 rep stosd
.text:0042E1A5 mov byte ptr [ebp+var_4], 1
.text:0042E1A9 call ??2@YAPAXI@Z ; operator new(uint)
.text:0042E1AE mov ecx, eax
.text:0042E1B0 add esp, 4
.text:0042E1B3 mov [ebp+var_14], ecx
.text:0042E1B6 cmp ecx, ebx
.text:0042E1B8 mov byte ptr [ebp+var_4], 2
.text:0042E1BC jz short loc_42E1C8
.text:0042E1BE push 1
.text:0042E1C0 push ebx
.text:0042E1C1 call ??0Base64Decoder@CryptoPP@@QAE@PAVBufferedTransformation@1@@Z ; CryptoPP::Base64Decoder::Base64Decoder(Base64Decoder::BufferedTransformation *)
.text:0042E1C6 jmp short loc_42E1CA
.text:0042E1C8
.text:0042E1C8 loc_42E1C8: ; CODE XREF: sub_42E150+6C j
.text:0042E1C8 xor eax, eax
.text:0042E1CA
.text:0042E1CA loc_42E1CA: ; CODE XREF: sub_42E150+76 j
.text:0042E1CA cmp eax, ebx
.text:0042E1CC mov byte ptr [ebp+var_4], 1
.text:0042E1D0 jz short loc_42E1DC
.text:0042E1D2 mov ecx, [eax+4]
.text:0042E1D5 mov edx, [ecx+4]
.text:0042E1D8 lea ebx, [edx+eax+4]
.text:0042E1DC
.text:0042E1DC loc_42E1DC: ; CODE XREF: sub_42E150+80 j
.text:0042E1DC mov al, [ebp+arg_13]
.text:0042E1DF mov esi, [esi+0Ch]
.text:0042E1E2 push 0
.text:0042E1E4 lea ecx, [ebp+var_88]
.text:0042E1EA mov byte ptr [ebp+var_88], al
.text:0042E1F0 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042E1F6 mov edi, esi
.text:0042E1F8 or ecx, 0FFFFFFFFh
.text:0042E1FB xor eax, eax
.text:0042E1FD repne scasb
.text:0042E1FF not ecx
.text:0042E201 dec ecx
.text:0042E202 push ecx
.text:0042E203 push esi
.text:0042E204 lea ecx, [ebp+var_88]
.text:0042E20A call ds:?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBDI@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::assign(char const *,uint)
.text:0042E210 mov esi, offset off_45732C
.text:0042E215 mov [ebp+var_74], offset unk_457324
.text:0042E21C mov [ebp+var_48], esi
.text:0042E21F mov [ebp+var_14], 1
.text:0042E226 push 0
.text:0042E228 push ebx
.text:0042E229 lea ecx, [ebp+var_78]
.text:0042E22C mov byte ptr [ebp+var_4], 4
.text:0042E230 call ??0HexDecoder@CryptoPP@@QAE@PAVBufferedTransformation@1@@Z ; CryptoPP::HexDecoder::HexDecoder(HexDecoder::BufferedTransformation *)
.text:0042E235 lea ecx, [ebp+var_88]
.text:0042E23B push 1
.text:0042E23D push ecx
.text:0042E23E lea ecx, [ebp+var_6C]
.text:0042E241 mov [ebp+var_4], 5
.text:0042E248 call sub_42E820
.text:0042E24D mov edx, [ebp+var_74]
.text:0042E250 mov [ebp+var_78], offset off_457318
.text:0042E257 mov byte ptr [ebp+var_4], 6
.text:0042E25B mov eax, [edx+4]
.text:0042E25E mov [ebp+eax+var_74], offset off_457278
.text:0042E266 mov ecx, [ebp+var_74]
.text:0042E269 mov eax, [ecx+4]
.text:0042E26C lea ecx, [ebp+var_78]
.text:0042E26F lea edx, [eax-2Ch]
.text:0042E272 mov [ebp+eax+var_78], edx
.text:0042E276 call ?PumpAll@Source@CryptoPP@@QAEXXZ ; CryptoPP::Source::PumpAll(void)
.text:0042E27B push 1
.text:0042E27D lea ecx, [ebp+var_88]
.text:0042E283 mov byte ptr [ebp+var_4], 8
.text:0042E287 call ds:?_Tidy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AAEX_N@Z ; std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Tidy(bool)
.text:0042E28D lea eax, [ebp+var_78]
.text:0042E290 test eax, eax
.text:0042E292 jz short loc_42E29E
.text:0042E294 mov ecx, [ebp+var_74]
.text:0042E297 mov edx, [ecx+4]
.text:0042E29A lea eax, [ebp+edx+var_74]
.text:0042E29E
.text:0042E29E loc_42E29E: ; CODE XREF: sub_42E150+142 j
.text:0042E29E push 1
.text:0042E2A0 push eax
.text:0042E2A1 lea ecx, [ebp+var_AC]
.text:0042E2A7 call ??0RSAFunction@CryptoPP@@QAE@AAVBufferedTransformation@1@@Z ; CryptoPP::RSAFunction::RSAFunction(RSAFunction::BufferedTransformation &)
.text:0042E2AC mov [ebp+var_28], offset unk_457270
.text:0042E2B3 mov [ebp+var_18], esi
.text:0042E2B6 mov [ebp+var_14], 3
.text:0042E2BD push 0
.text:0042E2BF push 0
.text:0042E2C1 lea ecx, [ebp+var_2C]
.text:0042E2C4 mov byte ptr [ebp+var_4], 0Ah
.text:0042E2C8 call ??0Filter@CryptoPP@@QAE@PAVBufferedTransformation@1@@Z ; CryptoPP::Filter::Filter(Filter::BufferedTransformation *)
.text:0042E2CD mov eax, [ebp+var_28]
.text:0042E2D0 mov [ebp+var_2C], offset off_45726C
.text:0042E2D7 or esi, 0FFFFFFFFh
.text:0042E2DA mov ecx, [eax+4]
.text:0042E2DD mov [ebp+ecx+var_28], offset off_4571CC
.text:0042E2E5 mov edx, [ebp+var_28]
.text:0042E2E8 mov eax, [edx+4]
.text:0042E2EB lea ecx, [eax-10h]
.text:0042E2EE mov [ebp+eax+var_2C], ecx
.text:0042E2F2 mov [ebp+var_20], esi
.text:0042E2F5 mov eax, [ebp+arg_4]
.text:0042E2F8 mov [ebp+var_4], 0Bh
.text:0042E2FF test eax, eax
.text:0042E301 jnz short loc_42E308
.text:0042E303 mov eax, ds:?_C@?1??_Nullstr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@CAPBDXZ@4DB ; char const `std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Nullstr(void)'::`2'::_C
.text:0042E308
.text:0042E308 loc_42E308: ; CODE XREF: sub_42E150+1B1 j
.text:0042E308 mov edx, [ebp+arg_8]
.text:0042E30B lea ecx, [ebp+var_18]
.text:0042E30E push edx
.text:0042E30F push eax
.text:0042E310 call ?Put@HexDecoder@CryptoPP@@UAEXPBEI@Z ; CryptoPP::HexDecoder::Put(uchar const *,uint)
.text:0042E315 push esi
.text:0042E316 lea ecx, [ebp+var_18]
.text:0042E319 call ?MessageEnd@HexDecoder@CryptoPP@@UAEXH@Z ; CryptoPP::HexDecoder::MessageEnd(int)
.text:0042E31E mov ecx, [ebp+var_28]
.text:0042E321 lea eax, [ebp+var_8AC]
.text:0042E327 push 800h
.text:0042E32C push eax
.text:0042E32D mov edx, [ecx+4]
.text:0042E330 lea ecx, [ebp+edx+var_28]
.text:0042E334 call ?Get@BufferedTransformation@CryptoPP@@UAEIPAEI@Z ; CryptoPP::BufferedTransformation::Get(uchar *,uint)
.text:0042E339 push 0
.text:0042E33B push eax
.text:0042E33C lea eax, [ebp+var_8AC]
.text:0042E342 lea ecx, [ebp+var_38]
.text:0042E345 push eax
.text:0042E346 call ??0Integer@CryptoPP@@QAE@PBEIW4Signedness@01@@Z ; CryptoPP::Integer::Integer(uchar const *,uint,Integer::Integer::Signedness)
.text:0042E34B lea ecx, [ebp+var_38]
.text:0042E34E lea edx, [ebp+var_44]
.text:0042E351 push ecx
.text:0042E352 push edx
.text:0042E353 lea ecx, [ebp+var_8C]
.text:0042E359 mov byte ptr [ebp+var_4], 0Ch
.text:0042E35D call ?ApplyFunction@RSAFunction@CryptoPP@@UBE?AVInteger@2@ABV32@@Z ; CryptoPP::RSAFunction::ApplyFunction(CryptoPP::Integer const &)
.text:0042E362 mov edi, [ebp+18h]
.text:0042E365 push 0
.text:0042E367 push 40h
.text:0042E369 push edi
.text:0042E36A lea ecx, [ebp+var_44]
.text:0042E36D mov byte ptr [ebp+var_4], 0Dh
.text:0042E371 call ?Encode@Integer@CryptoPP@@QBEIPAEIW4Signedness@12@@Z ; CryptoPP::Integer::Encode(uchar *,uint,CryptoPP::Integer::Signedness)
…………………...
如何?这个函数简直太清楚了,一切都摆在了眼前。那么,flair/flirt怎么用呢?当初我认为可能非常复杂,在网上四处找教程,结果没找到,后来我仔细了解了flair后,才知道没有教程是因为这个东西太简单了,呵呵。
flair/flirt是IDA的独有的快速分辨库函数的方法,如果用IDA而不用flair的话,IDA的功能会损失大半。
下面我们以insure++为例来说明一下用法:
首先,我们要辨别insure++是用什么函数库来生成key的,这个不难找到,在关键函数的周围,充斥着”cryptpp”之类的字符串,上网搜一下,发现其用的是crypto++函数库,基本上,现在软件都用的是现成的函数库,如果不是,恭喜你,这意味着这个软件的加密实现可能有问题。
下载crypto++,编译得到一个静态的库cryptlib.lib,然后用IDA flair的应用程序pcf(或plb)生成cryptlib.pat:
pcf cryptlib.lib cryptlib.pat
打开cryptlib.pat,你会看到像这样的东西:
C3909090909090909090909090909090................................ 11 1234 0010 :0000 ?NotifyAttachmentChange@Filter@CryptoPP@@MAEXXZ
前面这个“C3909090909090909090909090909090................................”是函数NotifyAttachmentChange@Filter@CryptoPP@@MAEXXZ的最前面的32个字节,其中”…..”代表任意,因为这些可以与编译器有关。11代表后面那个1234是函数的33字节到43字节(11字节)的crc16的结果,那个0010:0000代表函数的44字节加上0x10的偏移(这个奇怪,有的用10进制,有的用16进制),那个地方(60)的值是0000,这个表达式这个复杂,就是为了给世界上的每一个函数都确定一个唯一的值,这样IDA就可以快速的分辨出已知的函数了。同时,你也可以全凭手工而不用pcf.exe来生成pat文件,这个在你知道一些关键函数在一些相关的应用程序中使用时,来同时在这些应用程序中标记这些函数比较有用。
生成pat文件了,下一步就是应用sigmake来生成sig了:
sigmake cryptlib.pat cryptlib.sig
可能这时候,会出现“cryptlib.pat (1066): bad pattern”这样的提示信息,我的解决方法是在cryptlib.pat文件中找到那一行1066,删掉它,呵呵。
在这个过程中,重要的问题就是解决冲突问题,就是自动生成的pat文件里,有很多函数的特征值一样了,需要手工来解决区分,如果你嫌太麻烦得话,可以简单的把生成的cryptlib.exc文件的前3行去掉就可。
运行: sigmake -xcryptlib.exc cryptlib.pat cryptlib.sig
OK,把生成的cryptlib.sig扔到IDA的sig目录下,再点IDA菜单上的那朵花来载入我们的sig,如果都没有出错的话,OK,你会看到奇迹发生了,呵呵。如果出错的话,IDA会提示你是那一行,在sig里找到它的函数名,在pat里删掉,在生成一遍,呵呵,直到没错误发生。
通过flair的帮助,我们很快了解了insure++的算法,流程是这样的:
你要输入的serials(k), k**17 mod ( n ) 的结果某些位要等于一个固定值,同时k的前16字节在以”donut”为key的blowfish的解密运算后,一半是等于你的machine key,另一半满足一点点条件就可以了,呵呵。
注:欢迎各位把使用IDA pro的心得体会与大家分享。
感谢 team509 的各位牛牛
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [翻译]sp 800系列翻译设想 12142
- [下载]IDA pro代码破解揭秘的随书例子下载 93413
- [注意]RE with IDA Pro的例子程序的答复 12865
- [注意]“惊”闻 RE with IDA Pro 就要面世了 329426
- [注意]一本新书,有人有意翻译吗? 3969
赞赏
雪币:
留言: