• 标 题:I am Back :) 贴个安装程序的破解 (6千字)
  • 作 者:商朝子
  • 时 间:2003-4-6 14:22:56
  • 链 接:http://bbs.pediy.com

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.

  • 标 题:更简单的方法,用hwun反编译,立即得到程序。
  • 作 者:小楼
  • 时 间:2003-4-6 15:04:55
  • 链 接:http://bbs.pediy.com

http://66.36.228.12/protools/files/decompilers/hwun.zip