I am Back :) 贴个安装程序的破解 (6千字)
I am Back :) 贴个安装程序的破解最近因为一些非自然、极端的因素,上不了网,快想疯你们了 ^_^
这个软件是半个月前一朋友帮忙让看的,一别半月偶也不想啊,呵呵,今天才又重新做到爱机前,过意不去过意不去...
SoftName:上网记录生成器v1.1
这个软件在安装时要求输入安装密码,而密码只有在用户注册后才能在软件作者处得到。
我也很少动过安装程序的,but我会说的尽量详细一些
常见一点儿的安装程序是Installshield的,看雪以往的教程中都有讲,有空的话可以看一下。而偶今天遇到的这个不知道名字应该怎么叫。看初始化的时候显示的是Wise Installation,哪位老哥出来讲一下官方的名字应该是什么? :> 总知这个安装程序也很常见到的。你可以到网上把偶贴的这个软件拉下来看一下嘛 ^_^
好的,你需调试器一个,TRW2000或SoftICE。我用的是TRW2000。
运行这个名为lcinstall.exe的安装程序,在输入了一些路径信息后当程序要开始安装的时候会提示你输入安装密码。
我们先来随便输入一个,我输入的是Suunb[CCG],接下来就会提示你出错。别甚着了,请调试器出场吧,Ctrl+N呼出TRW2000,接下来下断点。我是在98下,所以用bpx hmemcpy来做断点。下完断点后再点确定马上就会被拦到,pmodule跳回领空居然跳飞了,呵呵,那再来一遍吧。再次用bpx hmemcpy做断点。这次断到后来按F12,在按了34下后会再次提示出错。那我们就重头再来一遍吧 :) (要有耐心) 这次按33下后改按F10,一下后我们会来到这里:
0167:10014318 cmp eax,byte +02 <--我们会来到这里!
0167:1001431b jz 1001434b
0167:1001431d push dword [10026854]
0167:10014323 push edi
0167:10014324 call 100121b4 <--这个CALL后会将你输入的密码装入eax指向的内存地址处
0167:10014329 push dword [10026854]
0167:1001432f call 10014350 <--这个CALL就是关键所在,伊拉克战势的结果就由它来决定了 ^_^
0167:10014334 add esp,byte +0c
0167:10014337 test eax,eax <--测试eax,而eax中的值由上面1001432f处的CALL决定
0167:10014339 jnz near 10014291 <--这个跳转很关键哦,从这里跳到10014291后你在哪儿动什么手脚意义都不大了,所以我们还是要在这里动动手脚 :)
0167:1001433f and dword [100269bc],byte -02
0167:10014346 xor eax,eax
0167:10014348 pop edi
0167:10014349 pop esi
0167:1001434a ret
上面的流程很清楚嘛,在1001432f处的CALL中程序会对所输入的密码做比较,如果正解的话eax就会被置0返回。那还等什么呢?我们进去吧 ^_^
这次可以直接用bpx 1001432f来做断点,断到后直接按F8跟进:
0167:10014350 test byte [100269bc],01
0167:10014357 push ebx
0167:10014358 push ebp
0167:10014359 push esi
0167:1001435a push edi
0167:1001435b jz 100143ce
0167:1001435d push dword [esp+14]
0167:10014361 call 10019017
0167:10014366 pop ecx
0167:10014367 mov ebx,eax
0167:10014369 mov ecx,[100268dc]
0167:1001436f cmp ebx,ecx
0167:10014371 jl near 10014424
0167:10014377 mov esi,[100266f4]
0167:1001437d cmp ebx,esi
0167:1001437f jg near 10014424
0167:10014385 mov eax,esi
0167:10014387 sub eax,ecx
0167:10014389 inc eax
0167:1001438a test byte [100269bc],02
0167:10014391 jz 10014395
0167:10014393 add eax,eax
0167:10014395 cdq
0167:10014396 idiv dword [10026710]
0167:1001439c mov edi,ecx
0167:1001439e mov ebp,eax
0167:100143a0 lea eax,[ecx+ebp]
0167:100143a3 mov [10026860],eax
0167:100143a8 cmp edi,esi
0167:100143aa jg 10014424
0167:100143ac cmp edi,ebx
0167:100143ae jz 10014420
0167:100143b0 test byte [100269bc],02
0167:100143b7 jz 100143ca
0167:100143b9 push ebp
0167:100143ba call 1001442c
0167:100143bf mov esi,[100266f4]
0167:100143c5 pop ecx
0167:100143c6 add edi,eax
0167:100143c8 jmp short 100143a8
0167:100143ca add edi,ebp
0167:100143cc jmp short 100143a8
0167:100143ce mov eax,[1002669c]
0167:100143d3 mov edi,[esp+14]
0167:100143d7 xor ebx,ebx
0167:100143d9 xor esi,esi
0167:100143db cmp [eax],bl
0167:100143dd jz 10014416
0167:100143df cmp [esi+edi],bl
0167:100143e2 jz 10014416
0167:100143e4 mov al,[eax+esi] <--上面那些意义不大,直接从这里开始说吧 ^_^ 此时eax+esi中放的便是正确的密码,不过是被处理过的“密文”,密码是一位一位来进行比较的,当前位装入al中
0167:100143e7 not al <--al做取反,什么跟什么嘛,这样就得到正确的密码了,衰!
0167:100143e9 movzx eax,al <--霸占整个eax :)
0167:100143ec push eax <--eax入栈
0167:100143ed call 10019122 <--将字符转换为大写
0167:100143f2 mov ebp,eax <--装eax装入ebp中
0167:100143f4 movsx eax,byte [esi+edi] <--esi+edi中装的是你输入的密码,得到当前参加比较的字符
0167:100143f8 push eax <--入栈
0167:100143f9 call 10019122 <--也是将其转换为大写字符
0167:100143fe pop ecx <--在ecx中也复制一份
0167:100143ff cmp ebp,eax <--比较正确的密码与你输入的密码的相应位是否相等
0167:10014401 pop ecx <--ecx还原
0167:10014402 jnz 10014411 <--不相等就跳到10014411处
0167:10014404 mov eax,[1002669c] <--正确密码的地址再次装入eax中
0167:10014409 inc esi <--esi加1,用来比较下一个字符
0167:1001440a cmp [eax+esi],bl <--eax+esi是否为0,也就是看密码是否比较完毕
0167:1001440d jnz 100143df <--没比较完就跳到上边儿接着比较下一位
0167:1001440f jmp short 10014416 <--完了跳到10014416处
0167:10014411 mov eax,[1002669c]
0167:10014416 cmp [eax+esi],bl <--是否等于bl中的值?
0167:10014419 jnz 10014424 <--不是就跳
0167:1001441b cmp [esi+edi],bl <--是否等于bl中的值?
0167:1001441e jnz 10014424 <--不是就跳
0167:10014420 xor eax,eax <--呜呜呜…能来到这里感觉真好
0167:10014422 jmp short 10014427 <--直接跳到10014427处,eax此时为0
0167:10014424 push byte +01
0167:10014426 pop eax
0167:10014427 pop edi
0167:10014428 pop esi
0167:10014429 pop ebp
0167:1001442a pop ebx
0167:1001442b ret
明白过来了吗?程序通过对你输入的密码与正确的密码进行一位一位的比较,来确定你输入的密码是否正确。而这个正确的密码并不是使用的明文,而是被处理过后的密文。说实话这密文也真够逊的… ^_^ 程序通过对密文进行取反操作来得到正确的密码,之后再将其转换为大写字符。而你输入的密码也会被转换为大写后与其比较,如果相等就接着比较下一位,直到所有的字符都被比较过了…
呵呵,不难吧,你可以自己写个小程序来对密文进行取反后再转换为字符串,不过我觉的没有那个必要了。呵呵,我们可以100143f2处的时候记下程序自己计算出来并转换为大写了的字符的ASCII码,然后到了10014402处用r fl z指令来阻止程序跳走,接着程序便会计算正确密码的下一位的值,同样到了100143f2处的时候把它的ASCII码记下,然后就一直这样,直到正确密码的所有字符都计算出来为止,当然前提条件是你也得输入一个长度有够长的密码,所以我把把Suunb[CCG]换为aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa了,呵呵,只要长度够了就行了,程序根本就不管具体的位数,它只管正确密码的各位都已经比较过没有 :)
用了N个r fl z指令后得到的正确密码的ASCII码分别是:
42 38 44 32 59 36 54 39 48 54 54 50 3A 2F 2F 57 57 57 2E 57 45 4E 58 49 4E 2E 4E 45 54
转换为相应的字符就是:B8D2Y6T9HTTP://WWW.WENXIN.NET
the end.
