【软件名称】: Net meter
【下载地址】: 自己搜索下载
【保护方式】: 序列号和30天时间限制
【编写语言】: VC++6.0
【使用工具】: Ollydbg
【软件介绍】: 网络速度监控软件
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
简单介绍:年初的时候签了电信的ADSL2M,速度很慢,就想找款软件来监控下电信是不是克扣了
我的流量,就发现了这款软件.不过只能试用30天.当时研究了下,直接爆破了事.现在年底了,
再拿出来整整,了却一桩心事. 下面Let's begin.
1. peid扫描下,没有加壳,显示是Microsoft Visual C++ 6.0.一般来说VC++开发的程序,比较接近Win32,破解起来难度比较小.
2. 寻找注册函数
OD载入没有发现反调试, 直接查找注册失败提示字符串,进行定位
0040BD50 . 64:A1 0000000>mov eax, dword ptr fs:[0]
0040BD56 . 6A FF push -1
0040BD58 . 68 78AB4500 push 0045AB78
0040BD5D . 50 push eax
0040BD5E . 64:8925 00000>mov dword ptr fs:[0], esp
0040BD65 . 53 push ebx
0040BD66 . 56 push esi
0040BD67 . 57 push edi
0040BD68 . 8BF1 mov esi, ecx
0040BD6A . E8 7BC80400 call 004585EA
0040BD6F . 8B48 04 mov ecx, dword ptr [eax+4]
0040BD72 . E8 51360400 call 0044F3C8
0040BD77 . 6A 01 push 1
0040BD79 . 8BCE mov ecx, esi
0040BD7B . C74424 18 000>mov dword ptr [esp+18], 0
0040BD83 . E8 D91C0400 call 0044DA61
0040BD88 . 8D7E 5C lea edi, dword ptr [esi+5C]
0040BD8B . 8BCF mov ecx, edi
0040BD8D . E8 F4D10300 call 00448F86
0040BD92 . 8BCF mov ecx, edi
0040BD94 . E8 A4D10300 call 00448F3D
0040BD99 . 8D5E 60 lea ebx, dword ptr [esi+60]
0040BD9C . 8BCB mov ecx, ebx
0040BD9E . E8 E3D10300 call 00448F86
0040BDA3 . 8BCB mov ecx, ebx
0040BDA5 . E8 93D10300 call 00448F3D
0040BDAA . 8B07 mov eax, dword ptr [edi]
0040BDAC . 8B48 F8 mov ecx, dword ptr [eax-8]
0040BDAF . 85C9 test ecx, ecx
0040BDB1 . 75 0E jnz short 0040BDC1 ; //在此处下断点
0040BDB3 . 6A 30 push 30
0040BDB5 . 68 C8F24500 push 0045F2C8 ; net meter
0040BDBA . 68 28F44500 push 0045F428 ; invalid username. must not be empty.定位用的字符串(Unicode)
0040BDBF . EB 3B jmp short 0040BDFC
0040BDC1 > 8B1B mov ebx, dword ptr [ebx] ; ebx 中保存着输入的序列号
0040BDC3 . 8D4E 64 lea ecx, dword ptr [esi+64] ; 一个栈地址,估计是用来存返回信息的
0040BDC6 . 51 push ecx
0040BDC7 . 53 push ebx
0040BDC8 . E8 239B0200 call <Serial_check> ; 下面就是注册成功失败的提示信息,看来该函数就是注册码验证函数,因为参数中没有用户名,所以验证函数只和注册码有关
0040BDCD . 83C4 08 add esp, 8
0040BDD0 . 85C0 test eax, eax
0040BDD2 . 74 1C je short 0040BDF0 ; 可以考虑在这里爆破
0040BDD4 . 6A 40 push 40
0040BDD6 . 68 C8F24500 push 0045F2C8 ; net meter
0040BDDB . 68 74F44500 push 0045F474 ; register successfully. thank you for your support.
0040BDE0 . 8BCE mov ecx, esi
0040BDE2 . E8 84140400 call 0044D26B
0040BDE7 . 8BCE mov ecx, esi
0040BDE9 . E8 30400400 call 0044FE1E
0040BDEE . EB 13 jmp short 0040BE03
0040BDF0 > 6A 10 push 10
0040BDF2 . 68 C8F24500 push 0045F2C8 ; net meter
0040BDF7 . 68 DCF24500 push 0045F2DC ; invalid registration code.\nplease check that you entered exact information.\n\nif you have any problem with your registration code
0040BDFC > 8BCE mov ecx, esi
0040BDFE . E8 68140400 call 0044D26B
0040BE03 > C74424 14 FFF>mov dword ptr [esp+14], -1
0040BE0B . E8 DAC70400 call 004585EA
0040BE10 . 8B48 04 mov ecx, dword ptr [eax+4]
0040BE13 . E8 C5350400 call 0044F3DD
0040BE18 . 8B4C24 0C mov ecx, dword ptr [esp+C]
0040BE1C . 5F pop edi
0040BE1D . 5E pop esi
0040BE1E . 64:890D 00000>mov dword ptr fs:[0], ecx
0040BE25 . 5B pop ebx
0040BE26 . 83C4 0C add esp, 0C
0040BE29 . C3 retn
3.分析验证函数
004358F0 >/$ 81EC A0000000 sub esp, 0A0 ; 返回值0表明检查失败,返回1表示成功
004358F6 |. 56 push esi
004358F7 |. 8BB424 A80000>mov esi, dword ptr [esp+A8]
004358FE |. 56 push esi ; /String
004358FF |. FF15 5CE34500 call dword ptr [<&KERNEL32.lstrlenW>] ; \lstrlenW
00435905 |. 83F8 40 cmp eax, 40 ; 注册码长度必须为64
00435908 |. 74 0A je short 00435914
0043590A |. 33C0 xor eax, eax
0043590C |. 5E pop esi
0043590D |. 81C4 A0000000 add esp, 0A0
00435913 |. C3 retn
00435914 |> 53 push ebx
00435915 |. 55 push ebp
00435916 |. 8B2D 28E34500 mov ebp, dword ptr [<&KERNEL32.lstrc>; kernel32.lstrcpynW
0043591C |. 57 push edi
0043591D |. 8D7C24 10 lea edi, dword ptr [esp+10]
00435921 |. BB 08000000 mov ebx, 8
00435926 |> 6A 09 push 9
00435928 |. 8D4424 34 lea eax, dword ptr [esp+34]
0043592C |. 56 push esi
0043592D |. 50 push eax
0043592E |. FFD5 call ebp ; lstrcpy(&dst, serialNo, 9)
00435930 |. 57 push edi
00435931 |. 8D4C24 34 lea ecx, dword ptr [esp+34]
00435935 |. 68 CC4F4700 push 00474FCC ; %x
0043593A |. 51 push ecx
0043593B |. 83C6 10 add esi, 10
0043593E |. E8 E9310000 call 00438B2C ; swscanf(&dst, L"%x", seriakNo[i])
00435943 |. 83C4 0C add esp, 0C
00435946 |. 83C7 04 add edi, 4
00435949 |. 4B dec ebx
0043594A |.^ 75 DA jnz short 00435926 ; 这里实际是一个循环,把序列号当作一个16进制字符串,来恢复成一个8个整数数组
0043594C |. 8BBC24 B80000>mov edi, dword ptr [esp+B8]
00435953 |. B9 08000000 mov ecx, 8
00435958 |. 8D7424 10 lea esi, dword ptr [esp+10]
0043595C |. 8D5424 10 lea edx, dword ptr [esp+10]
00435960 |. F3:A5 rep movs dword ptr es:[edi], dword p>; 把整数数组结果拷贝到第二个参数指向的地址中
00435962 |. 52 push edx
00435963 |. E8 18000000 call <serialNo_check2(int[8] a)> ; 以整数数组为参数的函数,显然是对序列号做进一步检查
00435968 |. 83C4 04 add esp, 4
0043596B |. 5F pop edi
0043596C |. 5D pop ebp
0043596D |. 5B pop ebx
0043596E |. 5E pop esi
0043596F |. 81C4 A0000000 add esp, 0A0
00435975 \. C3 retn
4. 分析serialNo_check2(int[8] a)
00435980 >/$ 81EC C8000000 sub esp, 0C8 ; 注册码检查函数2,返回0表示失败,返回1为注册成功
00435986 |. 53 push ebx
00435987 |. 55 push ebp
00435988 |. 56 push esi
00435989 |. 8BB424 D80000>mov esi, dword ptr [esp+D8] ; esi = a[0]; //a即输入参数
00435990 |. 57 push edi
00435991 |. C74424 44 000>mov dword ptr [esp+44], 0 ; esp_44 = 0;
00435999 |. 8B5E 1C mov ebx, dword ptr [esi+1C] ; ebx = a[7]
0043599C |. 8B56 14 mov edx, dword ptr [esi+14] ; edx = a[5]
0043599F |. 8BC2 mov eax, edx
004359A1 |. 8BCB mov ecx, ebx
004359A3 |. 25 AB793B57 and eax, 573B79AB ; eax = a[5] & 0x573B79AB
004359A8 |. 81E1 5486C4A8 and ecx, A8C48654 ; ecx = a[7] & 0xA8C48654
004359AE |. 0FAFC1 imul eax, ecx ; eax = (a[5] & 0x573B79AB) * (a[7] & 0xA8C48654)
004359B1 |. 8B7E 04 mov edi, dword ptr [esi+4] ; edi = a[1]
004359B4 |. 894424 48 mov dword ptr [esp+48], eax ; esp_48 = (a[5] & 0x573B79AB) * (a[7] & 0xA8C48654)
004359B8 |. 8B46 10 mov eax, dword ptr [esi+10] ; eax=a[4]
004359BB |. 8BCF mov ecx, edi
004359BD |. 8BE8 mov ebp, eax
004359BF |. 81E1 31908848 and ecx, 48889031
004359C5 |. 81E5 CE6F77B7 and ebp, B7776FCE
004359CB |. C74424 6C 000>mov dword ptr [esp+6C], 0 ; esp_6c = 0
004359D3 |. 0FAFCD imul ecx, ebp
004359D6 |. 894C24 60 mov dword ptr [esp+60], ecx ; esp_60 = (a[4] & 0xB7776FCE) * (a[1] & 0x48889031)
004359DA |. 8BCF mov ecx, edi
004359DC |. 33CB xor ecx, ebx
004359DE |. 8B6E 18 mov ebp, dword ptr [esi+18] ; ebp = a[6]
004359E1 |. 81E1 7F755A3E and ecx, 3E5A757F
004359E7 |. 896C24 10 mov dword ptr [esp+10], ebp ; esp_10 = a[6]
004359EB |. 894C24 24 mov dword ptr [esp+24], ecx ; esp_24=(a[7] ^ a[1]) & 0x3E5A757F
004359EF |. 33CF xor ecx, edi
004359F1 |. 894C24 30 mov dword ptr [esp+30], ecx ; esp_30 = esp_24 ^ a[1]
004359F5 |. 8BCF mov ecx, edi
004359F7 |. 33CA xor ecx, edx
004359F9 |. 8BD7 mov edx, edi
004359FB |. 81E1 77777777 and ecx, 77777777
00435A01 |. 81E2 5486C4A8 and edx, A8C48654
00435A07 |. 33CF xor ecx, edi
00435A09 |. 898C24 D00000>mov dword ptr [esp+D0], ecx ; esp_d0 = ((a[5] ^ a[1]) & 0x77777777) ^ a[1]
00435A10 |. 8BCB mov ecx, ebx
00435A12 |. F7D1 not ecx
00435A14 |. 81E1 7F755A3E and ecx, 3E5A757F
00435A1A |. 0BCA or ecx, edx
00435A1C |. 8B56 0C mov edx, dword ptr [esi+C] ; edx = a[3]
00435A1F |. 894C24 78 mov dword ptr [esp+78], ecx ; esp_78 = (a[1] & 0xA8C48654) | (~a[7] & 0x3E5A757F)
00435A23 |. 8D4E 18 lea ecx, dword ptr [esi+18]
00435A26 |. 894C24 1C mov dword ptr [esp+1C], ecx ; esp_1c = &a[6]
00435A2A |. 8BCA mov ecx, edx
00435A2C |. 33CD xor ecx, ebp
00435A2E |. 895424 18 mov dword ptr [esp+18], edx ; esp_18=a[3]
00435A32 |. 81E1 31908848 and ecx, 48889031
00435A38 |. 8BEB mov ebp, ebx ; ebp = a[7]
00435A3A |. 33CA xor ecx, edx
00435A3C |. 33D2 xor edx, edx ; edx=0
00435A3E |. 894C24 20 mov dword ptr [esp+20], ecx ; esp_20 = a[3] ^ ((a[6] ^ a[3]) & 0x48889031)
00435A42 |. 894C24 28 mov dword ptr [esp+28], ecx ; esp_28 = a[3] ^ ((a[6] ^ a[3]) & 0x48889031)
00435A46 |. 69C9 73853409 imul ecx, ecx, 9348573
00435A4C |. 81E1 87A93434 and ecx, 3434A987
00435A52 |. 81E2 9823FEAD and edx, ADFE2398
00435A58 |. 894C24 38 mov dword ptr [esp+38], ecx ; esp_38 = (0x9348573 * (a[3] ^ ((a[6] ^ a[3]) & 0x48889031))) & 0x3434A987
00435A5C |. 8B4E 08 mov ecx, dword ptr [esi+8] ; ecx=a[2]
00435A5F |. 895424 3C mov dword ptr [esp+3C], edx ; esp_3C = 0
00435A63 |. 8BD1 mov edx, ecx
00435A65 |. 33D0 xor edx, eax
00435A67 |. 81E5 37422398 and ebp, 98234237
00435A6D |. 81E2 77777777 and edx, 77777777
00435A73 |. 33D0 xor edx, eax
00435A75 |. 895424 2C mov dword ptr [esp+2C], edx ; esp_2c=a[4] ^ ((a[4] ^ a[2]) & 0x77777777)
00435A79 |. 8B16 mov edx, dword ptr [esi] ; edx = a[0]
00435A7B |. 895424 14 mov dword ptr [esp+14], edx ; esp_14=a[0]
00435A7F |. 81E2 E93A8290 and edx, 90823AE9
00435A85 |. 0FAFD5 imul edx, ebp
00435A88 |. 895424 40 mov dword ptr [esp+40], edx ; esp_40 = (a[7] & 0x98234237) * (a[0] & 0x90823AE9)
00435A8C |. 8B5424 10 mov edx, dword ptr [esp+10] ; edx = a[6]
00435A90 |. 8BEB mov ebp, ebx ; ebp = a[7]
00435A92 |. 81E2 808AA5C1 and edx, C1A58A80
00435A98 |. 81E5 7F755A3E and ebp, 3E5A757F
00435A9E |. 0FAFD5 imul edx, ebp
00435AA1 |. 8B6E 14 mov ebp, dword ptr [esi+14] ; ebp = a[5]
00435AA4 |. 895424 68 mov dword ptr [esp+68], edx ; esp_68 = (a[7] & 0x3E5A757F) * ((a[6] & 0xC1A58A80);
00435AA8 |. 8B5424 14 mov edx, dword ptr [esp+14]
00435AAC |. 33D5 xor edx, ebp
00435AAE |. 81E2 AB793B57 and edx, 573B79AB
00435AB4 |. 25 31908848 and eax, 48889031 ; eax = (a[4] & 0x48889031)
00435AB9 |. 33D5 xor edx, ebp
00435ABB |. 8BE9 mov ebp, ecx
00435ABD |. 899424 840000>mov dword ptr [esp+84], edx ; esp_84=a[5] ^ ((a[5] ^ a[0]) & 0x573B79AB)
00435AC4 |. 8B5424 10 mov edx, dword ptr [esp+10]
00435AC8 |. 33EA xor ebp, edx
00435ACA |. 8B5424 24 mov edx, dword ptr [esp+24] ; edx = (a[7] ^ a[1]) & 0x3E5A757F
00435ACE |. 81E5 31908848 and ebp, 48889031 ; ebp=
00435AD4 |. 68 98720000 push 7298
00435AD9 |. 33E9 xor ebp, ecx ; ebp = a[2] ^ ((a[6] ^ a[2]) & 0x48889031)
00435ADB |. 81E1 7F755A3E and ecx, 3E5A757F
00435AE1 |. 0FAFC1 imul eax, ecx
00435AE4 |. 894424 54 mov dword ptr [esp+54], eax ; esp_50 = (a[2] & 0x3E5A757F) * (a[4] & 0x48889031)
00435AE8 |. 8B4424 1C mov eax, dword ptr [esp+1C] ; eax = &a[3]
00435AEC |. 68 988776A8 push A8768798
00435AF1 |. 33D3 xor edx, ebx
00435AF3 |. 6A 00 push 0
00435AF5 |. 50 push eax
00435AF6 |. 895424 24 mov dword ptr [esp+24], edx ; esp_14 = a[7] ^ ((a[7] ^ a[1]) & 0x3E5A757F)
00435AFA |. E8 71300000 call <mul(int64,int64) i2hi2l i1hi1l >; eax * 0x7298A8768798
00435AFF |. 8B4C24 38 mov ecx, dword ptr [esp+38]
00435B03 |. 23C1 and eax, ecx
00435B05 |. 8B4C24 3C mov ecx, dword ptr [esp+3C]
00435B09 |. 23D1 and edx, ecx
00435B0B |. 3D 80A628C4 cmp eax, C428A680
00435B10 |. 75 3E jnz short 00435B50
00435B12 |. 81FA 723AE792 cmp edx, 92E73A72
00435B18 |. 75 36 jnz short 00435B50 ; if( ((eax * 0x7298A8768798) & (esp_3c:esp38)) != 0x92E73A72 c428A680 jmp 00435b50 (esp_3c = 0 所以这个不可能成立)
00435B1A |. 8B5C24 20 mov ebx, dword ptr [esp+20] ; 因为esp_3c == 0; 所以这里不可能执行
00435B1E |. 8B7C24 14 mov edi, dword ptr [esp+14]
00435B22 |. 33ED xor ebp, ebp
00435B24 |. 33C0 xor eax, eax
00435B26 |. 899C24 980000>mov dword ptr [esp+98], ebx
00435B2D |. 89AC24 9C0000>mov dword ptr [esp+9C], ebp
00435B34 |. 23DF and ebx, edi
00435B36 |. 23E8 and ebp, eax
00435B38 |. 81F3 46838419 xor ebx, 19848346
00435B3E |. 898424 940000>mov dword ptr [esp+94], eax
00435B45 |. 81F5 35716887 xor ebp, 87687135
00435B4B |. E9 93010000 jmp 00435CE3
00435B50 |> 0FAFAC24 D000>imul ebp, dword ptr [esp+D0] ; we are here; ebp = esp_d0 * (a[2] ^ ((a[6] ^ a[2]) & 0x48889031))
00435B58 |. 8B5424 48 mov edx, dword ptr [esp+48] ; edx = esp_48
00435B5C |. 8BC5 mov eax, ebp ; eax = ebp
00435B5E |. 33ED xor ebp, ebp ; ebp = 0
00435B60 |. 33C9 xor ecx, ecx ; ecx = 0
00435B62 |. 3BC2 cmp eax, edx
00435B64 |. 75 57 jnz short 00435BBD ; if(esp_48 != esp_d0 * (a[2] ^ ((a[6] ^ a[2]) & 0x48889031))) jump 435BDD
00435B66 |. 33C0 xor eax, eax ; eax = 0
00435B68 |. 3BC8 cmp ecx, eax ; eax = 0, ecx = 0;
00435B6A |. 75 51 jnz short 00435BBD ; 该跳转不可能
00435B6C |. 8B4424 10 mov eax, dword ptr [esp+10] ; esp_48 == esp_d0 * (a[2] ^ ((a[6] ^ a[2]) & 0x48889031))
00435B70 |. 8B4C24 18 mov ecx, dword ptr [esp+18]
00435B74 |. 25 5486C4A8 and eax, A8C48654
00435B79 |. 81E1 CE6F77B7 and ecx, B7776FCE
00435B7F |. 81E7 AB793B57 and edi, 573B79AB
00435B85 |. 81E3 808AA5C1 and ebx, C1A58A80
00435B8B |. 0BC1 or eax, ecx ; eax = (a[6] & A8C48654) | (esp_18 & 0xB7776FCE)
00435B8D |. 0BFB or edi, ebx ; edi = (a[7] & 0xC1A58A80) | (a[1] & 0x573B79AB)
00435B8F |. 8BD8 mov ebx, eax
00435B91 |. 33D2 xor edx, edx ; edx = 0
00435B93 |. 89AC24 9C0000>mov dword ptr [esp+9C], ebp ; esp_9c = 0
00435B9A |. 33DF xor ebx, edi
00435B9C |. 33EA xor ebp, edx
00435B9E |. 81F3 858F0019 xor ebx, 19008F85 ; ebx = eax ^ edi ^ 0x19008F85
00435BA4 |. 899424 940000>mov dword ptr [esp+94], edx ; esp_94 = 0
00435BAB |. 898424 980000>mov dword ptr [esp+98], eax ; esp_98 = (esp_18 & 0xB7776FCE) | (a[6] & 0xA8C48654)
00435BB2 |. 81F5 66EC6827 xor ebp, 2768EC66 ; ebp = 0x2768EC66 至此5个值都赋值了ebp, edi, ebx, esp_94, esp_98, 同时esp_9c也赋了值
00435BB8 |. E9 26010000 jmp 00435CE3
00435BBD |> 8B4C24 14 mov ecx, dword ptr [esp+14]
00435BC1 |. 8B5424 28 mov edx, dword ptr [esp+28]
00435BC5 |. 33CA xor ecx, edx
00435BC7 |. F7C1 472383AE test ecx, AE832347
00435BCD |. 0F84 C2000000 je 00435C95 ; (esp[28] ^ a[0]) & 0xAE832347 == 0 jump
00435BD3 |. 8B5C24 1C mov ebx, dword ptr [esp+1C] ; ebx = &a[6]
00435BD7 |. 33FF xor edi, edi ; edi = 0
00435BD9 |. 89AC24 940000>mov dword ptr [esp+94], ebp ; ebp 的值为0
00435BE0 |. 89AC24 980000>mov dword ptr [esp+98], ebp
00435BE7 |. 89AC24 9C0000>mov dword ptr [esp+9C], ebp
00435BEE |. 897424 10 mov dword ptr [esp+10], esi ; esp_10 = a[0]
00435BF2 |. C74424 18 070>mov dword ptr [esp+18], 7
00435BFA |> 8B5424 10 /mov edx, dword ptr [esp+10]
00435BFE |. 8B0B |mov ecx, dword ptr [ebx]
00435C00 |. F7D1 |not ecx
00435C02 |. 8B02 |mov eax, dword ptr [edx]
00435C04 |. 8BD1 |mov edx, ecx
00435C06 |. 8BE8 |mov ebp, eax ; ebp = a[i], adx = ^a[6-i]
00435C08 |. 81E2 808AA5C1 |and edx, C1A58A80
00435C0E |. 81E5 AB793B57 |and ebp, 573B79AB
00435C14 |. 0FAFD5 |imul edx, ebp ; edx = (a[i] & 0x573B79AB) * (a[6 - i] & 0xC1A58A80)
00435C17 |. 8BAC24 940000>|mov ebp, dword ptr [esp+94]
00435C1E |. 03FA |add edi, edx
00435C20 |. BA 00000000 |mov edx, 0
00435C25 |. 13EA |adc ebp, edx
00435C27 |. 25 CE6F77B7 |and eax, B7776FCE
00435C2C |. 81E1 5486C4A8 |and ecx, A8C48654
00435C32 |. 89AC24 940000>|mov dword ptr [esp+94], ebp ; esp_94:edi += edx
00435C39 |. 0FAFC1 |imul eax, ecx
00435C3C |. 8B8C24 980000>|mov ecx, dword ptr [esp+98]
00435C43 |. 8BAC24 9C0000>|mov ebp, dword ptr [esp+9C]
00435C4A |. 03C8 |add ecx, eax
00435C4C |. 8B4424 18 |mov eax, dword ptr [esp+18]
00435C50 |. 898C24 980000>|mov dword ptr [esp+98], ecx
00435C57 |. 8B4C24 10 |mov ecx, dword ptr [esp+10]
00435C5B |. 13EA |adc ebp, edx
00435C5D |. 83EB 04 |sub ebx, 4
00435C60 |. 83C1 04 |add ecx, 4
00435C63 |. 48 |dec eax
00435C64 |. 89AC24 9C0000>|mov dword ptr [esp+9C], ebp ; esp_9c:esp_98 += (a[6 - i] & 0xA8C48654) * (a[i] & 0xB7776FCE)
00435C6B |. 894C24 10 |mov dword ptr [esp+10], ecx
00435C6F |. 894424 18 |mov dword ptr [esp+18], eax
00435C73 |.^ 75 85 \jnz short 00435BFA ; 等价于for(int 1=0; i<7; i++)
00435C75 |. 8B9C24 980000>mov ebx, dword ptr [esp+98]
00435C7C |. 8B9424 940000>mov edx, dword ptr [esp+94] ; edx = esp_94
00435C83 |. 23DF and ebx, edi
00435C85 |. 23EA and ebp, edx
00435C87 |. 81F3 4A98AE68 xor ebx, 68AE984A ; ebx:ebp = (sum1 & sum2) ^ (0x35489719:0x68AE984A )
00435C8D |. 81F5 19974835 xor ebp, 35489719
00435C93 |. EB 4E jmp short 00435CE3
00435C95 |> 55 push ebp ; 该分支对应的5个值也被赋了值,但是是用GetTickCount,rand(), time(0)等函数的结果赋值的,所以这个流程基本走不通
00435C96 |. E8 F3230000 call 0043808E
00435C9B |. 83C4 04 add esp, 4
00435C9E |. 8BF8 mov edi, eax
00435CA0 |. E8 C7230000 call 0043806C
00435CA5 |. 0FAFF8 imul edi, eax
00435CA8 |. FF15 0CE34500 call dword ptr [<&KERNEL32.GetTickCou>; [GetTickCount
00435CAE |. 0FAFF8 imul edi, eax
00435CB1 |. 8B4E 04 mov ecx, dword ptr [esi+4]
00435CB4 |. 33C0 xor eax, eax
00435CB6 |. 50 push eax
00435CB7 |. 57 push edi
00435CB8 |. 55 push ebp
00435CB9 |. 51 push ecx
00435CBA |. 898424 A40000>mov dword ptr [esp+A4], eax
00435CC1 |. E8 AA2E0000 call <mul(int64,int64) i2hi2l i1hi1l >
00435CC6 |. 898424 980000>mov dword ptr [esp+98], eax
00435CCD |. 8BD8 mov ebx, eax
00435CCF |. 8B8424 940000>mov eax, dword ptr [esp+94]
00435CD6 |. 8BEA mov ebp, edx
00435CD8 |. 33DF xor ebx, edi
00435CDA |. 899424 9C0000>mov dword ptr [esp+9C], edx
00435CE1 |. 33E8 xor ebp, eax
00435CE3 |> 8B0E mov ecx, dword ptr [esi] ; now we are here.开始第二阶段
00435CE5 |. 8B56 14 mov edx, dword ptr [esi+14]
00435CE8 |. 8BC1 mov eax, ecx
00435CEA |. 6A 00 push 0 ; 注意这里esp的值加了4
00435CEC |. 33C2 xor eax, edx
00435CEE |. 8B5424 20 mov edx, dword ptr [esp+20]
00435CF2 |. 25 AB793B57 and eax, 573B79AB
00435CF7 |. 33C1 xor eax, ecx
00435CF9 |. 894424 74 mov dword ptr [esp+74], eax ; esp_70 = a[0] ^ ((a[5] ^ a[0]) & 0x573B79AB)
00435CFD |. 8B4424 2C mov eax, dword ptr [esp+2C]
00435D01 |. 35 64316121 xor eax, 21613164
00435D06 |. 894424 2C mov dword ptr [esp+2C], eax ; esp_28 ^= 0x21613164
00435D0A |. 8B46 08 mov eax, dword ptr [esi+8]
00435D0D |. 8B32 mov esi, dword ptr [edx]
00435D0F |. F7D6 not esi
00435D11 |. 33F0 xor esi, eax
00435D13 |. 81E6 31908848 and esi, 48889031
00435D19 |. 33F0 xor esi, eax ; esi = a[2] ^ ((a[2] ^ ~a[6]) & 0x48889031);
00435D1B |. 8B4424 30 mov eax, dword ptr [esp+30]
00435D1F |. 35 159A4865 xor eax, 65489A15
00435D24 |. 894424 30 mov dword ptr [esp+30], eax ; esp_28 ^= 0x65489A15
00435D28 |. E8 61230000 call 0043808E
00435D2D |. 83C4 04 add esp, 4
00435D30 |. E8 37230000 call 0043806C
00435D35 |. FF15 0CE34500 call dword ptr [<&KERNEL32.GetTickCou>; [GetTickCount
00435D3B |. 8B4424 28 mov eax, dword ptr [esp+28] ; eax被直接赋值,所以上面3个函数为干扰函数
00435D3F |. 8B5424 30 mov edx, dword ptr [esp+30]
00435D43 |. 8B8C24 840000>mov ecx, dword ptr [esp+84]
00435D4A |. 33C2 xor eax, edx ; eax = esp_28 ^ esp_30
00435D4C |. 81F1 ECA89458 xor ecx, 5894A8EC ; ecx = esp_84 ^ 0x5894A8EC
00435D52 |. 3D EA4F7A89 cmp eax, 897A4FEA
00435D57 |. 0F85 99000000 jnz 00435DF6 ; 分支
00435D5D |. 8B4424 70 mov eax, dword ptr [esp+70]
00435D61 |. 8B7424 2C mov esi, dword ptr [esp+2C]
00435D65 |. 33C6 xor eax, esi
00435D67 |. 3D 544F7A98 cmp eax, 987A4F54
00435D6C |. 74 49 je short 00435DB7 ; if((esp_70 ^ esp_2c) == 0x987A4F54) jmp
00435D6E |. 8B4424 68 mov eax, dword ptr [esp+68]
00435D72 |. 8B7C24 50 mov edi, dword ptr [esp+50]
00435D76 |. 8B4C24 6C mov ecx, dword ptr [esp+6C]
00435D7A |. 8B6C24 60 mov ebp, dword ptr [esp+60]
00435D7E |. F7D0 not eax
00435D80 |. 23C7 and eax, edi
00435D82 |. 33D2 xor edx, edx
00435D84 |. F7D1 not ecx
00435D86 |. 33C5 xor eax, ebp
00435D88 |. 23CA and ecx, edx
00435D8A |. F7D0 not eax
00435D8C |. 33CA xor ecx, edx
00435D8E |. 3D 2802C042 cmp eax, 42C00228
00435D93 |. F7D1 not ecx
00435D95 |. 0F85 12010000 jnz 00435EAD
00435D9B |. 81F9 8AE96598 cmp ecx, 9865E98A ; ecx = ^(x & 0 ^ 0)
00435DA1 |. 0F85 06010000 jnz 00435EAD ; go to failure
00435DA7 |. 5F pop edi ; not enter
00435DA8 |. 5E pop esi
00435DA9 |. 5D pop ebp
00435DAA |. B8 01000000 mov eax, 1 ;这是一个比较好的爆破点,可以修改程序的开头直接跳到这个位置
00435DAF |. 5B pop ebx
00435DB0 |. 81C4 C8000000 add esp, 0C8
00435DB6 |. C3 retn
00435DB7 |> B8 F1F0F0F0 mov eax, F0F0F0F1
00435DBC |. F7E1 mul ecx ; ecx = esp_84 ^ 0x5894A8EC 从前面copy的
00435DBE |. C1EA 04 shr edx, 4
00435DC1 |. B8 4FECC44E mov eax, 4EC4EC4F
00435DC6 |. 8BFA mov edi, edx
00435DC8 |. F7E1 mul ecx
00435DCA |. 0FAFFE imul edi, esi
00435DCD |. 8B4424 28 mov eax, dword ptr [esp+28]
00435DD1 |. 8B4C24 14 mov ecx, dword ptr [esp+14]
00435DD5 |. C1EA 02 shr edx, 2
00435DD8 |. 0FAFF0 imul esi, eax
00435DDB |. 0FAFD0 imul edx, eax
00435DDE |. 03FA add edi, edx
00435DE0 |. 33C0 xor eax, eax
00435DE2 |. 03FE add edi, esi
00435DE4 |. F7D7 not edi
00435DE6 |. 3BF9 cmp edi, ecx ; ~(esp_28 * esp_2c + esp_28 * ecx / 13 + esp_2c * ecx / 17) == esp_14;
00435DE8 |. 5F pop edi
00435DE9 |. 5E pop esi
00435DEA |. 5D pop ebp
00435DEB |. 0F94C0 sete al ; 如果上面等式成立,则注册成功
00435DEE |. 5B pop ebx
00435DEF |. 81C4 C8000000 add esp, 0C8
00435DF5 |. C3 retn
00435DF6 |> 8B4424 40 mov eax, dword ptr [esp+40]
00435DFA |. 8B5424 48 mov edx, dword ptr [esp+48]
00435DFE |. 33C2 xor eax, edx
00435E00 |. 8B5424 44 mov edx, dword ptr [esp+44]
00435E04 |. C74424 4C 000>mov dword ptr [esp+4C], 0 ; esp_4c == 0
00435E0C |. 335424 4C xor edx, dword ptr [esp+4C] ; edx = edx
00435E10 |. 3D E8005A5F cmp eax, 5F5A00E8
00435E15 |. 75 5A jnz short 00435E71
00435E17 |. 81FA E48954A6 cmp edx, A65489E4
00435E1D |. 75 52 jnz short 00435E71 ; (esp_48 ^ esp_40) == 0x5F5A00E8 && esp_44 == 0xA65489E4 如果不满足跳转00435E71
00435E1F |. B8 25499224 mov eax, 24924925
00435E24 |. 0FAF7424 78 imul esi, dword ptr [esp+78]
00435E29 |. F7E1 mul ecx ; ecx = esp_84 ^ 0x5894A8EC 从前面copy的
00435E2B |. 8BC1 mov eax, ecx
00435E2D |. 2BC2 sub eax, edx
00435E2F |. D1E8 shr eax, 1
00435E31 |. 03C2 add eax, edx
00435E33 |. C1E8 02 shr eax, 2
00435E36 |. 8BF8 mov edi, eax
00435E38 |. B8 CB6B28AF mov eax, AF286BCB
00435E3D |. F7E1 mul ecx
00435E3F |. 0FAF7C24 2C imul edi, dword ptr [esp+2C]
00435E44 |. 2BCA sub ecx, edx
00435E46 |. 33C0 xor eax, eax
00435E48 |. D1E9 shr ecx, 1
00435E4A |. 03CA add ecx, edx
00435E4C |. C1E9 04 shr ecx, 4
00435E4F |. 0FAF4C24 28 imul ecx, dword ptr [esp+28]
00435E54 |. 03F9 add edi, ecx
00435E56 |. 8B8C24 D00000>mov ecx, dword ptr [esp+D0]
00435E5D |. 03FE add edi, esi
00435E5F |. F7D7 not edi
00435E61 |. 3BF9 cmp edi, ecx
00435E63 |. 5F pop edi
00435E64 |. 5E pop esi
00435E65 |. 5D pop ebp
00435E66 |. 0F94C0 sete al ; return ~(esp_78 * esi + esp_28 * ecx / 19 + esp_2c * ecx /7) == esp_d0
00435E69 |. 5B pop ebx
00435E6A |. 81C4 C8000000 add esp, 0C8
00435E70 |. C3 retn
00435E71 |> 8B8424 980000>mov eax, dword ptr [esp+98]
00435E78 |. 8B8C24 9C0000>mov ecx, dword ptr [esp+9C]
00435E7F |. 8B9424 940000>mov edx, dword ptr [esp+94]
00435E86 |. 23C7 and eax, edi
00435E88 |. 23CA and ecx, edx
00435E8A |. 33C3 xor eax, ebx
00435E8C |. 33CD xor ecx, ebp
00435E8E |. 3D 4F79AE48 cmp eax, 48AE794F
00435E93 |. 75 18 jnz short 00435EAD
00435E95 |. 81F9 34023784 cmp ecx, 84370234 ; ((esp_98 & edi) ^ ebx == 0x48AE794F) && (((esp_9c & esp_94) ^ ebp) == 0x84370234)
00435E9B |. 75 10 jnz short 00435EAD
00435E9D |. 5F pop edi
00435E9E |. 5E pop esi
00435E9F |. 5D pop ebp
00435EA0 |. B8 01000000 mov eax, 1
00435EA5 |. 5B pop ebx
00435EA6 |. 81C4 C8000000 add esp, 0C8
00435EAC |. C3 retn
00435EAD |> 5F pop edi
00435EAE |. 5E pop esi
00435EAF |. 5D pop ebp
00435EB0 |. 33C0 xor eax, eax
00435EB2 |. 5B pop ebx
00435EB3 |. 81C4 C8000000 add esp, 0C8
00435EB9 \. C3 retn
总结:改注册码验证函数使用了一下几个手段来增加逆向难度。
1.使用了8个整数的值来做注册码,使穷举变得基本不可能。
2.使用了与运算这种单向不可逆运算,模糊运算的中间值和注册码本身的关系。
3.加入无用代码,如GetTickCount等3个函数的调用。
4.增加了无效分支,用随机值来填充中间数据,把逆向者引入歧途。
5.函数分支众多。
读者可以根据上面描述的计算步骤,自己尝试写出注册算法。
5. 拆解时间保护.
如果采用爆破的方法,在试用30天后,你会发现程序启动5分钟后,还是会弹出提示过了试用期,确定后退出.显然这里存在个计时器,在启动后再次进行检查.
在所有的SetTimer参考上下断点,
参考位于 HooNetMe:.text 到 USER32.SetTimer
地址 反汇编 注释
0040A1E9 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0040CB40 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0040F1FF call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0041152F call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
004118CD call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
00419ACA call dword ptr [<&USER32.SetTimer>] USER32.SetTimer 这是我们要找的目标
0041AD2F call dword ptr [<&USER32.SetTimer>] USER32.SetTimer 这是我们要找的目标
0041B6A5 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0041BF28 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0042B4B7 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0042DC12 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
0043014C call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
00433922 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
00453303 call dword ptr [<&USER32.SetTimer>] USER32.SetTimer
这所以把上面两个列入目标,是因为只有这两个函数的周期比较可以(300s和600s)
双击第一个进入
00419ABE |> \68 20144300 push 00431420 ; /Timerproc = HooNetMe.00431420
00419AC3 |. 68 E0930400 push 493E0 ; |Timeout = 300000. ms
00419AC8 |. 55 push ebp ; |TimerID
00419AC9 |. 55 push ebp ; |hWnd
00419ACA |. FF15 10E54500 call dword ptr [<&USER32.SetTimer>] ; \SetTimer
然后再来到HooNetMe.00431420
00431420 . 56 push esi
00431421 . E8 E4D10100 call 0044E60A
00431426 . 85C0 test eax, eax
00431428 . 74 0B je short 00431435
0043142A . 8B10 mov edx, dword ptr [eax]
0043142C . 8BC8 mov ecx, eax
0043142E . FF52 74 call dword ptr [edx+74]
00431431 . 8BF0 mov esi, eax
00431433 . EB 02 jmp short 00431437
00431435 > 33F6 xor esi, esi
00431437 > F786 A0000000>test dword ptr [esi+A0], A6000000
00431441 . 74 33 je short 00431476
00431443 . 8D46 5C lea eax, dword ptr [esi+5C]
00431446 . 50 push eax
00431447 . E8 D44E0000 call 00436320 ;该函数很可疑,进入看看
0043144C . 83C4 04 add esp, 4
0043144F . 85C0 test eax, eax
00431451 . 75 23 jnz short 00431476 ; 爆破点
00431453 . 817E 7C 20040>cmp dword ptr [esi+7C], 420
0043145A . 76 1A jbe short 00431476
0043145C . 8BCE mov ecx, esi
0043145E . E8 DDA1FEFF call 0041B640
00431463 . 8B4E 1C mov ecx, dword ptr [esi+1C]
00431466 . 6A 00 push 0 ; /lParam = 0
00431468 . 6A 00 push 0 ; |wParam = 0
0043146A . 68 77040000 push 477 ; |Message = MSG(477)
0043146F . 51 push ecx ; |hWnd
00431470 . FF15 08E54500 call dword ptr [<&USER32.PostMessageW>; \PostMessageW
00431476 > 8B96 A4000000 mov edx, dword ptr [esi+A4]
0043147C . 52 push edx ; /TimerID
0043147D . 6A 00 push 0 ; |hWnd = NULL
0043147F . FF15 04E54500 call dword ptr [<&USER32.KillTimer>] ; \KillTimer
00431485 . 5E pop esi
00431486 . C2 1000 retn 10
进入436320
00436320 /$ 8B4424 04 mov eax, dword ptr [esp+4]
00436324 |. 53 push ebx
00436325 |. 55 push ebp
00436326 |. 56 push esi
00436327 |. 8B50 14 mov edx, dword ptr [eax+14]
0043632A |. 8B18 mov ebx, dword ptr [eax]
0043632C |. 8B68 18 mov ebp, dword ptr [eax+18]
0043632F |. 8BCA mov ecx, edx
00436331 |. 33CB xor ecx, ebx
00436333 |. 8B58 08 mov ebx, dword ptr [eax+8]
00436336 |. 81E1 AB793B57 and ecx, 573B79AB
0043633C |. 57 push edi
0043633D |. 33CA xor ecx, edx
0043633F |. 8B50 0C mov edx, dword ptr [eax+C]
00436342 |. 33EA xor ebp, edx
00436344 |. 81F1 ECA89458 xor ecx, 5894A8EC ;ecx = a[5] ^ ((a[0] ^ a[5]) & 0x573B79AB) ^ 0x5894A8EC
0043634A |. 81E5 31908848 and ebp, 48889031
00436350 |. 8B78 10 mov edi, dword ptr [eax+10]
00436353 |. 33EA xor ebp, edx
00436355 |. B8 ABAAAAAA mov eax, AAAAAAAB
0043635A |. 81F5 64316121 xor ebp, 21613164 ;ebp = a[3] ^ ((a[3] ^ a[6]) & 0x48889031) ^ 0x21613164
00436360 |. 8BF3 mov esi, ebx
00436362 |. 0FAFE9 imul ebp, ecx
00436365 |. F7E5 mul ebp
00436367 |. 33F7 xor esi, edi
00436369 |. 81E6 77777777 and esi, 77777777
0043636F |. 8BC6 mov eax, esi
00436371 |. 33F3 xor esi, ebx ;esi = a[2] ^ ((a[4] ^ a[2]) & 0x77777777)
00436373 |. 33C7 xor eax, edi
00436375 |. 5F pop edi
00436376 |. D1EA shr edx, 1 ;edx =
00436378 |. 35 159A4865 xor eax, 65489A15 ;eax = a[4] ^ ((a[4] ^ a[2]) & 0x77777777) ^ 0x65489a15
0043637D |. 2BC2 sub eax, edx
0043637F |. 03C1 add eax, ecx
00436381 |. 33C9 xor ecx, ecx
00436383 |. F7D0 not eax
00436385 |. 3BC6 cmp eax, esi
00436387 |. 5E pop esi
00436388 |. 0F94C1 sete cl
0043638B |. 5D pop ebp
0043638C |. 8BC1 mov eax, ecx
0043638E |. 5B pop ebx
0043638F \. C3 retn
该函数伪代码如下:
int foo(int[8] a){
//这里用到了a[0], a[2], a[3], a[4], a[5], a[6]
if(~((a[5] ^ ((a[0] ^ a[5]) & 0x573B79AB) ^ 0x5894A8EC)
+ (a[4] ^ ((a[4] ^ a[2]) & 0x77777777) ^ 0x65489a15)
- (a[5] ^ ((a[0] ^ a[5]) & 0x573B79AB) ^ 0x5894A8EC)
* (a[3] ^ ((a[3] ^ a[6]) & 0x48889031) ^ 0x21613164)
/ 3) == (a[2] ^ ((a[4] ^ a[2]) & 0x77777777)))
return 1;
return 0;
}
由此可见,注册码还必须满足这里的条件。
双击第二个目标进入
0041AD23 |> \68 507D4200 push 00427D50 ; /Timerproc = HooNetMe.00427D50
0041AD28 |. 68 C0270900 push 927C0 ; |Timeout = 600000. ms
0041AD2D |. 53 push ebx ; |TimerID
0041AD2E |. 53 push ebx ; |hWnd
0041AD2F |. FF15 10E54500 call dword ptr [<&USER32.SetTimer>] ; \SetTimer
然后再来到HooNetMe.00427D50
00427D50 . 56 push esi
00427D51 . E8 B4680200 call 0044E60A
00427D56 . 85C0 test eax, eax
00427D58 . 74 0B je short 00427D65
00427D5A . 8B10 mov edx, dword ptr [eax]
00427D5C . 8BC8 mov ecx, eax
00427D5E . FF52 74 call dword ptr [edx+74]
00427D61 . 8BF0 mov esi, eax
00427D63 . EB 02 jmp short 00427D67
00427D65 > 33F6 xor esi, esi
00427D67 > F786 A0000000>test dword ptr [esi+A0], A6000000
00427D71 . 74 33 je short 00427DA6
00427D73 . 8D46 5C lea eax, dword ptr [esi+5C]
00427D76 . 50 push eax
00427D77 . E8 44E10000 call 00435EC0 ;该函数比较可以,进去查看后实际会发现就是serialNo_check2的功能
00427D7C . 83C4 04 add esp, 4
00427D7F . 85C0 test eax, eax
00427D81 . 75 23 jnz short 00427DA6 ; 爆破点
00427D83 . 817E 7C E0030>cmp dword ptr [esi+7C], 3E0 ;发注册码不合法消息,从而弹出窗口提示试用结束(估计应该还会先检测是否过试用期)
00427D8A . 76 1A jbe short 00427DA6
00427D8C . 8BCE mov ecx, esi
00427D8E . E8 AD38FFFF call 0041B640
00427D93 . 8B4E 1C mov ecx, dword ptr [esi+1C]
00427D96 . 6A 00 push 0 ; /lParam = 0
00427D98 . 6A 00 push 0 ; |wParam = 0
00427D9A . 68 77040000 push 477 ; |Message = MSG(477)
00427D9F . 51 push ecx ; |hWnd
00427DA0 . FF15 08E54500 call dword ptr [<&USER32.PostMessageW>; \PostMessageW
00427DA6 > 8B96 A8000000 mov edx, dword ptr [esi+A8]
00427DAC . 52 push edx ; /TimerID
00427DAD . 6A 00 push 0 ; |hWnd = NULL
00427DAF . FF15 04E54500 call dword ptr [<&USER32.KillTimer>] ; \KillTimer
00427DB5 . 5E pop esi
00427DB6 . C2 1000 retn 10
虽然函数00435EC0和serialNo_check2的功能一致,但是他们属于不同的函数,所以仅仅爆破serialNo_check2是不行的。
6. 更进一步,寻找试用时间的相关信息的存储位置
寻找读取注册表的操作,发现该程序读取了一个HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ShellExStateN的注册表项。
通过查找ShellExStateN字符串的方法可以到来到一下代码处
004114D8 . 50 push eax ; /pHandle
004114D9 . 6A 01 push 1 ; |Access = KEY_QUERY_VALUE
004114DB . 6A 00 push 0 ; |Reserved = 0
004114DD . 51 push ecx ; |Subkey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
004114DE . 68 01000080 push 80000001 ; |hKey = HKEY_CURRENT_USER
004114E3 . FF15 04E04500 call dword ptr [<&ADVAPI32.RegOpenKey>; \RegOpenKeyExW
004114E9 . 85C0 test eax, eax
004114EB . 75 34 jnz short 00411521
004114ED . 8D5424 14 lea edx, dword ptr [esp+14]
004114F1 . 8D4424 2C lea eax, dword ptr [esp+2C]
004114F5 . 52 push edx ; /pBufSize
004114F6 . 8B5424 14 mov edx, dword ptr [esp+14] ; |
004114FA . 8D4C24 1C lea ecx, dword ptr [esp+1C] ; |
004114FE . 50 push eax ; |Buffer ;在Buffer地址处下内存访问断点
004114FF . 51 push ecx ; |pValueType
00411500 . 6A 00 push 0 ; |Reserved = NULL
00411502 . 68 840A4600 push 00460A84 ; |shellexstaten
00411507 . 52 push edx ; |hKey
00411508 . C74424 2C 3C0>mov dword ptr [esp+2C], 3C ; |
00411510 . FF15 00E04500 call dword ptr [<&ADVAPI32.RegQueryVa>; \RegQueryValueExW
下内存断点后,F9运行,然后停在下面的函数里面。
0040FC20 /$ 8B4424 0C mov eax, dword ptr [esp+C]
0040FC24 |. 53 push ebx
0040FC25 |. 55 push ebp
0040FC26 |. 56 push esi
0040FC27 |. 8B7424 10 mov esi, dword ptr [esp+10] ;参数1保存着注册表shellexstaten的键值
0040FC2B |. 33C9 xor ecx, ecx
0040FC2D |. 8908 mov dword ptr [eax], ecx
0040FC2F |. 57 push edi
0040FC30 |. 8B46 0C mov eax, dword ptr [esi+C]
0040FC33 |. 8B56 38 mov edx, dword ptr [esi+38]
0040FC36 |. 33D0 xor edx, eax
0040FC38 |. 81F2 C00E48AD xor edx, AD480EC0
0040FC3E |. 81FA 1A325684 cmp edx, 8456321A
0040FC44 |. 0F85 42010000 jnz 0040FD8C
0040FC4A |. 8B7E 04 mov edi, dword ptr [esi+4]
0040FC4D |. 8B16 mov edx, dword ptr [esi] ;内存访问断点断下位置
0040FC4F |. 8B4E 10 mov ecx, dword ptr [esi+10]
0040FC52 |. 8BDA mov ebx, edx
0040FC54 |. 8BEF mov ebp, edi
0040FC56 |. 81F3 C00E48AD xor ebx, AD480EC0
0040FC5C |. 81F5 C00E48AD xor ebp, AD480EC0
0040FC62 |. 35 C00E48AD xor eax, AD480EC0
0040FC67 |. 03DD add ebx, ebp
0040FC69 |. 8BE9 mov ebp, ecx
0040FC6B |. 81F5 C00E48AD xor ebp, AD480EC0
0040FC71 |. 03DD add ebx, ebp
0040FC73 |. 03D8 add ebx, eax
0040FC75 |. 8B46 08 mov eax, dword ptr [esi+8]
0040FC78 |. 35 C00E48AD xor eax, AD480EC0
0040FC7D |. 03D8 add ebx, eax
0040FC7F |. 8B46 18 mov eax, dword ptr [esi+18]
0040FC82 |. F7D0 not eax
0040FC84 |. 3BD8 cmp ebx, eax
0040FC86 |. 0F85 F9000000 jnz 0040FD85
0040FC8C |. 8B5E 24 mov ebx, dword ptr [esi+24]
0040FC8F |. 8B46 20 mov eax, dword ptr [esi+20]
0040FC92 |. 8BEB mov ebp, ebx
0040FC94 |. 35 C18EF0A8 xor eax, A8F08EC1
0040FC99 |. 81F5 C18EF0A8 xor ebp, A8F08EC1
0040FC9F |. 0FAFC5 imul eax, ebp
0040FCA2 |. 8B6E 30 mov ebp, dword ptr [esi+30]
0040FCA5 |. F7D5 not ebp
0040FCA7 |. 3BC5 cmp eax, ebp
0040FCA9 |. 0F85 D6000000 jnz 0040FD85
0040FCAF |. 8B46 14 mov eax, dword ptr [esi+14]
0040FCB2 |. 33C1 xor eax, ecx
0040FCB4 |. 35 C00E48AD xor eax, AD480EC0
0040FCB9 |. 3D 5F1E1AE6 cmp eax, E61A1E5F
0040FCBE |. 75 59 jnz short 0040FD19
0040FCC0 |. 8B4E 1C mov ecx, dword ptr [esi+1C]
0040FCC3 |. 33CA xor ecx, edx
0040FCC5 |. 81F1 C00E48AD xor ecx, AD480EC0
0040FCCB |. 81F9 AC351F59 cmp ecx, 591F35AC
0040FCD1 |. 75 46 jnz short 0040FD19
0040FCD3 |. 8B56 28 mov edx, dword ptr [esi+28]
0040FCD6 |. 33D7 xor edx, edi
0040FCD8 |. 81F2 C00E48AD xor edx, AD480EC0
0040FCDE |. 81FA C4FE8426 cmp edx, 2684FEC4
0040FCE4 |. 75 33 jnz short 0040FD19
0040FCE6 |. 8B4E 2C mov ecx, dword ptr [esi+2C]
0040FCE9 |. 33CB xor ecx, ebx
0040FCEB |. 81F1 C18EF0A8 xor ecx, A8F08EC1
0040FCF1 |. 81F9 12E6F8A4 cmp ecx, A4F8E612
0040FCF7 |. 75 20 jnz short 0040FD19
0040FCF9 |. 8B56 34 mov edx, dword ptr [esi+34]
0040FCFC |. 8B5E 20 mov ebx, dword ptr [esi+20]
0040FCFF |. 33D3 xor edx, ebx
0040FD01 |. 81F2 C18EF0A8 xor edx, A8F08EC1
0040FD07 |. 81FA E8ECA531 cmp edx, 31A5ECE8
0040FD0D |. 75 0A jnz short 0040FD19
0040FD0F |. 5F pop edi
0040FD10 |. 5E pop esi
0040FD11 |. 5D pop ebp
0040FD12 |. B8 01000000 mov eax, 1
0040FD17 |. 5B pop ebx
0040FD18 |. C3 retn
0040FD19 |> 3D 118E5FA4 cmp eax, A45F8E11
0040FD1E |. 75 65 jnz short 0040FD85
0040FD20 |. 33FF xor edi, edi
0040FD22 |. 57 push edi
0040FD23 |. E8 66830200 call 0043808E ; time(0)
0040FD28 |. 894424 18 mov dword ptr [esp+18], eax
0040FD2C |. 8D4424 18 lea eax, dword ptr [esp+18]
0040FD30 |. 50 push eax
0040FD31 |. E8 26860200 call 0043835C ; localtime
0040FD36 |. 50 push eax
0040FD37 |. 8978 08 mov dword ptr [eax+8], edi
0040FD3A |. 8978 04 mov dword ptr [eax+4], edi
0040FD3D |. 8938 mov dword ptr [eax], edi
0040FD3F |. E8 26840200 call 0043816A ; mktime
0040FD44 |. 8B4E 1C mov ecx, dword ptr [esi+1C]
0040FD47 |. 8B5E 24 mov ebx, dword ptr [esi+24]
0040FD4A |. 33CB xor ecx, ebx
0040FD4C |. 83C4 0C add esp, 0C
0040FD4F |. 81F1 C18EF0A8 xor ecx, A8F08EC1 ; ecx = arg1[7] ^ arg1[9] ^ 0xA8F08EC1;表示上次程序运行的时间
0040FD55 |. 3BC1 cmp eax, ecx ; eax此时存储的为当前时间值;运算后为与上次运行时间的差
0040FD57 |. 7C 2C jl short 0040FD85
0040FD59 |. 2BC1 sub eax, ecx ; 计算与程序上次运行时间的差(以秒为单位)
0040FD5B |. 8B7E 08 mov edi, dword ptr [esi+8]
0040FD5E |. 8BC8 mov ecx, eax
0040FD60 |. B8 07452EC2 mov eax, C22E4507
0040FD65 |. F7E9 imul ecx
0040FD67 |. 8B46 28 mov eax, dword ptr [esi+28]
0040FD6A |. 03D1 add edx, ecx
0040FD6C |. C1FA 10 sar edx, 10
0040FD6F |. 8BCA mov ecx, edx
0040FD71 |. 33C7 xor eax, edi
0040FD73 |. C1E9 1F shr ecx, 1F
0040FD76 |. 03D1 add edx, ecx ; 上面几步运算实际是 eax(时间差秒数) / 86400,
0040FD78 |. 8B4C24 1C mov ecx, dword ptr [esp+1C] ; 参数2
0040FD7C |. 35 C00E48AD xor eax, AD480EC0 ; eax = arg1[2] ^ arg1[10] ^ 0xAD480EC0; 表示的是上一次程序运行时所经历的试用天数
0040FD81 |. 03D0 add edx, eax
0040FD83 |. 8911 mov dword ptr [ecx], edx ; 把运算结果保存起来,回传给调用者
0040FD85 |> 5F pop edi
0040FD86 |. 5E pop esi
0040FD87 |. 5D pop ebp
0040FD88 |. 33C0 xor eax, eax
0040FD8A |. 5B pop ebx
0040FD8B |. C3 retn
0040FD8C |> 5F pop edi
0040FD8D |. 5E pop esi
0040FD8E |. 5D pop ebp
0040FD8F |. 8BC1 mov eax, ecx
0040FD91 |. 5B pop ebx
0040FD92 \. C3 retn
这样看来,程序不仅保存了程序每次运行的日期,还保存了最后一次运行时所流失的试用天数。并且这些信息
不是直接保存的,而是分成两部分保存的。
当然大家还可以通过追踪写注册表的操作,来完全的恢复出注册表值中各个字节的用处。这里就不赘述了。
7. 结束
总算把自己的心事了了,没有带进2010.^_^
8. 经验总结
1. 该软件注册算法使用了计算计算中间值的过程,使用了单向的算法来防止逆向。并且在
注册算法中加入干扰信息来迷惑破解者。
2. 该软件把注册算法分成3个部分。在各个不同的阶段来进行检查。
3. 该软件把相关注册信息存储在不相关的注册表中,并且把信息拆分成几个部分保存。
4. 该软件没有对提示信息进行处理,所以给破解者留下了可乘之机。
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2009年12月03日 13:41:27
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!