UltraEdit 16.10.0.1028,是一款集成了多种功能的文件二进制查看编辑工具。
官方发布30天免费使用版,如果要正式版需要$60。闲来无事,拿来破解了一下。
系统:Windows 7
工具:OllyDBG1.10 汉化第二版
1、因为看此软件主程序有.tls段,为了确定在main()入口之前,是否通过tls回调函数执行了反破解保护,修改一下OD的系统设置“选项->调试设置->事件->第一次中断于->系统断点”,然后加载该软件。待停住后,在Uedit32.exe模块的.text段设置访问断点,然后F9运行。
2、在 00ACB92B > $ E8 8E040200 CALL Uedit32.00AEBDBE 此处停了下来。发现这就是函数的入口点了。说明此时并没有执行反破解保护。程序的入口大致是这样的:
代码:
00AEBDF4 |. 50 PUSH EAX ; /pFileTime 00AEBDF5 |. FF15 A8A4CF00 CALL DWORD PTR DS:[<&KERNEL32.GetSystemT>; \GetSystemTimeAsFileTime 取得系统日期和时间 00AEBDFB |. 8B75 FC MOV ESI,DWORD PTR SS:[EBP-4] 00AEBDFE |. 3375 F8 XOR ESI,DWORD PTR SS:[EBP-8] 00AEBE01 |. FF15 9CA6CF00 CALL DWORD PTR DS:[<&KERNEL32.GetCurrent>; [GetCurrentProcessId 00AEBE07 |. 33F0 XOR ESI,EAX 00AEBE09 |. FF15 D0A6CF00 CALL DWORD PTR DS:[<&KERNEL32.GetCurrent>; [GetCurrentThreadId 00AEBE0F |. 33F0 XOR ESI,EAX 00AEBE11 |. FF15 DCA6CF00 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou>; [GetTickCount 取得CPU运行时间, 00AEBE17 |. 33F0 XOR ESI,EAX 00AEBE19 |. 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] 00AEBE1C |. 50 PUSH EAX ; /pPerformanceCount 00AEBE1D |. FF15 18A4CF00 CALL DWORD PTR DS:[<&KERNEL32.QueryPerfo>; \QueryPerformanceCounter 取得精确系统时间 00AEBE23 |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C] 00AEBE26 |. 3345 F0 XOR EAX,DWORD PTR SS:[EBP-10] 00AEBE29 |. 33F0 XOR ESI,EAX ; 将上面取得的值都异或在一起,作为一个唯一标志值 00AEBE2B |. 3BF7 CMP ESI,EDI 00AEBE2D |. 75 07 JNZ SHORT Uedit32.00AEBE36 00AEBE2F |. BE 4FE640BB MOV ESI,BB40E64F 00AEBE34 |. EB 0B JMP SHORT Uedit32.00AEBE41 00AEBE36 |> 85F3 TEST EBX,ESI 00AEBE38 |. 75 07 JNZ SHORT Uedit32.00AEBE41 00AEBE3A |. 8BC6 MOV EAX,ESI 00AEBE3C |. C1E0 10 SHL EAX,10 00AEBE3F |. 0BF0 OR ESI,EAX 00AEBE41 |> 8935 B45C0101 MOV DWORD PTR DS:[1015CB4],ESI ; 将这串标志值写到[1015CB4],用于后面的频繁比较 00AEBE47 |. F7D6 NOT ESI 00AEBE49 |. 8935 B85C0101 MOV DWORD PTR DS:[1015CB8],ESI 00AEBE4F |. 5E POP ESI 00AEBE50 |> 5F POP EDI 00AEBE51 |. 5B POP EBX 00AEBE52 |. C9 LEAVE 00AEBE53 \. C3 RETN
3、对[1015CB4]设置内存访问断点,发现在后面的执行中,频繁的执行比较:
代码:
00ABA020 $ 3B0D B45C0101 CMP ECX,DWORD PTR DS:[1015CB4] ; 比较标志,防止破解.如果不相等就跳转到AD599C 00ABA026 . 75 02 JNZ SHORT Uedit32.00ABA02A 00ABA028 . F3: PREFIX REP: ; 多余的前缀 00ABA029 . C3 RETN 00ABA02A > E9 6DB90100 JMP Uedit32.00AD599C
代码:
00AD599C > \8BFF MOV EDI,EDI 00AD599E /. 55 PUSH EBP 00AD599F |. 8BEC MOV EBP,ESP 00AD59A1 |. 81EC 28030000 SUB ESP,328 00AD59A7 |. A3 C0B40701 MOV DWORD PTR DS:[107B4C0],EAX 00AD59AC |. 890D BCB40701 MOV DWORD PTR DS:[107B4BC],ECX 00AD59B2 |. 8915 B8B40701 MOV DWORD PTR DS:[107B4B8],EDX 00AD59B8 |. 891D B4B40701 MOV DWORD PTR DS:[107B4B4],EBX 00AD59BE |. 8935 B0B40701 MOV DWORD PTR DS:[107B4B0],ESI 00AD59C4 |. 893D ACB40701 MOV DWORD PTR DS:[107B4AC],EDI 00AD59CA |. 66:8C15 D8B40>MOV WORD PTR DS:[107B4D8],SS 00AD59D1 |. 66:8C0D CCB40>MOV WORD PTR DS:[107B4CC],CS 00AD59D8 |. 66:8C1D A8B40>MOV WORD PTR DS:[107B4A8],DS 00AD59DF |. 66:8C05 A4B40>MOV WORD PTR DS:[107B4A4],ES 00AD59E6 |. 66:8C25 A0B40>MOV WORD PTR DS:[107B4A0],FS 00AD59ED |. 66:8C2D 9CB40>MOV WORD PTR DS:[107B49C],GS 00AD59F4 |. 9C PUSHFD 00AD59F5 |. 8F05 D0B40701 POP DWORD PTR DS:[107B4D0] 00AD59FB |. 8B45 00 MOV EAX,DWORD PTR SS:[EBP] 00AD59FE |. A3 C4B40701 MOV DWORD PTR DS:[107B4C4],EAX 00AD5A03 |. 8B45 04 MOV EAX,DWORD PTR SS:[EBP+4] 00AD5A06 |. A3 C8B40701 MOV DWORD PTR DS:[107B4C8],EAX 00AD5A0B |. 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8] 00AD5A0E |. A3 D4B40701 MOV DWORD PTR DS:[107B4D4],EAX 00AD5A13 |. 8B85 E0FCFFFF MOV EAX,DWORD PTR SS:[EBP-320] 00AD5A19 |. C705 10B40701>MOV DWORD PTR DS:[107B410],10001 00AD5A23 |. A1 C8B40701 MOV EAX,DWORD PTR DS:[107B4C8] 00AD5A28 |. A3 C4B30701 MOV DWORD PTR DS:[107B3C4],EAX 00AD5A2D |. C705 B8B30701>MOV DWORD PTR DS:[107B3B8],C0000409 00AD5A37 |. C705 BCB30701>MOV DWORD PTR DS:[107B3BC],1 00AD5A41 |. A1 B45C0101 MOV EAX,DWORD PTR DS:[1015CB4] 00AD5A46 |. 8985 D8FCFFFF MOV DWORD PTR SS:[EBP-328],EAX 00AD5A4C |. A1 B85C0101 MOV EAX,DWORD PTR DS:[1015CB8] 00AD5A51 |. 8985 DCFCFFFF MOV DWORD PTR SS:[EBP-324],EAX 00AD5A57 |. FF15 00A5CF00 CALL DWORD PTR DS:[<&KERNEL32.IsDebugger>; [判断当前是否处在Debugger模式 00AD5A5D |. A3 08B40701 MOV DWORD PTR DS:[107B408],EAX 00AD5A62 |. 6A 01 PUSH 1 00AD5A64 |. E8 CFF7FFFF CALL Uedit32.00AD5238 00AD5A69 |. 59 POP ECX 00AD5A6A |. 6A 00 PUSH 0 ; /pTopLevelFilter = NULL 00AD5A6C |. FF15 BCA7CF00 CALL DWORD PTR DS:[<&KERNEL32.SetUnhandl>; \SetUnhandledExceptionFilter 设置异常处理 00AD5A72 |. 68 90B1DD00 PUSH Uedit32.00DDB190 ; /pExceptionInfo = Uedit32.00DDB190 00AD5A77 |. FF15 E0A4CF00 CALL DWORD PTR DS:[<&KERNEL32.UnhandledE>; \UnhandledExceptionFilter 00AD5A7D |. 833D 08B40701>CMP DWORD PTR DS:[107B408],0 00AD5A84 |. 75 08 JNZ SHORT Uedit32.00AD5A8E 00AD5A86 |. 6A 01 PUSH 1 00AD5A88 |. E8 ABF7FFFF CALL Uedit32.00AD5238 00AD5A8D |. 59 POP ECX 00AD5A8E |> 68 090400C0 PUSH C0000409 ; /ExitCode = C0000409 (-1073740791.) 00AD5A93 |. FF15 C8A7CF00 CALL DWORD PTR DS:[<&KERNEL32.GetCurrent>; |[GetCurrentProcess 00AD5A99 |. 50 PUSH EAX ; |hProcess 00AD5A9A |. FF15 A4A4CF00 CALL DWORD PTR DS:[<&KERNEL32.TerminateP>; \TerninateProces 结束进程 00AD5AA0 |. C9 LEAVE 00AD5AA1 \. C3 RETN
将00ABA026 . 75 02 JNZ SHORT Uedit32.00ABA02A这个地方的代码改成两个nop,也就废了它的“时间点”保护。
4、废掉它的时间点一致性保护后,继续运行,却发现程序执行异常。经过研究问题出在这里
代码:
004D31B3 . 6A 00 PUSH 0 ; /Title = NULL 004D31B5 . 68 28A3D000 PUSH Uedit32.00D0A328 ; |Class = "UEDIT32" 004D31BA . FFD7 CALL EDI ; \FindWindowA 004D31BC . 8985 C8B3FFFF MOV DWORD PTR SS:[EBP+FFFFB3C8],EAX 004D31C2 . 8B83 20040000 MOV EAX,DWORD PTR DS:[EBX+420] 004D31C8 . 85C0 TEST EAX,EAX 004D31CA . 74 5B JE SHORT Uedit32.004D3227
5、加载的方式程序执行过不去,再看看附加的方式。我把文件中的代码改了一下,意图破坏它的时间校验,执行起来却发生出错。说明它还有“程序代码完整性校验”。没办法,只有等运行起来后再改了。注意,OllyDBG附加上后,立即让其处于运行状态,再去改时间校验代码。否则,因为改代码而暂停程序,会让其所有线程进入等待“死锁”而被挂起。
6、这回一些防破解保护应该都去掉了吧!点处Uedit32的注册码输入窗口试试看吧!怀着一颗紧张而低调的心情,将本模块中所有调用“GetWindowstextA”的函数都设上了断点。然而,郁闷的事情发生了

代码:
75D51949 > 8BFF MOV EDI,EDI 75D5194B CC INT3 75D5194C C3 RETN
7、查看堆栈,根据返回地址,找到了这段代码:
代码:
00CCB510 55 PUSH EBP 00CCB511 8BEC MOV EBP,ESP 00CCB513 6A FE PUSH -2 00CCB515 68 C083EB00 PUSH Uedit32.00EB83C0 00CCB51A 68 F0BFAB00 PUSH Uedit32.00ABBFF0 00CCB51F 64:A1 00000000 MOV EAX,DWORD PTR FS:[0] 00CCB525 50 PUSH EAX 00CCB526 83C4 F0 ADD ESP,-10 00CCB529 53 PUSH EBX 00CCB52A 56 PUSH ESI 00CCB52B 57 PUSH EDI 00CCB52C A1 B45C0101 MOV EAX,DWORD PTR DS:[1015CB4] 00CCB531 3145 F8 XOR DWORD PTR SS:[EBP-8],EAX 00CCB534 33C5 XOR EAX,EBP 00CCB536 50 PUSH EAX 00CCB537 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] 00CCB53A 64:A3 00000000 MOV DWORD PTR FS:[0],EAX 00CCB540 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP 00CCB543 C745 E4 0100000>MOV DWORD PTR SS:[EBP-1C],1 00CCB54A C745 FC 0000000>MOV DWORD PTR SS:[EBP-4],0 00CCB551 FF15 D4A4CF00 CALL DWORD PTR DS:[<&KERNEL32.DebugBreak>; kernel32.DebugBreak
[CODE]
看来一旦用户有所操作,它就要调用此函数,从而导致错误。
好好复杂呀!不知道把这个函数搞掉后,会是怎样?根据它这情况,它肯定还有别的保护点。
我投降了

===========================================
好家伙,这用了多少反调试的手段呀!虽然没有成功,但是通过破解它,倒是让人学习了很多知识。也让我第一次在逆向跟踪里碰了个钉子。或许碰见狠角色了,心有未甘,我怀着虐人的心理,加载了我机器上试用版的WinRAR.exe,结果我大吃一惊

看来,这反调试功能是一个公司的产品,两款软件都采用了这一种反调试模块了。
这要是搞掉它,就搞掉一大片啊!
到网上一搜,这个版本的UEDIT32和WinRAR都有破解版的了。真是人外有人啊!由衷感叹。路漫漫其修远兮,吾将上下而求索。
诸位兄弟有没有对此保护方式有什么认识的,请不吝赐教几句,让吾辈有醍醐灌顶之感,岂不美哉?