一个拨号软件的Win32Dasm暴力破解法

日期:2003年9月23日 作者:ddcrack 人气: 34

这里演示的是一个叫“中国用户专用拨号软件”的程序的暴力破解法,这个拨号软件在拨号上网后会打开IE窗口并将默认网址改为:http://www.chinauser.com,这根本就是违背用户的自由强迫用户访问那个网址,实在是对用户权力的一种侵害。

程序名 :中国用户专用拨号软件
版本   :无
大小   :99KB
运行平台:Windows 98/Me/NT/2000
保护方式:无
破解方式:暴力破解
破解难度:中等

破解步骤

  1. 破解方法:对付这种情况通常我们会有两种方法——一种是跳过相应的程序段,另外一种就是屏蔽掉原来的相应程序段。具体对于这个程序,因为拨号跟时间很有关系,所以我们不太方便使用SOFTICE的动态调试工具去跟踪它,而可以借助静态反编译工具Win32Dasm来分析它。按照通常的思维我们破解时首先会选择第1种方法,即认为程序中肯定有某个地方进行判断然后可以绕过弹出IE窗口的子程序,但是事实证明第2种方法比较适合于这个程序。本文的主要目的是讲述暴力破解和Win32Dasm的使用方法,所以为了能更深入的讲解破解方法,我按照通常的思维模式来讲解,即先用第1总种方法,然后自然而然的导出使用第2种方法的必要,以此来提高大家的破解经验;

  2. 首先,用Win32Dasm中“Disassemmbler”菜单下的“Open File to Disassembler...”打开userdial.exe;

  3. 选择“Refs”下的“String Data Reference”查看程序中的字符串信息;

  4. 仔细浏览你将会发现有“Program Files\Internet Explorer\IEXPLORE.EXE”及“http://www.chinauser.com”的字符串,显然程序会用这两串字符来调用IE并打开“http://www.chinauser.com”的网址,从而打开可恶的广告窗;;

  5. 双击字符串“Program Files\Internet Explorer\IEXPLORE.EXE”来到程序中调用它的地方:

* Possible StringData Ref from Data Obj ->"Program Files\Internet Explorer\IEXPLORE.EXE"
                                  |
:0041C78E 68047B4300              push 00437B04                <-- 我们来到这里
:0041C793 8D542410                lea edx, dword ptr [esp+10]
:0041C797 8D442418                lea eax, dword ptr [esp+18]
:0041C79B 52                      push edx
:0041C79C 50                      push eax

* Reference To: MFC42.Ordinal:039C, Ord:039Ch
                                  |
:0041C79D E80C040000              Call 0041CBAE

从程序可以看出push 00437B04这条指令的作用是将IE程序的路径压栈,那么后面的Call 0041CBAE自然就是打开IE窗口的子程序了;

  1. 让我们往上搜索,看看有没有跳转指令可以跳过这里,中间你还可以看到调用字符串“http://www.chinauser.com”的地方:
* Possible StringData Ref from Data Obj ->"http://www.chinauser.com/"
                                  |
:0041C683 BE787B4300              mov esi, 00437B78
:0041C688 8D7C2418                lea edi, dword ptr [esp+18]
:0041C68C F3                      repz
:0041C68D A5                      movsd
:0041C68E 66A5                    movsw
:0041C690 B93A000000              mov ecx, 0000003A
:0041C695 33C0                    xor eax, eax
:0041C697 8D7C2432                lea edi, dword ptr [esp+32]

指令mov esi, 00437B78将字符串“http://www.chinauser.com”的地址压栈,说明这里以下的程序段都是在为打开IE做准备,继续往上看,就在上面我们可以看到:

* Referenced by a CALL at Address:
|:0041B74A
|
:0041C660 6AFF                    push FFFFFFFF
:0041C662 6871D74100              push 0041D771
:0041C667 64A100000000            mov eax, dword ptr fs:[00000000]
:0041C66D 50                      push eax
:0041C66E 64892500000000          mov dword ptr fs:[00000000], esp
:0041C675 81EC10030000            sub esp, 00000310
:0041C67B 55                      push ebp
:0041C67C 56                      push esi
:0041C67D 57                      push edi
:0041C67E B906000000              mov ecx, 00000006

从这里我们可以知道始终没有跳转指令可以跳过这段程序,只是发现这段打开IE窗口的程序被0041B74A处的CALL所调用;

  1. 按SHIFT+F12组合键,输入地址0041B74A,我们跳到那里的程序去看看:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B674(C)
|
:0041B70F F6C720                  test bh, 20
:0041B712 7442                    je 0041B756
:0041B714 8B4620                  mov eax, dword ptr [esi+20]

* Reference To: USER32.KillTimer, Ord:0195h
                                  |
:0041B717 8B3DA4E34100            mov edi, dword ptr [0041E3A4]
:0041B71D 6A4A                    push 0000004A
:0041B71F 50                      push eax
:0041B720 FFD7                    call edi
:0041B722 8B4E20                  mov ecx, dword ptr [esi+20]

* Possible Reference to String Resource ID=00103: "Windows .犸??1%."
                                  |
:0041B725 6A67                    push 00000067
:0041B727 51                      push ecx
:0041B728 FFD7                    call edi
:0041B72A 51                      push ecx
:0041B72B 8D566C                  lea edx, dword ptr [esi+6C]
:0041B72E 8BCC                    mov ecx, esp
:0041B730 89642424                mov dword ptr [esp+24], esp
:0041B734 52                      push edx
:0041B735 C7466801000000          mov [esi+68], 00000001

* Reference To: MFC42.Ordinal:0217, Ord:0217h
                                  |
:0041B73C E8E9130000              Call 0041CB2A
:0041B741 8BCE                    mov ecx, esi
:0041B743 E868FCFFFF              call 0041B3B0
:0041B748 8BCE                    mov ecx, esi
:0041B74A E8110F0000              call 0041C660                <-- 我们来到这里
:0041B74F 8BCE                    mov ecx, esi
:0041B751 E82A000000              call 0041B780

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041B6DB(U), :0041B70D(U), :0041B712(C)
|
:0041B756 8D4C240C                lea ecx, dword ptr [esp+0C]
:0041B75A C7442418FFFFFFFF        mov [esp+18], FFFFFFFF
  1. 现在已经知道0041B74A处的CALL 0041C660跟打开IE窗口有很大关系,让我们从这里往上看,可以发现上面0041B712处的je 0041B756指令可以跳过CALL 0041C660

  2. 为了验证这里是否是破解的关键点,我们首先将程序userdial.exe备份一下,以免将源程序改了之后又未能达到目的,可以重来嘛^_^。接下来我们要将指令je 0041B756改为 jne 0041B756,即改变程序原本的运行方向,使其跳过打开IE的程序段。那么怎样改程序代码呢?首先我们看看0041B712处的je 0041B756其机器码是7442,我们要用HIEW打开userdial.exe并找到 je 0041B756这条指令,然后将其改为jne 0041B756(对应的机器码为7542,因为je的指令码为74,而jne的指令码为75)。因为程序中程序中很可能会有很多地方其机器码是7442,为了能准确的找到这里,我们将这条指令前后的机器码一起F6 C7 20 74 42 8B 46 20 作为搜索对象,将HIEW的显示模式设为“Decode”,然后按F7输入F6 C7 20 74 42 8B 46 20 ,找到之后按F3将74改为75,按F9存盘退出(其实也可以用TAB键直接用汇编语句将je 0041B756改为jne 0041B756,但是很多时候你会发现用汇编语句并不能达到预期的目的,很可能会使相应的机器码长度前后不一样,尽管汇编指令看起来是一样的)。注意:修改源程序代码时要保证被修改的指令机器码其长度前后一致,否则会影响被修改指令以后的程序,例如je 0041B756的机器码是7442,为两个字节,修改为jne 0041B756之后其机器码为7542,也是两个字节,千万不能出现被修改指令修改前后的字节程度不一样,这样的话程序肯定会死掉的;

  3. 修改完程序之后运行它试试,你会发现当一开始拨号(还没有连接上网)时程序就开始打开IE,默认网址为“http://www.chinauser.com”,更有趣的是连续打开了3个同样的IE窗口,哎!失败了!改动的地方不对!重来!

  4. 现在知道0041B712处的je 0041B756并不是破解的关键点,往上看,我们可以发现这里的程序段被0041B674处的跳转指令调用(你也许不明白为什么我知道这里的程序被跳转指令所调用?因为Win32Dasm中的“* Referenced by a (U)nconditional or (C)onditional Jump at Address:”信息指示出了程序的来龙去脉^_^);

  5. 按SHIFT+F12组合键,输入地址0041B674,跳过去看看:

* Reference To: MFC42.Ordinal:1741, Ord:1741h
                                  |
:0041B669 E892140000              Call 0041CB00
:0041B66E 8B442424                mov eax, dword ptr [esp+24]
:0041B672 85C0                    test eax, eax
:0041B674 0F8495000000            je 0041B70F                <-- 我们来到这里
:0041B67A 8B860C010000            mov eax, dword ptr [esi+0000010C]
:0041B680 85C0                    test eax, eax
:0041B682 7406                    je 0041B68A
:0041B684 50                      push eax

可以看出指令je 0041B70F将会使程序跳到打开IE的程序段,现在我们要使程序不跳到0041B70F去,一种办法是将je改成jne,另外一种办法是将je 0041B70F改成空指令nop。这里我们采用第2中方法,由于je 0041B70F的机器码是0F8495000000,所以我们用nop的机器码90添满0F8495000000,在HIEW中搜索85 C0 0F 84 95 00 00 00 8B 86(注意将刚才改坏的userdial.exe删掉,用原始的userdial.exe来修改^_^),然后将0F 84 95 00 00 00改成90 90 90 90 90 90,存盘退出后运行userdial.exe,你会发现按“连接”后程序没有打开IE窗口,哈。。。有戏唱了!不过虽然可恶的IE窗口没有打开,但是程序却不工作了,有问题???

  1. 再看看上面的程序,发现je 0041B70F的下面紧接着有另外一个跳转指令je 0041B68A,是不是它在作怪呢?试一下就知道了:将je 0041B68A改成jne 0041B68A(方法不用具体再叙述了吧^_^);

  2. 修改完之后重新启动userdial.exe,按“连接”键,哈哈。。。程序开始拨号,而且没有再打开IE窗口。可是拨号上网以后你会发现有点不对劲,程序界面不会自动最小化并进入后台运行,而且“连接状态”显示“不能接通, 已经断开.”的信息,虽然去掉了可恶的IE窗口,但是却使程序的运行出现了一些问题,尽管这些问题并不影响程序的正常使用;

  3. 选择“Refs”下的“String Data Reference”,找到字符串“不能接通, 已经断开.”并双击来到调用它的地方:

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041B69C(C), :0041B6B5(C)
|
:0041B6DD 8B5620                  mov edx, dword ptr [esi+20]

* Possible Reference to String Resource ID=00103: "Windows .犸??1%."
                                  |
:0041B6E0 6A67                    push 00000067
:0041B6E2 52                      push edx

* Reference To: USER32.KillTimer, Ord:0195h
                                  |
:0041B6E3 FF15A4E34100            Call dword ptr [0041E3A4]
:0041B6E9 6A01                    push 00000001
:0041B6EB 8BCE                    mov ecx, esi
:0041B6ED E8DED6FFFF              call 00418DD0

* Possible StringData Ref from Data Obj ->"不能接通, 已经断开." (注意:在Win32Dasm中你看到的将是一堆乱码,不过并不影响我们)
                                  |
:0041B6F2 68347A4300              push 00437A34                <-- 我们来到这里
:0041B6F7 68F4030000              push 000003F4
:0041B6FC 8BCE                    mov ecx, esi

* Reference To: MFC42.Ordinal:1741, Ord:1741h
                                  |
:0041B6FE E8FD130000              Call 0041CB00
:0041B703 C7861801000000000000    mov dword ptr [esi+00000118], 00000000
:0041B70D EB47                    jmp 0041B756

在将字符串“不能接通, 已经断开.”的地址压栈指令 push 00437A34的上面我们可以看到这段程被两个相互很近的地方0041B69C和0041B6B5所调用;

  1. 按SHIFT+F12组合键,输入地址0041B69C,跳过去看看:
* Reference To: MFC42.Ordinal:1741, Ord:1741h
                                  |
:0041B669 E892140000              Call 0041CB00
:0041B66E 8B442424                mov eax, dword ptr [esp+24]
:0041B672 85C0                    test eax, eax
:0041B674 0F8495000000            je 0041B70F
:0041B67A 8B860C010000            mov eax, dword ptr [esi+0000010C]
:0041B680 85C0                    test eax, eax
:0041B682 7406                    je 0041B68A
:0041B684 50                      push eax

* Reference To: RASAPI32.RasHangUpA, Ord:0039h
                                  |
:0041B685 E816180000              Call 0041CEA0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B682(C)
|
:0041B68A 8B8614010000            mov eax, dword ptr [esi+00000114]
:0041B690 C7860C01000000000000    mov dword ptr [esi+0000010C], 00000000
:0041B69A 85C0                    test eax, eax
:0041B69C 753F                    jne 0041B6DD                <-- 我们来到这里
:0041B69E 8B9618010000            mov edx, dword ptr [esi+00000118]
:0041B6A4 8B8E04010000            mov ecx, dword ptr [esi+00000104]
:0041B6AA 42                      inc edx
:0041B6AB 8BC2                    mov eax, edx
:0041B6AD 899618010000            mov dword ptr [esi+00000118], edx
:0041B6B3 3BC1                    cmp eax, ecx
:0041B6B5 7D26                    jge 0041B6DD

哦!原来调用字符串“不能接通, 已经断开.”的地方就在刚才修改的程序的下面,0041B69C处的jne 0041B6DD0041B6B5处的jge 0041B6DD都会让程序去调用显示字符串“不能接通, 已经断开.”。那么我们就不让程序去显示这个字符串:将jne 0041B6DD(对应的机器码753F)用空指令nop填充(对应的机器码为9090),将jge 0041B6DD(对应的机器码7D26)用空指令nop填充(对应的机器码为9090),然后存盘退出(要在刚才修改过的程序的基础上改噢);

  1. 再一次重新启动userdial.exe,你会发现除了“连接状态”信息由“不能接通, 已经断开.”变为“准备重拨”之外,程序依然如故。现在我们应该想一想:在0041B674处我们将je 0041B70F用空指令nop填充后虽然跳过了打开IE窗口的程序段,而且程序也能成功拨号使用,但是却出现了一些不正常的状态(不能最小化进入后台运行,“连接状态”信息不对)。那么我们能不能让程序je 0041B70F有效走到0041B70F去而又不使其弹出IE窗口呢?

  2. 在第7步骤时我们已经知道call 0041C660这条指令是直接打开IE的地方(但也不是百分之百的正确,至少这个CALL是主要的部分吧):

* Reference To: MFC42.Ordinal:0217, Ord:0217h
                                  |
:0041B73C E8E9130000              Call 0041CB2A
:0041B741 8BCE                    mov ecx, esi
:0041B743 E868FCFFFF              call 0041B3B0
:0041B748 8BCE                    mov ecx, esi
:0041B74A E8110F0000              call 0041C660                <-- 这个CALL打开IE窗口
:0041B74F 8BCE                    mov ecx, esi
:0041B751 E82A000000              call 0041B780

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041B6DB(U), :0041B70D(U), :0041B712(C)
|
:0041B756 8D4C240C                lea ecx, dword ptr [esp+0C]
:0041B75A C7442418FFFFFFFF        mov [esp+18], FFFFFFFF

现在我们试试用空指令nopcall 0041C660屏蔽掉,看看程序是否既能不弹出IE窗口又能正常工作(注意:使用原始的userdial.exe喔^_^,刚才修改的程序证明不太成功啦:-(,将call 0041C660的机器码E8110F0000改成9090909090);

  1. 修改完后打开userdial.exe,选择“连接”后等待运行结果——哈哈。。。成功了,没有了可恶的IE弹出窗口,程序运行和原始程序完全一样^^!(破解就是这样,经常会走一些弯路才会发现正确的方向^^,这就要求我们要开拓思路,不能一条道走到底,不知去另寻它路,这样会极大的限制自己的视野。)

  2. 有一点要提醒大家:在用Win32Dasm观察分析程序时始终要用原始程序,不要打开修改过的程序进行分析。你可以在打开原始程序后选择“Disassember”下的“Save Disassembler Text File and Create Project File”将反汇编结果存盘,以后再次启动Win32Dasm时可以直接选择“Project”下的“Open Project File...”来打开原先保存的反汇编结果。

Contributors: FHL