SKYPE中的 anti-debug 分析
软件名称: skype
实例下载: http://www.skype.com/download
作 者: blackeyes
声 明: skype 是 freeware, 没有什么要 PJ的, 只是分析它的anti-debug 1. 基本信息
入口点(OEP): 005E7A28
引入表(I T): 00B8F000-00B8F21B ( size: 021C )
引入地址表(IAT): 00B8F21C-00B8FD38 ( size: 0B1C )
PeID结果: Borland Delphi 6.0 - 7.0 [Overlay]
2. 调试器检测, CODE 解码, 解析第二份IAT
// OD 载入后停在这里 005E7A28
005E7A28 > $ /EB 57 JMP SHORT Skype.005E7A81
005E7A81 > \E8 26010000 CALL Skype.005E7BAC ; // detect softice (第 1 处)
005E7A86 . 84C0 TEST AL,AL
005E7A88 . 74 1C JE SHORT Skype.005E7AA6
005E7A8A . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
005E7A8C . FF35 482FB800 PUSH DWORD PTR DS:[B82F48] ; |Title = "Skype"
005E7A92 . FF35 4C2FB800 PUSH DWORD PTR DS:[B82F4C] ; |Text = "Error: Skype is not compatible with debuggers like SoftICE .."
005E7A98 . 6A 00 PUSH 0 ; |hOwner = NULL
005E7A9A . E8 9910E2FF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
005E7A9F . 6A 01 PUSH 1 ; /ExitCode = 1
005E7AA1 . E8 5A04E2FF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
005E7AA6 > BA 011E1600 MOV EDX,161E01
005E7AAB . 81C2 A38BA100 ADD EDX,Skype.00A18BA3 ; // EDX = 00B7A9A4
005E7AB1 . 52 PUSH EDX
005E7AB2 . EB 10 JMP SHORT Skype.005E7AC4
005E7AB4 . BF 287A5E00 MOV EDI,Skype.<ModuleEntryPoint>
005E7AB9 . B9 C47A5E00 MOV ECX,Skype.005E7AC4
005E7ABE . 29F9 SUB ECX,EDI
005E7AC0 . 31C0 XOR EAX,EAX
005E7AC2 . F3:AA REP STOS BYTE PTR ES:[EDI]
005E7AC4 > E8 CF3F0100 CALL Skype.005FBA98
005E7AC9 . E8 AAFEFFFF CALL Skype.005E7978
005E7ACE . C3 RETN ; // return 00B7A9A4
00B7A9A4 . 55 PUSH EBP ; 感觉这儿才是程序入口点
00B7A9A5 . 8BEC MOV EBP,ESP
00B7A9A7 . B9 20000000 MOV ECX,20
00B7A9AC > 6A 00 PUSH 0
00B7A9AE . 6A 00 PUSH 0
00B7A9B0 . 49 DEC ECX
00B7A9B1 .^ 75 F9 JNZ SHORT Skype.00B7A9AC
00B7A9B3 . 53 PUSH EBX
00B7A9B4 . 56 PUSH ESI
00B7A9B5 . 57 PUSH EDI
00B7A9B6 . B8 749FB700 MOV EAX,Skype.00B79F74
00B7A9BB . E8 6CD088FF CALL Skype.00407A2C ; // *** Init CALL ****
00B7A9C0 . BF 78E6B800 MOV EDI,Skype.00B8E678
00B7A9C5 . 33C0 XOR EAX,EAX
00B7A9C7 . 55 PUSH EBP
00B7A9C8 . 68 1BBAB700 PUSH Skype.00B7BA1B
00B7A9CD . 64:FF30 PUSH DWORD PTR FS:[EAX]
00B7A9D0 . 64:8920 MOV DWORD PTR FS:[EAX],ESP
00B7A9D3 . A1 90B2B800 MOV EAX,DWORD PTR DS:[B8B290]
00B7A9D8 . C600 01 MOV BYTE PTR DS:[EAX],1
00B7A9DB . 6A 00 PUSH 0
00B7A9DD . E8 661D8AFF CALL <JMP.&ole32.OleInitialize>
00B7A9E2 . E8 3DB6A6FF CALL Skype.005E6024 ; // detect debug (第 2 处)
00B7A9E7 . 84C0 TEST AL,AL
00B7A9E9 . 74 1A JE SHORT Skype.00B7AA05
00B7A9EB . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00B7A9ED . 68 30BAB700 PUSH Skype.00B7BA30 ; |Title = "Skype"
00B7A9F2 . 68 38BAB700 PUSH Skype.00B7BA38 ; |Text = "Skype is not compatible with system debuggers like SoftICE."
00B7A9F7 . 6A 00 PUSH 0 ; |hOwner = NULL
00B7A9F9 . E8 32E188FF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
00B7A9FE . 6A 00 PUSH 0 ; /ExitCode = 0
00B7AA00 . E8 FBD488FF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
00B7AA05 > B9 7CBAB700 MOV ECX,Skype.00B7BA7C ; ASCII "Starting .."
00B7AA0A . BA 94BAB700 MOV EDX,Skype.00B7BA94 ; ASCII "Skype.main" // Init call
00407A2C /$ 53 PUSH EBX
00407A2D |. 8BD8 MOV EBX,EAX
00407A2F |. 33C0 XOR EAX,EAX
00407A31 |. A3 A4C0B700 MOV DWORD PTR DS:[B7C0A4],EAX
00407A36 |. 6A 00 PUSH 0 ; /pModule = NULL
00407A38 |. E8 2BFFFFFF CALL <JMP.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
00407A3D |. A3 68C6B800 MOV DWORD PTR DS:[B8C668],EAX
00407A42 |. A1 68C6B800 MOV EAX,DWORD PTR DS:[B8C668]
00407A47 |. A3 B0C0B700 MOV DWORD PTR DS:[B7C0B0],EAX
00407A4C |. 33C0 XOR EAX,EAX
00407A4E |. A3 B4C0B700 MOV DWORD PTR DS:[B7C0B4],EAX
00407A53 |. 33C0 XOR EAX,EAX
00407A55 |. A3 B8C0B700 MOV DWORD PTR DS:[B7C0B8],EAX
00407A5A |. E8 C1FFFFFF CALL Skype.00407A20
00407A5F |. BA ACC0B700 MOV EDX,Skype.00B7C0AC
00407A64 |. 8BC3 MOV EAX,EBX
00407A66 |. E8 95D2FFFF CALL Skype.00404D00 ; // 都在这里 CALL init
00407A6B |. 5B POP EBX
00407A6C \. C3 RETN 00404D00 /$ C705 14C0B800 F01240>MOV DWORD PTR DS:[B8C014],<JMP.&kernel32.RaiseException>
00404D0A |. C705 18C0B800 001340>MOV DWORD PTR DS:[B8C018],<JMP.&kernel32.RtlUnwind>
00404D14 |. A3 40C6B800 MOV DWORD PTR DS:[B8C640],EAX
00404D19 |. 33C0 XOR EAX,EAX
00404D1B |. A3 44C6B800 MOV DWORD PTR DS:[B8C644],EAX
00404D20 |. 8915 48C6B800 MOV DWORD PTR DS:[B8C648],EDX
00404D26 |. 8B42 04 MOV EAX,DWORD PTR DS:[EDX+4]
00404D29 |. A3 30C0B800 MOV DWORD PTR DS:[B8C030],EAX
00404D2E |. E8 A5FEFFFF CALL Skype.00404BD8
00404D33 |. C605 38C0B800 00 MOV BYTE PTR DS:[B8C038],0
00404D3A |. E8 51FFFFFF CALL Skype.00404C90 ; // Delphi 的程序好象都是这样
00404D3F \. C3 RETN
00404C90 $ 55 PUSH EBP
00404C91 . 8BEC MOV EBP,ESP
00404C93 . 83C4 F8 ADD ESP,-8
00404C96 . 53 PUSH EBX
00404C97 . 56 PUSH ESI
00404C98 . 57 PUSH EDI
00404C99 . BF 38C6B800 MOV EDI,Skype.00B8C638
00404C9E . 8B47 08 MOV EAX,DWORD PTR DS:[EDI+8]
00404CA1 . 85C0 TEST EAX,EAX
00404CA3 . 74 54 JE SHORT Skype.00404CF9
00404CA5 . 8B30 MOV ESI,DWORD PTR DS:[EAX]
00404CA7 . 33DB XOR EBX,EBX
00404CA9 . 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
00404CAC . 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00404CAF . 33C0 XOR EAX,EAX
00404CB1 . 55 PUSH EBP
00404CB2 . 68 E54C4000 PUSH Skype.00404CE5
00404CB7 . 64:FF30 PUSH DWORD PTR FS:[EAX]
00404CBA . 64:8920 MOV DWORD PTR FS:[EAX],ESP
00404CBD . 3BF3 CMP ESI,EBX
00404CBF . 7E 1A JLE SHORT Skype.00404CDB
00404CC1 > 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00404CC4 . 8B04D8 MOV EAX,DWORD PTR DS:[EAX+EBX*8]
00404CC7 . 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
00404CCA . 43 INC EBX
00404CCB . 895F 0C MOV DWORD PTR DS:[EDI+C],EBX
00404CCE . 837D F8 00 CMP DWORD PTR SS:[EBP-8],0
00404CD2 . 74 03 JE SHORT Skype.00404CD7
00404CD4 . FF55 F8 CALL DWORD PTR SS:[EBP-8] ; // Call each init Func, 其中 00B75AF0 最关键,
00404CD7 > 3BF3 CMP ESI,EBX
00404CD9 .^ 7F E6 JG SHORT Skype.00404CC1
00404CDB > 33C0 XOR EAX,EAX
00404CDD . 5A POP EDX
00404CDE . 59 POP ECX
00404CDF . 59 POP ECX
00404CE0 . 64:8910 MOV DWORD PTR FS:[EAX],EDX
00404CE3 . EB 14 JMP SHORT Skype.00404CF9
00404CE5 .^ E9 3AF9FFFF JMP Skype.00404624
00404CEA . E8 31FFFFFF CALL Skype.00404C20
00404CEF . E8 08FDFFFF CALL Skype.004049FC
00404CF4 . E8 57FDFFFF CALL Skype.00404A50
00404CF9 > 5F POP EDI
00404CFA . 5E POP ESI
00404CFB . 5B POP EBX
00404CFC . 59 POP ECX
00404CFD . 59 POP ECX
00404CFE . 5D POP EBP
00404CFF . C3 RETN
检查调试器的两处, 下 CreateFileA, CreateFileW 断点, 很快就可以跟到, 不过它不检测OLLYDBG.
3. 最关键的一个 Init CALL 00B75AF0-00B75EB1
// 对 00724F70-00B70F70 (size 0044C000) 解码, 并解析第二份 IAT
// 第二份 IAT: 00A09F70-00A0A38C, size: 041C
// 00B75AF0 返回后, 内存中全是明文.
00B75AF0 /> /55 PUSH EBP
00B75AF1 |. |8BEC MOV EBP,ESP
00B75AF3 |. |83C4 A0 ADD ESP,-60
00B75AF6 |. |33C0 XOR EAX,EAX
00B75AF8 |. |8945 A8 MOV DWORD PTR SS:[EBP-58],EAX
00B75AFB |. |8945 A4 MOV DWORD PTR SS:[EBP-5C],EAX
00B75AFE |. |8945 A0 MOV DWORD PTR SS:[EBP-60],EAX
00B75B01 |. |8945 AC MOV DWORD PTR SS:[EBP-54],EAX
00B75B04 |. |33C0 XOR EAX,EAX
00B75B06 |. |55 PUSH EBP
00B75B07 |. |68 A75EB700 PUSH Skype.00B75EA7
00B75B0C |. |64:FF30 PUSH DWORD PTR FS:[EAX]
00B75B0F |. |64:8920 MOV DWORD PTR FS:[EAX],ESP
00B75B12 |. |A1 18BAB800 MOV EAX,DWORD PTR DS:[B8BA18]
00B75B17 |. |C700 09000000 MOV DWORD PTR DS:[EAX],9
00B75B1D |. |B8 287A5E00 MOV EAX,Skype.<ModuleEntryPoint>
00B75B22 |. |8945 D4 MOV DWORD PTR SS:[EBP-2C],EAX
00B75B25 |. C745 D0 F4000000 MOV DWORD PTR SS:[EBP-30],0F4
00B75B2C |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
00B75B2F |. 50 PUSH EAX ; /pOldProtect
00B75B30 |. 6A 40 PUSH 40 ; |NewProtect = PAGE_EXECUTE_READWRITE
00B75B32 |. 8B45 D0 MOV EAX,DWORD PTR SS:[EBP-30] ; |
00B75B35 |. 50 PUSH EAX ; |Size
00B75B36 |. 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C] ; |
00B75B39 |. 50 PUSH EAX ; |Address
00B75B3A |. E8 192789FF CALL <JMP.&kernel32.VirtualProtect> ; \VirtualProtect
00B75B3F |. 85C0 TEST EAX,EAX
00B75B41 |. 75 0A JNZ SHORT Skype.00B75B4D
00B75B43 |. B8 BC5EB700 MOV EAX,Skype.00B75EBC ; ASCII "0ut of memory"
00B75B48 |. E8 2BFAFFFF CALL Skype.00B75578
00B75B4D |> 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C]
00B75B50 |. 33C9 XOR ECX,ECX
00B75B52 |. 8B55 D0 MOV EDX,DWORD PTR SS:[EBP-30]
00B75B55 |. E8 96DD88FF CALL Skype.004038F0 ; 将 OEP 处开始的一小段代码清 0, 防止解码后的 DUMP
00B75B5A |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
00B75B5D |. 50 PUSH EAX ; /pOldProtect
00B75B5E |. 6A 20 PUSH 20 ; |NewProtect = PAGE_EXECUTE_READ
00B75B60 |. 8B45 D0 MOV EAX,DWORD PTR SS:[EBP-30] ; |
00B75B63 |. 50 PUSH EAX ; |Size
00B75B64 |. 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C] ; |
00B75B67 |. 50 PUSH EAX ; |Address
00B75B68 |. E8 EB2689FF CALL <JMP.&kernel32.VirtualProtect> ; \VirtualProtect
00B75B6D |. 85C0 TEST EAX,EAX
00B75B6F |. 75 0A JNZ SHORT Skype.00B75B7B
00B75B71 |. B8 BC5EB700 MOV EAX,Skype.00B75EBC ; ASCII "0ut of memory"
00B75B76 |. E8 FDF9FFFF CALL Skype.00B75578
00B75B7B |> C605 0C5FB800 01 MOV BYTE PTR DS:[B85F0C],1
00B75B82 |. 6A 04 PUSH 4 ; /Protect = PAGE_READWRITE
00B75B84 |. 68 00100000 PUSH 1000 ; |AllocationType = MEM_COMMIT
00B75B89 |. A1 605FB800 MOV EAX,DWORD PTR DS:[B85F60] ; |
00B75B8E |. 50 PUSH EAX ; |Size => 44C000 (4505600.)
00B75B8F |. 6A 00 PUSH 0 ; |Address = NULL
00B75B91 |. E8 B22689FF CALL <JMP.&kernel32.VirtualAlloc> ; \VirtualAlloc, 分配 Memory 用来解码
00B75B96 |. A3 4CE1B800 MOV DWORD PTR DS:[B8E14C],EAX
00B75B9B |. 833D 4CE1B800 00 CMP DWORD PTR DS:[B8E14C],0
00B75BA2 |. 75 0A JNZ SHORT Skype.00B75BAE
00B75BA4 |. B8 D45EB700 MOV EAX,Skype.00B75ED4 ; ASCII "Not enough memory!"
00B75BA9 |. E8 CAF9FFFF CALL Skype.00B75578
00B75BAE |> B8 684F7200 MOV EAX,Skype.00724F68 ; 从这儿开始是解码的CODE, 很简单, 就一个XOR, 只是XOR的值是一直在变.
00B75BB3 |. BA 684F7200 MOV EDX,Skype.00724F68
00B75BB8 |. 0302 ADD EAX,DWORD PTR DS:[EDX]
00B75BBA |. 8945 CC MOV DWORD PTR SS:[EBP-34],EAX
00B75BBD |. 33C0 XOR EAX,EAX
00B75BBF |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
00B75BC2 |. E9 83000000 JMP Skype.00B75C4A
00B75BC7 |> 8B45 F8 /MOV EAX,DWORD PTR SS:[EBP-8]
...省略一些CODE
00B75C3B |. 8345 EC 71 ||ADD DWORD PTR SS:[EBP-14],71
00B75C3F |. FF45 E8 ||INC DWORD PTR SS:[EBP-18]
00B75C42 |. FF4D C8 ||DEC DWORD PTR SS:[EBP-38]
00B75C45 |.^ 75 D0 |\JNZ SHORT Skype.00B75C17
00B75C47 |> FF45 F8 |INC DWORD PTR SS:[EBP-8]
00B75C4A |> 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00B75C4D |. 8D0480 |LEA EAX,DWORD PTR DS:[EAX+EAX*4]
00B75C50 |. 833C85 105FB800 00 |CMP DWORD PTR DS:[EAX*4+B85F10],0
00B75C58 |.^ 0F87 69FFFFFF \JA Skype.00B75BC7 ; 解码的CODE到这儿为止 00B75C5E |. 33C0 XOR EAX,EAX ; 从这儿起开始解析一份内部的IAT
00B75C60 |. 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
00B75C63 |. 33C0 XOR EAX,EAX
00B75C65 |. 8945 DC MOV DWORD PTR SS:[EBP-24],EAX
00B75C68 |. C745 E8 01000000 MOV DWORD PTR SS:[EBP-18],1
00B75C6F |> 8B45 E8 /MOV EAX,DWORD PTR SS:[EBP-18]
...省略一些CODE
00B75D51 |> 8B45 E0 |MOV EAX,DWORD PTR SS:[EBP-20]
00B75D54 |. 0145 DC |ADD DWORD PTR SS:[EBP-24],EAX
00B75D57 |. 8B45 E8 |MOV EAX,DWORD PTR SS:[EBP-18]
00B75D5A |. 8D0440 |LEA EAX,DWORD PTR DS:[EAX+EAX*2]
00B75D5D |. 8B0485 705FB800 |MOV EAX,DWORD PTR DS:[EAX*4+B85F70]
00B75D64 |. 0305 4CE1B800 |ADD EAX,DWORD PTR DS:[B8E14C]
00B75D6A |. 8B55 E0 |MOV EDX,DWORD PTR SS:[EBP-20]
00B75D6D |. 8910 |MOV DWORD PTR DS:[EAX],EDX
00B75D6F |> FF45 E8 |INC DWORD PTR SS:[EBP-18]
00B75D72 |. 817D E8 09010000 |CMP DWORD PTR SS:[EBP-18],109
00B75D79 |.^ 0F85 F0FEFFFF \JNZ Skype.00B75C6F
00B75D7F |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
00B75D82 |. 50 PUSH EAX ; /pOldProtect
00B75D83 |. 6A 04 PUSH 4 ; |NewProtect = PAGE_READWRITE
00B75D85 |. A1 605FB800 MOV EAX,DWORD PTR DS:[B85F60] ; |
00B75D8A |. 50 PUSH EAX ; |Size => 44C000 (4505600.)
00B75D8B |. 8B45 CC MOV EAX,DWORD PTR SS:[EBP-34] ; |
00B75D8E |. 50 PUSH EAX ; |Address
00B75D8F |. E8 C42489FF CALL <JMP.&kernel32.VirtualProtect> ; \VirtualProtect
00B75D94 |. 85C0 TEST EAX,EAX
00B75D96 |. 75 51 JNZ SHORT Skype.00B75DE9
00B75D98 |. 68 405FB700 PUSH Skype.00B75F40 ; ASCII "error 9920 ("
00B75D9D |. 8D4D A4 LEA ECX,DWORD PTR SS:[EBP-5C]
00B75DA0 |. B2 08 MOV DL,8
00B75DA2 |. A1 605FB800 MOV EAX,DWORD PTR DS:[B85F60]
00B75DA7 |. E8 E09791FF CALL Skype.0048F58C
00B75DAC |. FF75 A4 PUSH DWORD PTR SS:[EBP-5C]
00B75DAF |. 68 585FB700 PUSH Skype.00B75F58
00B75DB4 |. E8 572289FF CALL <JMP.&kernel32.GetLastError> ; GetLastError
00B75DB9 |. 33D2 XOR EDX,EDX
00B75DBB |. 52 PUSH EDX ; /Arg2 => 00000000
00B75DBC |. 50 PUSH EAX ; |Arg1
00B75DBD |. 8D45 A0 LEA EAX,DWORD PTR SS:[EBP-60] ; |
00B75DC0 |. E8 9B5189FF CALL Skype.0040AF60 ; \Skype.0040AF60
00B75DC5 |. FF75 A0 PUSH DWORD PTR SS:[EBP-60]
00B75DC8 |. 68 645FB700 PUSH Skype.00B75F64
00B75DCD |. 8D45 A8 LEA EAX,DWORD PTR SS:[EBP-58]
00B75DD0 |. BA 05000000 MOV EDX,5
00B75DD5 |. E8 52F688FF CALL Skype.0040542C
00B75DDA |. 8B45 A8 MOV EAX,DWORD PTR SS:[EBP-58]
00B75DDD |. E8 46468CFF CALL Skype.0043A428
00B75DE2 |. 6A 00 PUSH 0 ; /ExitCode = 0
00B75DE4 |. E8 172189FF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
00B75DE9 |> 8B55 CC MOV EDX,DWORD PTR SS:[EBP-34]
00B75DEC |. A1 4CE1B800 MOV EAX,DWORD PTR DS:[B8E14C]
00B75DF1 |. 8B0D 605FB800 MOV ECX,DWORD PTR DS:[B85F60] ; Skype.0044C000
00B75DF7 |. E8 14D388FF CALL Skype.00403110 ;
00B75DFC |. 68 00800000 PUSH 8000 ; /FreeType = MEM_RELEASE
00B75E01 |. 6A 00 PUSH 0 ; |Size = 0
00B75E03 |. A1 4CE1B800 MOV EAX,DWORD PTR DS:[B8E14C] ; |
00B75E08 |. 50 PUSH EAX ; |Address => NULL
00B75E09 |. E8 422489FF CALL <JMP.&kernel32.VirtualFree> ; \VirtualFree
00B75E0E |. 8B45 CC MOV EAX,DWORD PTR SS:[EBP-34]
00B75E11 |. A3 4CE1B800 MOV DWORD PTR DS:[B8E14C],EAX
00B75E16 |. 33C0 XOR EAX,EAX
00B75E18 |. 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
00B75E1B |> 8D45 FC /LEA EAX,DWORD PTR SS:[EBP-4]
00B75E1E |. 50 |PUSH EAX ; /pOldProtect
00B75E1F |. 8B45 E8 |MOV EAX,DWORD PTR SS:[EBP-18] ; |
00B75E22 |. 8D0480 |LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; |
00B75E25 |. 8B0485 205FB800 |MOV EAX,DWORD PTR DS:[EAX*4+B85F20] ; |
00B75E2C |. 50 |PUSH EAX ; |NewProtect
00B75E2D |. 8B45 E8 |MOV EAX,DWORD PTR SS:[EBP-18] ; |
00B75E30 |. 8D0480 |LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; |
00B75E33 |. 8B0485 145FB800 |MOV EAX,DWORD PTR DS:[EAX*4+B85F14] ; |
00B75E3A |. 50 |PUSH EAX ; |Size
00B75E3B |. 8B45 E8 |MOV EAX,DWORD PTR SS:[EBP-18] ; |
00B75E3E |. 8D0480 |LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; |
00B75E41 |. 8B0485 105FB800 |MOV EAX,DWORD PTR DS:[EAX*4+B85F10] ; |
00B75E48 |. 0305 4CE1B800 |ADD EAX,DWORD PTR DS:[B8E14C] ; |
00B75E4E |. 50 |PUSH EAX ; |Address
00B75E4F |. E8 042489FF |CALL <JMP.&kernel32.VirtualProtect> ; \VirtualProtect
00B75E54 |. FF45 E8 |INC DWORD PTR SS:[EBP-18]
00B75E57 |. 8B45 E8 |MOV EAX,DWORD PTR SS:[EBP-18]
00B75E5A |. 8D0480 |LEA EAX,DWORD PTR DS:[EAX+EAX*4]
00B75E5D |. 833C85 105FB800 00 |CMP DWORD PTR DS:[EAX*4+B85F10],0
00B75E65 |.^ 75 B4 \JNZ SHORT Skype.00B75E1B
00B75E67 |. A1 705FB800 MOV EAX,DWORD PTR DS:[B85F70]
00B75E6C |. 0305 4CE1B800 ADD EAX,DWORD PTR DS:[B8E14C]
00B75E72 |. 6A 00 PUSH 0
00B75E74 |. 6A 01 PUSH 1
00B75E76 |. FF35 4CE1B800 PUSH DWORD PTR DS:[B8E14C]
00B75E7C |. FFD0 CALL EAX
00B75E7E |. 833D 4CE1B800 00 CMP DWORD PTR DS:[B8E14C],0
00B75E85 |. 75 05 JNZ SHORT Skype.00B75E8C
00B75E87 |. E8 3805A7FF CALL Skype.005E63C4
00B75E8C |> 33C0 XOR EAX,EAX
00B75E8E |. 5A POP EDX
00B75E8F |. 59 POP ECX
00B75E90 |. 59 POP ECX
00B75E91 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
00B75E94 |. 68 AE5EB700 PUSH Skype.00B75EAE
00B75E99 |> 8D45 A0 LEA EAX,DWORD PTR SS:[EBP-60]
00B75E9C |. BA 04000000 MOV EDX,4
00B75EA1 |. E8 FEF188FF CALL Skype.004050A4
00B75EA6 \. C3 RETN
00B75EA7 .^ E9 2CEA88FF JMP Skype.004048D8
00B75EAC .^ EB EB JMP SHORT Skype.00B75E99
00B75EAE . 8BE5 MOV ESP,EBP
00B75EB0 . 5D POP EBP
00B75EB1 . C3 RETN 整个过程用C写大致是:
VirtualProtect(OEP, size, PAGE_EXECUTE_READWRITE, &oldProtect);
memset(OEP, 0, size);
VirtualProtect(OEP, size, PAGE_EXECUTE_READ, &oldProtect);
pMem = VirtualAlloc(NULL, 0x44C000, MEM_COMMIT, PAGE_READWRITE);
value = 0X????;
for(i=0;i<SegNum;i++){
for(j=0;j<Segs[i].size;j+=4) {
offset = ....
pMem[offset] = pOrig[offset] ^ value;
value += xxxx;
}
}
for(i=0;i<num;i++) {
if (info[i].flags == xxx)
Handle = LoadLibrary(info[i].name);
else {
pProc = GetProcAddress(Handle, info[i].name)
offset = info[i].offset;
pMem[offset] = pProc;
}
}
VirtualProtect(pStart, 0x44C000, PAGE_READ_WRITE, &oldProtect);
memcpy(pStart, pMem, 0x44C000);
VirtualFree(pMem, 0, MEM_RELEASE);
for(i=0;i<SegNum;i++){
offset = ...
VirtualProtect(pStart+offset, sizexx, NewProtectxxxx, &oldProtect);
}
看看它的作用:
a.) 解码的时候清掉了OEP处的一小段代码清, 可防止解码后的简单 DUMP
b.) 调用了 VirtualProtect, 对这段 被解密的CODE 下的 memory write 断点不再起作用.
c.) 两份IAT, 第一份是标准的EXE的, 由 Loader 解析, 另一份由 自己在解码后 解析. 所以解码后, 即使内存中全是明文, DUMP 后, IAT 也不容易修复,
两份 IAT 在 memory 中相差很远, ImportRec 好象不行, 总不至于手工构造 引入表(I T) 吧? 4. 程序中的 anti-debug 解除
用OllyDbg载入程序, 忽略 所有 Exception, F9 能正确运行, 但是运行不久, 就出现
Debugged program was unable to process exception
但是单独运行却是好好的, 十有八九是 SetUnhandledExceptionFilter 的 anti-debug.
Ctrl-F2 重新开始, bp SetUnhandledExceptionFilter, 然后 F9 运行, 运行不久就断下来, 果然不出所料.
Ctrl-G UnhandledExceptionFilter, 向下一点, 将CALL ZwQueryInformationProcess 下面的第二个条件跳转 NOP 掉,
// UnhandledExceptionFilter
7C59BCDC > 55 PUSH EBP
7C59BCDD 8BEC MOV EBP,ESP
7C59BCDF 6A FF PUSH -1
7C59BCE1 68 C02E577C PUSH kernel32.7C572EC0
...
7C59BD3B 6A 07 PUSH 7
7C59BD3D E8 7BBBFFFF CALL kernel32.GetCurrentProcess
7C59BD42 50 PUSH EAX
7C59BD43 FF15 B810577C CALL DWORD PTR DS:[<&ntdll.NtQueryInformationProc>; ntdll.ZwQueryInformationProcess
7C59BD49 3BC3 CMP EAX,EBX
7C59BD4B 7C 09 JL SHORT kernel32.7C59BD56
7C59BD4D 395D C8 CMP DWORD PTR SS:[EBP-38],EBX
7C59BD50 0F85 49020000 JNZ kernel32.7C59BF9F ; // 这儿不能跳, NOP 掉就好了
这样, 程序总算开始听话. 由于Windows各个平台/版本的差异, 下载的 OLLYDBG 插件不起作用, 就只好手工改了. 4. 程序中的 anti-debug CODE 分析 (1)
解除 anti-debug 后总想看看, 这样的 anti-debug CODE 是怎么写的, 又是如何触发的.
bp SetUnhandledExceptionFilter, 可找到 程序的 exception filter function 地址是 0072B670
分析一下这段CODE:
:0072B670 53 push ebx
* Reference To: kernel32.GetCurrentThreadId, Ord:0111h
|
:0072B671 FF15909FA000 Call dword ptr [00A09F90]
:0072B677 3B05F017B200 cmp eax, dword ptr [00B217F0] ; ThreadId == [00B217F0]?
:0072B67D 741C je 0072B69B ; YES
:0072B67F A1EC17B200 mov eax, dword ptr [00B217EC]
:0072B684 33DB xor ebx, ebx
:0072B686 3BC3 cmp eax, ebx
:0072B688 740B je 0072B695
:0072B68A 8B4C2408 mov ecx, dword ptr [esp+08]
:0072B68E 51 push ecx
:0072B68F FFD0 call eax
:0072B691 5B pop ebx
:0072B692 C20400 ret 0004 * Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B688(C)
|
:0072B695 33C0 xor eax, eax
:0072B697 5B pop ebx
:0072B698 C20400 ret 0004 * Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B67D(C)
|
:0072B69B 8B0DE817B200 mov ecx, dword ptr [00B217E8] ; 一个 NUM
:0072B6A1 55 push ebp
:0072B6A2 56 push esi
:0072B6A3 8B742410 mov esi, dword ptr [esp+10] ; ExceptionInfo 参数
:0072B6A7 8D1449 lea edx, dword ptr [ecx+2*ecx]
:0072B6AA 57 push edi
:0072B6AB 41 inc ecx
:0072B6AC B801000000 mov eax, 00000001 ; 初始化返回值
:0072B6B1 8D3C952018B200 lea edi, dword ptr [4*edx+00B21820] ; 00B21820 处是一个表, 每项size=3*4
:0072B6B8 890DE817B200 mov dword ptr [00B217E8], ecx ; NUM 加 1 了,
:0072B6BE C74708FFFFFFFF mov [edi+08], FFFFFFFF
:0072B6C5 8B0E mov ecx, dword ptr [esi] ; ExceptionRecord
:0072B6C7 8B29 mov ebp, dword ptr [ecx] ; ExceptionCode
:0072B6C9 F7C500FFFF00 test ebp, 00FFFF00 ; 是 xx0000yy 的格式吗?
:0072B6CF 7516 jne 0072B6E7
:0072B6D1 8BD5 mov edx, ebp ; xx0000yy ==> xxyy
:0072B6D3 C1EA10 shr edx, 10
:0072B6D6 8ADA mov bl, dl
:0072B6D8 3219 xor bl, byte ptr [ecx]
:0072B6DA 81E3FF000000 and ebx, 000000FF
:0072B6E0 33DA xor ebx, edx
:0072B6E2 66891F mov word ptr [edi], bx ; 保存xxyy
:0072B6E5 EB05 jmp 0072B6EC
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B6CF(C)
|
:0072B6E7 66C707FFFF mov word ptr [edi], FFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B6E5(U)
|
:0072B6EC 8B0E mov ecx, dword ptr [esi]
:0072B6EE 33DB xor ebx, ebx
:0072B6F0 8B510C mov edx, dword ptr [ecx+0C]
:0072B6F3 895704 mov dword ptr [edi+04], edx ; 保存 ExceptionAddress
:0072B6F6 8B0E mov ecx, dword ptr [esi]
:0072B6F8 8B510C mov edx, dword ptr [ecx+0C] ; edi = ExceptionAddress
:0072B6FB 33C9 xor ecx, ecx
:0072B6FD 668B0F mov cx, word ptr [edi]
:0072B700 81F91DC00000 cmp ecx, 0000C01D
:0072B706 0F8F4E020000 jg 0072B95A
:0072B70C 0F84C4010000 je 0072B8D6
:0072B712 81E903800000 sub ecx, 00008003
:0072B718 0F847D010000 je 0072B89B
:0072B71E 49 dec ecx
:0072B71F 0F845E010000 je 0072B883
:0072B725 81E901400000 sub ecx, 00004001
:0072B72B 0F8534020000 jne 0072B965
:0072B731 803ACD cmp byte ptr [edx], CD ; xxyy == C005 到这,
:0072B734 0F8578020000 jne 0072B9B2
:0072B73A 807A0101 cmp byte ptr [edx+01], 01
:0072B73E 0F856E020000 jne 0072B9B2
:0072B744 8B7A01 mov edi, dword ptr [edx+01]
:0072B747 32C9 xor cl, cl
:0072B749 81FF01CC8DC0 cmp edi, C08DCC01
:0072B74F 7540 jne 0072B791
:0072B751 8B5604 mov edx, dword ptr [esi+04] ; ExceptionAddress 处是 CD 01 CC 8D C0 到这
:0072B754 8B82B0000000 mov eax, dword ptr [edx+000000B0]
:0072B75A A3281BB200 mov dword ptr [00B21B28], eax ; [00B21B28] = context->eax
:0072B75F 8B4E04 mov ecx, dword ptr [esi+04]
:0072B762 8B91A8000000 mov edx, dword ptr [ecx+000000A8]
:0072B768 89152C1BB200 mov dword ptr [00B21B2C], edx ; [00B21B28] = context->eax
:0072B76E 8B4604 mov eax, dword ptr [esi+04]
:0072B771 8B88B8000000 mov ecx, dword ptr [eax+000000B8]
:0072B777 83C105 add ecx, 00000005
:0072B77A 8988B8000000 mov dword ptr [eax+000000B8], ecx ; context->eip += 5
:0072B780 A1681BB200 mov eax, dword ptr [00B21B68]
:0072B785 0C02 or al, 02
:0072B787 A3681BB200 mov dword ptr [00B21B68], eax ; [00B21B68] |=2
:0072B78C 83C8FF or eax, FFFFFFFF ; eax = -1
:0072B78F EB6E jmp 0072B7FF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B74F(C)
|
:0072B791 81FF018DC0CC cmp edi, CCC08D01
:0072B797 7568 jne 0072B801
:0072B799 8B15681BB200 mov edx, dword ptr [00B21B68] ; ExceptionAddress 处是 CD 01 8D C0 CC 到这
:0072B79F 83CA04 or edx, 00000004
:0072B7A2 8915681BB200 mov dword ptr [00B21B68], edx ; [00B21B68] |=4
:0072B7A8 8B4604 mov eax, dword ptr [esi+04]
:0072B7AB F6C202 test dl, 02
:0072B7AE 8B80B0000000 mov eax, dword ptr [eax+000000B0]
:0072B7B4 A3201BB200 mov dword ptr [00B21B20], eax ; [00B21B20] = context->eax
:0072B7B9 8B4E04 mov ecx, dword ptr [esi+04]
:0072B7BC 8B89A8000000 mov ecx, dword ptr [ecx+000000A8]
:0072B7C2 890D241BB200 mov dword ptr [00B21B24], ecx ; [00B21B20] = context->edx
:0072B7C8 7428 je 0072B7F2
:0072B7CA 8B2D281BB200 mov ebp, dword ptr [00B21B28]
:0072B7D0 8B152C1BB200 mov edx, dword ptr [00B21B2C]
:0072B7D6 2BC5 sub eax, ebp
:0072B7D8 A3701BB200 mov dword ptr [00B21B70], eax ; [00B21B70] = context->eax - [00B21B28]
:0072B7DD A1681BB200 mov eax, dword ptr [00B21B68]
:0072B7E2 1BCA sbb ecx, edx
:0072B7E4 80CC80 or ah, 80
:0072B7E7 890D741BB200 mov dword ptr [00B21B74], ecx ; [00B21B74] = context->edx - [00B21B2C]
:0072B7ED A3681BB200 mov dword ptr [00B21B68], eax ; [00B21B68] |= 00008000
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B7C8(C)
|
:0072B7F2 8B4E04 mov ecx, dword ptr [esi+04]
:0072B7F5 83C8FF or eax, FFFFFFFF
:0072B7F8 8381B800000004 add dword ptr [ecx+000000B8], 00000004 ; context->eip += 5
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B78F(U)
|
:0072B7FF B101 mov cl, 01
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B797(C)
|
:0072B801 81E7FFFF0000 and edi, 0000FFFF
:0072B807 81FF01CF0000 cmp edi, 0000CF01
:0072B80D 7565 jne 0072B874
:0072B80F 8B5604 mov edx, dword ptr [esi+04] ; ExceptionAddress 处是 CD 01 CF 到这
:0072B812 8B82C4000000 mov eax, dword ptr [edx+000000C4]
:0072B818 8B00 mov eax, dword ptr [eax]
:0072B81A F6C408 test ah, 08
:0072B81D A36C1BB200 mov dword ptr [00B21B6C], eax
:0072B822 750A jne 0072B82E
:0072B824 810D681BB20000000100 or dword ptr [00B21B68], 00010000 ; [00B21B68] |= 00010000
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B822(C)
|
:0072B82E F6C401 test ah, 01
:0072B831 750A jne 0072B83D
:0072B833 810D681BB20000000200 or dword ptr [00B21B68], 00020000 ; [00B21B68] |= 00010000
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B831(C)
|
:0072B83D 8B5604 mov edx, dword ptr [esi+04]
:0072B840 B9E0B97200 mov ecx, 0072B9E0
:0072B845 41 inc ecx
:0072B846 898AB8000000 mov dword ptr [edx+000000B8], ecx ; context->eip = 0072B9E1
:0072B84C 8B4604 mov eax, dword ptr [esi+04]
:0072B84F 8B0D601BB200 mov ecx, dword ptr [00B21B60]
:0072B855 8988C4000000 mov dword ptr [eax+000000C4], ecx ; context->esp = [00B21B60]
:0072B85B A1681BB200 mov eax, dword ptr [00B21B68]
:0072B860 0D00000400 or eax, 00040000
:0072B865 A3681BB200 mov dword ptr [00B21B68], eax ; [00B21B68] |= 00040000
:0072B86A E881FDFFFF call 0072B5F0
:0072B86F E93B010000 jmp 0072B9AF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B80D(C)
|
:0072B874 3ACB cmp cl, bl
:0072B876 0F8536010000 jne 0072B9B2
:0072B87C 33C0 xor eax, eax
:0072B87E E92F010000 jmp 0072B9B2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B71F(C)
|
:0072B883 391D641BB200 cmp dword ptr [00B21B64], ebx ; xxyy == 8004 到这
:0072B889 0F8520010000 jne 0072B9AF
:0072B88F A1681BB200 mov eax, dword ptr [00B21B68]
:0072B894 0C01 or al, 01
:0072B896 E90F010000 jmp 0072B9AA
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B718(C)
|
:0072B89B 803ACC cmp byte ptr [edx], CC ; xxyy == 8004 到这
:0072B89E 0F850E010000 jne 0072B9B2
:0072B8A4 807A018D cmp byte ptr [edx+01], 8D
:0072B8A8 750F jne 0072B8B9
:0072B8AA 807A02C0 cmp byte ptr [edx+02], C0
:0072B8AE 7509 jne 0072B8B9
:0072B8B0 A1681BB200 mov eax, dword ptr [00B21B68] ; ExceptionAddress 处是 CC 8D C0
:0072B8B5 0C08 or al, 08 ; [00B21B68] |= 08
:0072B8B7 EB07 jmp 0072B8C0
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072B8A8(C), :0072B8AE(C)
|
:0072B8B9 A1681BB200 mov eax, dword ptr [00B21B68]
:0072B8BE 0C10 or al, 10 ; [00B21B68] |= 08
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B8B7(U)
|
:0072B8C0 A3681BB200 mov dword ptr [00B21B68], eax
:0072B8C5 8B4E04 mov ecx, dword ptr [esi+04]
:0072B8C8 83C8FF or eax, FFFFFFFF
:0072B8CB FF81B8000000 inc dword ptr [ecx+000000B8] ; context->eip++
:0072B8D1 E9DC000000 jmp 0072B9B2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B70C(C)
|
:0072B8D6 803A0F cmp byte ptr [edx], 0F ; xxyy == C01D 到这
:0072B8D9 B902000000 mov ecx, 00000002 ; ecx = 2
:0072B8DE 7539 jne 0072B919
:0072B8E0 807A010B cmp byte ptr [edx+01], 0B
:0072B8E4 7533 jne 0072B919
:0072B8E6 8B4604 mov eax, dword ptr [esi+04] ; ExceptionAddress 处是 0F 0B
:0072B8E9 8BA8B8000000 mov ebp, dword ptr [eax+000000B8]
:0072B8EF 03E9 add ebp, ecx
:0072B8F1 89A8B8000000 mov dword ptr [eax+000000B8], ebp ; context->eip +=2
:0072B8F7 8B4604 mov eax, dword ptr [esi+04]
:0072B8FA 8BB8C0000000 mov edi, dword ptr [eax+000000C0]
:0072B900 81CF00090000 or edi, 00000900
:0072B906 89B8C0000000 mov dword ptr [eax+000000C0], edi ; context->EFlags |= 900 // OF, TF// 设置CPU单步 flags
:0072B90C 83C8FF or eax, FFFFFFFF
:0072B90F C705641BB20001000000 mov dword ptr [00B21B64], 00000001
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072B8DE(C), :0072B8E4(C)
|
:0072B919 803A8D cmp byte ptr [edx], 8D
:0072B91C 0F8590000000 jne 0072B9B2
:0072B922 807A01C0 cmp byte ptr [edx+01], C0
:0072B926 0F8586000000 jne 0072B9B2
:0072B92C 8B4604 mov eax, dword ptr [esi+04] ; ExceptionAddress 处是 8D C0
:0072B92F 8B90B8000000 mov edx, dword ptr [eax+000000B8]
:0072B935 03D1 add edx, ecx
:0072B937 8990B8000000 mov dword ptr [eax+000000B8], edx ; context->eip +=2
:0072B93D 8B4604 mov eax, dword ptr [esi+04]
:0072B940 8B88C0000000 mov ecx, dword ptr [eax+000000C0]
:0072B946 80E5F6 and ch, F6
:0072B949 8988C0000000 mov dword ptr [eax+000000C0], ecx ; context->EFlags &= ~900 // 设置CPU单步 flags
:0072B94F 83C8FF or eax, FFFFFFFF
:0072B952 891D641BB200 mov dword ptr [00B21B64], ebx
:0072B958 EB58 jmp 0072B9B2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B706(C)
|
:0072B95A 81E995C00000 sub ecx, 0000C095
:0072B960 7440 je 0072B9A2
:0072B962 49 dec ecx
:0072B963 7411 je 0072B976
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B72B(C)
|
:0072B965 8B0D681BB200 mov ecx, dword ptr [00B21B68]
:0072B96B 80CD08 or ch, 08
:0072B96E 890D681BB200 mov dword ptr [00B21B68], ecx
:0072B974 EB3C jmp 0072B9B2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B963(C)
|
:0072B976 803A0F cmp byte ptr [edx], 0F ; xxyy == C096 到这
:0072B979 7537 jne 0072B9B2
:0072B97B 807A0134 cmp byte ptr [edx+01], 34
:0072B97F 7531 jne 0072B9B2
:0072B981 8B3D681BB200 mov edi, dword ptr [00B21B68] ; ExceptionAddress 处是 0F 34
:0072B987 83C8FF or eax, FFFFFFFF
:0072B98A 81CF00100000 or edi, 00001000
:0072B990 893D681BB200 mov dword ptr [00B21B68], edi ; [00B21B68] |= 1000;
:0072B996 8B4E04 mov ecx, dword ptr [esi+04]
:0072B999 8381B800000002 add dword ptr [ecx+000000B8], 00000002 ; context->eip +=2
:0072B9A0 EB10 jmp 0072B9B2
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B960(C)
|
:0072B9A2 A1681BB200 mov eax, dword ptr [00B21B68] ; xxyy == C095 到这
:0072B9A7 80CC04 or ah, 04
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072B896(U)
|
:0072B9AA A3681BB200 mov dword ptr [00B21B68], eax ; [00B21B68] |= 400;
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072B86F(U), :0072B889(C)
|
:0072B9AF 83C8FF or eax, FFFFFFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072B734(C), :0072B73E(C), :0072B876(C), :0072B87E(U), :0072B89E(C)
|:0072B8D1(U), :0072B91C(C), :0072B926(C), :0072B958(U), :0072B974(U)
|:0072B979(C), :0072B97F(C), :0072B9A0(U)
|
:0072B9B2 8B5604 mov edx, dword ptr [esi+04]
:0072B9B5 5F pop edi
:0072B9B6 895A10 mov dword ptr [edx+10], ebx ; context->dr3 = 0, 清除硬件断点
:0072B9B9 8B4E04 mov ecx, dword ptr [esi+04]
:0072B9BC 89590C mov dword ptr [ecx+0C], ebx ; context->dr2 = 0
:0072B9BF 8B5604 mov edx, dword ptr [esi+04]
:0072B9C2 895A08 mov dword ptr [edx+08], ebx ; context->dr1 = 0
:0072B9C5 8B4E04 mov ecx, dword ptr [esi+04]
:0072B9C8 5E pop esi
:0072B9C9 5D pop ebp
:0072B9CA 895904 mov dword ptr [ecx+04], ebx ; context->dr0 = 0
:0072B9CD 5B pop ebx
:0072B9CE C20400 ret 0004
这段CODE 只是处理 Exception, 跟完了这段, 还是不太明白, 再想跟一跟 Exception 是如何触发的.
于是, 在 0072B9CE 处F8 返回到 kernel32.dll 领空后, 在 Memory Map 的 00401000 CODE 段上 F2 下断, 然后F9
断在0091885F
00918854 8B49 04 MOV ECX,DWORD PTR DS:[ECX+4]
00918857 50 PUSH EAX
00918858 51 PUSH ECX
00918859 FF15 ACA0A000 CALL DWORD PTR DS:[A0A0AC] ; kernel32.WaitForSingleObject
0091885F 85C0 TEST EAX,EAX ; 返回到这儿了????????
00918861 74 12 JE SHORT Skype.00918875
00918863 33D2 XOR EDX,EDX
00918865 3D 02010000 CMP EAX,102
0091886A 0F94C2 SETE DL
前后看看, 感觉不应该是这样的. 刚开始也是一阵迷惑不解, 后来弄了好久才想可能是这样:
程序是多线程的, 有个线程由于在00918859 CALL kernel32.WaitForSingleObject 而进入kernel32 的领空等待,
而我所跟的线程在处理好 Exception 后, 回到 kernel32.dll 领空, 再F9, 却被等待的线程抢先返回到 CODE 段的
0091885F 而触发了在 0401000 CODE 段上 的 F2 断点.
所以这条路走不通, 再想别的法子了. 5. 程序中的 anti-debug CODE 分析 (2) 根据 SetUnhandledExceptionFilter 找到下面的code:
* Referenced by a CALL at Address:
|:0072BF8C
|
:0072B9F0 53 push ebx
:0072B9F1 56 push esi
:0072B9F2 57 push edi
* Reference To: kernel32.GetCurrentThreadId, Ord:0111h
|
:0072B9F3 FF15909FA000 Call dword ptr [00A09F90]
:0072B9F9 A3F017B200 mov dword ptr [00B217F0], eax ; ThreadID
:0072B9FE E83DF2FFFF call 0072AC40 ; 将 SEH 链的最后一项填到第一项, 实际上是reset SEH 链
; 并返回第一项 * Reference To: kernel32.SetUnhandledExceptionFilter, Ord:02BFh
|
:0072BA03 8B3D949FA000 mov edi, dword ptr [00A09F94]
:0072BA09 6870B67200 push 0072B670
:0072BA0E 8BF0 mov esi, eax ; 保存第一项
:0072BA10 FFD7 call edi ; Call SetUnhandledExceptionFilter
:0072BA12 A3EC17B200 mov dword ptr [00B217EC], eax
:0072BA17 B904000000 mov ecx, 00000004
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BA54(C)
|
:0072BA1C A1381BB200 mov eax, dword ptr [00B21B38] ; rand的seed
:0072BA21 8B1D581BB200 mov ebx, dword ptr [00B21B58] ; VirtualAlloc 的一起始地址, 将用做 STACK
:0072BA27 8D1440 lea edx, dword ptr [eax+2*eax] ; 下面这几行就是 rand()
:0072BA2A 8D1490 lea edx, dword ptr [eax+4*edx]
:0072BA2D C1E204 shl edx, 04
:0072BA30 03D0 add edx, eax
:0072BA32 C1E208 shl edx, 08
:0072BA35 2BD0 sub edx, eax
:0072BA37 8D8490C39E2600 lea eax, dword ptr [eax+4*edx+00269EC3]
:0072BA3E 8B155C1BB200 mov edx, dword ptr [00B21B5C] ; VirtualAlloc 的 STACK size
:0072BA44 2BD1 sub edx, ecx
:0072BA46 83C104 add ecx, 00000004
:0072BA49 A3381BB200 mov dword ptr [00B21B38], eax
:0072BA4E 83F920 cmp ecx, 00000020
:0072BA51 89041A mov dword ptr [edx+ebx], eax ; 往memory的最后 0x20 bytes 填上一些随机数
:0072BA54 7EC6 jle 0072BA1C ; 循环
:0072BA56 E8F5FBFFFF call 0072B650 ; ****** 这里就是去产生各种 Unhandled Exception 的地方 ******
:0072BA5B A1EC17B200 mov eax, dword ptr [00B217EC]
:0072BA60 50 push eax
:0072BA61 FFD7 call edi ; 重 Call SetUnhandledExceptionFilter, 进行恢复工作
:0072BA63 56 push esi
:0072BA64 E8C7F1FFFF call 0072AC30 ; 恢复正常的SEH 链
:0072BA69 A1E817B200 mov eax, dword ptr [00B217E8] ; 下面的 CODE 检查 在 程序的UnhandledExceptionFilter的运行结果是否正常
:0072BA6E 83C404 add esp, 00000004
:0072BA71 83F80B cmp eax, 0000000B
:0072BA74 7544 jne 0072BABA
:0072BA76 33D2 xor edx, edx
:0072BA78 B92018B200 mov ecx, 00B21820
:0072BA7D B888A4A000 mov eax, 00A0A488
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BA9F(C)
|
:0072BA82 668B31 mov si, word ptr [ecx]
:0072BA85 663B30 cmp si, word ptr [eax]
:0072BA88 7517 jne 0072BAA1
:0072BA8A 0FBF7002 movsx esi, word ptr [eax+02]
:0072BA8E 397108 cmp dword ptr [ecx+08], esi
:0072BA91 750E jne 0072BAA1
:0072BA93 83C004 add eax, 00000004
:0072BA96 42 inc edx
:0072BA97 83C10C add ecx, 0000000C
:0072BA9A 3DB4A4A000 cmp eax, 00A0A4B4
:0072BA9F 7CE1 jl 0072BA82
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BA88(C), :0072BA91(C)
|
:0072BAA1 83FA0B cmp edx, 0000000B ; 结果是否正常?
:0072BAA4 7514 jne 0072BABA
:0072BAA6 8B0D681BB200 mov ecx, dword ptr [00B21B68]
:0072BAAC 81E116840400 and ecx, 00048416
:0072BAB2 81F916840400 cmp ecx, 00048416 ; flags 是 00048416 ?
:0072BAB8 740C je 0072BAC6
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BA74(C), :0072BAA4(C)
|
:0072BABA A1781BB200 mov eax, dword ptr [00B21B78] ; 非正常结果会到这,
:0072BABF 0C02 or al, 02
:0072BAC1 A3781BB200 mov dword ptr [00B21B78], eax ; 设置 1 flag
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BAB8(C)
|
:0072BAC6 5F pop edi
:0072BAC7 5E pop esi
:0072BAC8 5B pop ebx
:0072BAC9 C3 ret ; ret to 0072BF91 再跟一下返回后的CODE: :0072BF8C E85FFAFFFF call 0072B9F0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BF8A(C)
|
:0072BF91 A1681BB200 mov eax, dword ptr [00B21B68] ; 返回到这
:0072BF96 F6C480 test ah, 80
:0072BF99 7419 je 0072BFB4
:0072BF9B 392D741BB200 cmp dword ptr [00B21B74], ebp ; RDTSC 时间差的高 32bits
:0072BFA1 7C11 jl 0072BFB4
:0072BFA3 7F0C jg 0072BFB1 ; 大于 0 就 跳去 or edi, 1,
:0072BFA5 813D701BB20070640800 cmp dword ptr [00B21B70], 00086470 ; RDTSC 时间差的低 32bits < 00086470 ?
:0072BFAF 7203 jb 0072BFB4
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BFA3(C)
|
:0072BFB1 83CF01 or edi, 00000001 ;
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BF99(C), :0072BFA1(C), :0072BFAF(C)
|
:0072BFB4 F605341BB20001 test byte ptr [00B21B34], 01
:0072BFBB 7547 jne 0072C004 ********** 去产生各种 Unhandled Exception ****************
* Referenced by a CALL at Address:
|:0072BA56
|
:0072B650 9C pushfd ; 保存 Eflags
:0072B651 60 pushad ; 保存 REGs
:0072B652 8925601BB200 mov dword ptr [00B21B60], esp ; 保存 esp
:0072B658 8B25581BB200 mov esp, dword ptr [00B21B58] ; ***** ESP 给改了, 从现在起, STACK 窗口 没有有用的信息了 *******
:0072B65E 03255C1BB200 add esp, dword ptr [00B21B5C] ;
:0072B664 83EC20 sub esp, 00000020
:0072B667 61 popad ; ***** 这儿可不对应上面的pushad, pop的全是随机数, 看0072BA51
:0072B668 FF25501BB200 jmp dword ptr [00B21B50] ; 到这, 除了eip, esp的值有用, 起它的6个 reg 中全是垃圾, 跳到... 跳到这, 每次运行可是跳到不同的地址!!!
下面这一小段 CODE 要产生 11 (0x0B) 个 Unhandled Exception, 完成不同的功能 相当于CALL 0072B670 - 0072B9CE
********* 产生各种 Unhandled Exception 的 CODE *********
5F910152 /EB 02 JMP SHORT 5F910156 ; 跳
5F910154 C7 ??? ; Unknown command
5F910155 FA CLI
5F910156 /74 03 JE SHORT 5F91015B ; 跳
5F910158 |75 01 JNZ SHORT 5F91015B ; 跳
5F91015A 68 0F31CD01 PUSH 1CD310F
5F91015B 0F31 RDTSC ; 读 CPU 的xx counter, ==> EDX:EAX
5F91015D CD 01 INT 1 ; C0000005, eip+= 5
5F91015F CC INT3
5F910160 8DC0 LEA EAX,EAX ; Illegal use of register
5F910162 EB 02 JMP SHORT 5F910166 ; 跳
5F910164 - 0F84 0F31CD01 JE 615E3279
5F910166 0F31 RDTSC ; 再读 CPU 的xx counter, ==> EDX:EAX
5F910168 CD 01 INT 1 ; C0000005, eip+= 4
5F91016A 8DC0 LEA EAX,EAX ; Illegal use of register
5F91016C CC INT3 ; 80000003, eip++
5F91016D 0F0B UD2 ; C000001D, eip+= 2, set OF,TP
; 80000004, from 77F9FF64
5F91016F CE INTO ; C0000095, eip=eip
; 80000004, from 77F9FF64
5F910170 CC INT3 ; 80000003, eip++
5F910171 9C PUSHFD
5F910172 8DC0 LEA EAX,EAX ; 80000004, eip=eip
; C000001D, eip+=2, clear OF, TP
5F910174 CD 01 INT 1 ; C0000005, eip=0072B9E1
5F910176 CF IRETD ; 这一句没执行
最后的 Exception 使 eip = 0072B9E1,esp=[00B21B60], 还有花指令
0072B9DD 90 NOP
0072B9DE 90 NOP
0072B9DF 90 NOP
0072B9E0 E8 619DC37E CALL 7F365746
正确的应该是
0072B9E1 61 POPAD ; 这里才对应于 0072B651 的pushad
0072B9E2 9D POPFD ; 对应于 0072B650 的pushfd
0072B9E3 C3 RETN 再看一下与上面 Unhandled Exception 相关的 初始化部分:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072A8E0(U)
|
:0072BBC0 83EC0C sub esp, 0000000C
:0072BBC3 57 push edi
:0072BBC4 8B3D781BB200 mov edi, dword ptr [00B21B78]
:0072BBCA 6A01 push 00000001
:0072BBCC 68301BB200 push 00B21B30
:0072BBD1 897C2414 mov dword ptr [esp+14], edi
* Reference To: kernel32.InterlockedExchange, Ord:01D0h
|
:0072BBD5 FF15A49FA000 Call dword ptr [00A09FA4] ; 应该是读一 flag, 表示初始化或没有?
:0072BBDB 85C0 test eax, eax
:0072BBDD 0F852F040000 jne 0072C012
:0072BBE3 8B15341BB200 mov edx, dword ptr [00B21B34]
:0072BBE9 A1381BB200 mov eax, dword ptr [00B21B38]
:0072BBEE 55 push ebp
:0072BBEF 33ED xor ebp, ebp
:0072BBF1 42 inc edx
:0072BBF2 3BC5 cmp eax, ebp
:0072BBF4 56 push esi
:0072BBF5 8915341BB200 mov dword ptr [00B21B34], edx
:0072BBFB 750B jne 0072BC08
* Reference To: kernel32.GetTickCount, Ord:018Bh
|
:0072BBFD FF15A09FA000 Call dword ptr [00A09FA0]
:0072BC03 A3381BB200 mov dword ptr [00B21B38], eax ; 初始化 rand 的 seed
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BBFB(C)
|
:0072BC08 833D2C60AD00FF cmp dword ptr [00AD602C], FFFFFFFF
:0072BC0F 750F jne 0072BC20
:0072BC11 E8FAEFFFFF call 0072AC10
:0072BC16 A32C60AD00 mov dword ptr [00AD602C], eax
:0072BC1B A1381BB200 mov eax, dword ptr [00B21B38]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BC0F(C)
|
:0072BC20 392D401BB200 cmp dword ptr [00B21B40], ebp
:0072BC26 750A jne 0072BC32
:0072BC28 E823EFFFFF call 0072AB50
:0072BC2D A1381BB200 mov eax, dword ptr [00B21B38]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BC26(C)
|
:0072BC32 8A0D441BB200 mov cl, byte ptr [00B21B44]
:0072BC38 84C9 test cl, cl
:0072BC3A 7517 jne 0072BC53
:0072BC3C 68F817B200 push 00B217F8
* Reference To: kernel32.GetSystemInfo, Ord:0177h
|
:0072BC41 FF159C9FA000 Call dword ptr [00A09F9C] ; GetSystemInfo(), 下面用到
:0072BC47 A1381BB200 mov eax, dword ptr [00B21B38]
:0072BC4C C605441BB20001 mov byte ptr [00B21B44], 01
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BC3A(C)
|
:0072BC53 8A15341BB200 mov dl, byte ptr [00B21B34]
:0072BC59 F6C20E test dl, 0E
:0072BC5C 7555 jne 0072BCB3
:0072BC5E 8A0D441BB200 mov cl, byte ptr [00B21B44]
:0072BC64 84C9 test cl, cl
:0072BC66 744B je 0072BCB3
:0072BC68 8B0D4C1BB200 mov ecx, dword ptr [00B21B4C]
:0072BC6E 3BCD cmp ecx, ebp
:0072BC70 7408 je 0072BC7A
:0072BC72 392D581BB200 cmp dword ptr [00B21B58], ebp
:0072BC78 7539 jne 0072BCB3
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BC70(C)
|
:0072BC7A 80E201 and dl, 01
:0072BC7D 8854240F mov byte ptr [esp+0F], dl
:0072BC81 0F8471010000 je 0072BDF8
:0072BC87 3BCD cmp ecx, ebp
:0072BC89 7528 jne 0072BCB3
:0072BC8B 68F817B200 push 00B217F8
:0072BC90 68481BB200 push 00B21B48
:0072BC95 6880000000 push 00000080
:0072BC9A C605451BB20000 mov byte ptr [00B21B45], 00
:0072BCA1 E82AFEFFFF call 0072BAD0 ; 分配一段Memory,来放产生各种 Unhandled Exception 的 CODE,
起始地址 xxxx0000 中的 xxxx 是根据SystemInfo 随机生成, 每次运行都不一样, 而且一般都是 5xxx, 6xxx or 7xxxx,
跟系统 dll 中的地址混在一起, 在 OD 的 Memory Map 很容易被忽视掉. 刚开始的时候, 每次 exception 都在高地址空间,
我还总以为是哪个系统 dll 出问题了.
:0072BCA6 83C40C add esp, 0000000C
:0072BCA9 A34C1BB200 mov dword ptr [00B21B4C], eax ; 保存地址
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BE22(C)
|
:0072BCAE A1381BB200 mov eax, dword ptr [00B21B38]
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BC5C(C), :0072BC66(C), :0072BC78(C), :0072BC89(C), :0072BDFE(C)
|:0072BE5F(U)
|
:0072BCB3 392D4C1BB200 cmp dword ptr [00B21B4C], ebp
:0072BCB9 0F84EA010000 je 0072BEA9
:0072BCBF 8A0D451BB200 mov cl, byte ptr [00B21B45]
:0072BCC5 84C9 test cl, cl
:0072BCC7 0F85DC010000 jne 0072BEA9
:0072BCCD 8B15481BB200 mov edx, dword ptr [00B21B48]
:0072BCD3 33C9 xor ecx, ecx
:0072BCD5 3BD5 cmp edx, ebp
:0072BCD7 7637 jbe 0072BD10
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BD0E(C)
|
:0072BCD9 8D1440 lea edx, dword ptr [eax+2*eax]
:0072BCDC 83C104 add ecx, 00000004
:0072BCDF 8D1490 lea edx, dword ptr [eax+4*edx]
:0072BCE2 C1E204 shl edx, 04
:0072BCE5 03D0 add edx, eax
:0072BCE7 C1E208 shl edx, 08
:0072BCEA 2BD0 sub edx, eax
:0072BCEC 8D8490C39E2600 lea eax, dword ptr [eax+4*edx+00269EC3]
:0072BCF3 8B154C1BB200 mov edx, dword ptr [00B21B4C]
:0072BCF9 A3381BB200 mov dword ptr [00B21B38], eax
:0072BCFE 89440AFC mov dword ptr [edx+ecx-04], eax ; 将分配的 Memory 全填上随机数
:0072BD02 A1481BB200 mov eax, dword ptr [00B21B48]
:0072BD07 3BC8 cmp ecx, eax
:0072BD09 A1381BB200 mov eax, dword ptr [00B21B38]
:0072BD0E 72C9 jb 0072BCD9
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BCD7(C)
|
:0072BD10 392D2C60AD00 cmp dword ptr [00AD602C], ebp
:0072BD16 0F8586010000 jne 0072BEA2
:0072BD1C 8D0C40 lea ecx, dword ptr [eax+2*eax]
:0072BD1F 8B35B4A4A000 mov esi, dword ptr [00A0A4B4]
:0072BD25 53 push ebx
:0072BD26 BF04000000 mov edi, 00000004
:0072BD2B 8D1488 lea edx, dword ptr [eax+4*ecx]
:0072BD2E 8B0D481BB200 mov ecx, dword ptr [00B21B48] ; 分配的 size
:0072BD34 C1E204 shl edx, 04
:0072BD37 03D0 add edx, eax
:0072BD39 83C1BB add ecx, FFFFFFBB ; size - 0x45
:0072BD3C C1E208 shl edx, 08
:0072BD3F 2BD0 sub edx, eax
:0072BD41 8D8490C39E2600 lea eax, dword ptr [eax+4*edx+00269EC3]
:0072BD48 33D2 xor edx, edx
:0072BD4A A3381BB200 mov dword ptr [00B21B38], eax ; 随机数
:0072BD4F F7F1 div ecx ; rand() % (size - 0x45)
:0072BD51 A14C1BB200 mov eax, dword ptr [00B21B4C]
:0072BD56 8D4C0210 lea ecx, dword ptr [edx+eax+10] ; pStart + rand() % (size - 0x45) + 0x10
:0072BD5A 890D501BB200 mov dword ptr [00B21B50], ecx ; 代码起始地址pAddr, 随机的, 前面的 5F910152 就是这样来的
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BE97(C)
|
:0072BD60 B829000000 mov eax, 00000029 ; 下面一段解密一小段 CODE, 放到pAddr (也就是5F910152:-))
:0072BD65 2BC7 sub eax, edi
:0072BD67 83F804 cmp eax, 00000004
:0072BD6A 0F87F4000000 ja 0072BE64
:0072BD70 0F83EE000000 jnb 0072BE64
:0072BD76 33DB xor ebx, ebx
:0072BD78 33D2 xor edx, edx
:0072BD7A 3BC5 cmp eax, ebp
:0072BD7C 762E jbe 0072BDAC
:0072BD7E 8D0CC5F8FFFFFF lea ecx, dword ptr [8*eax+FFFFFFF8]
:0072BD85 894C2414 mov dword ptr [esp+14], ecx
...省略一些CODE
:0072BE91 83C704 add edi, 00000004
:0072BE94 83FF29 cmp edi, 00000029
:0072BE97 0F82C3FEFFFF jb 0072BD60
:0072BE9D 8B7C2418 mov edi, dword ptr [esp+18]
:0072BEA1 5B pop ebx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BD16(C)
|
:0072BEA2 C605451BB20001 mov byte ptr [00B21B45], 01 ; 解密结束
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BCB9(C), :0072BCC7(C)
|
:0072BEA9 A1341BB200 mov eax, dword ptr [00B21B34]
:0072BEAE 25FF010000 and eax, 000001FF
:0072BEB3 83F807 cmp eax, 00000007
:0072BEB6 751D jne 0072BED5
:0072BEB8 A0441BB200 mov al, byte ptr [00B21B44]
:0072BEBD 84C0 test al, al
:0072BEBF 7414 je 0072BED5
:0072BEC1 8B0D401BB200 mov ecx, dword ptr [00B21B40]
:0072BEC7 68F817B200 push 00B217F8
:0072BECC 51 push ecx
:0072BECD E8BEF2FFFF call 0072B190
:0072BED2 83C408 add esp, 00000008
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BEB6(C), :0072BEBF(C)
|
:0072BED5 8B15341BB200 mov edx, dword ptr [00B21B34]
:0072BEDB 81E2FF010000 and edx, 000001FF
:0072BEE1 81FA03010000 cmp edx, 00000103
:0072BEE7 7549 jne 0072BF32
:0072BEE9 F605781BB20004 test byte ptr [00B21B78], 04
:0072BEF0 7540 jne 0072BF32
:0072BEF2 892D681BB200 mov dword ptr [00B21B68], ebp
:0072BEF8 E863EEFFFF call 0072AD60
:0072BEFD 392D2C60AD00 cmp dword ptr [00AD602C], ebp
:0072BF03 7510 jne 0072BF15
:0072BF05 A1401BB200 mov eax, dword ptr [00B21B40]
:0072BF0A 50 push eax
:0072BF0B E850F0FFFF call 0072AF60
:0072BF10 83C404 add esp, 00000004
:0072BF13 EB05 jmp 0072BF1A
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BF03(C)
|
:0072BF15 E8A6F3FFFF call 0072B2C0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0072BF13(U)
|
:0072BF1A F705681BB200E0030000 test dword ptr [00B21B68], 000003E0
:0072BF24 740C je 0072BF32
:0072BF26 A1781BB200 mov eax, dword ptr [00B21B78]
:0072BF2B 0C04 or al, 04
:0072BF2D A3781BB200 mov dword ptr [00B21B78], eax
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0072BEE7(C), :0072BEF0(C), :0072BF24(C)
|
:0072BF32 A1341BB200 mov eax, dword ptr [00B21B34]
:0072BF37 B911000000 mov ecx, 00000011
:0072BF3C 99 cdq
:0072BF3D F7F9 idiv ecx
:0072BF3F 85D2 test edx, edx
:0072BF41 0F85BD000000 jne 0072C004
:0072BF47 392D4C1BB200 cmp dword ptr [00B21B4C], ebp
:0072BF4D 0F84B1000000 je 0072C004
:0072BF53 392D581BB200 cmp dword ptr [00B21B58], ebp
:0072BF59 0F84A5000000 je 0072C004
:0072BF5F A12C60AD00 mov eax, dword ptr [00AD602C]
:0072BF64 892D701BB200 mov dword ptr [00B21B70], ebp
:0072BF6A 3BC5 cmp eax, ebp
:0072BF6C 892D741BB200 mov dword ptr [00B21B74], ebp
:0072BF72 892D681BB200 mov dword ptr [00B21B68], ebp
:0072BF78 892D6C1BB200 mov dword ptr [00B21B6C], ebp
:0072BF7E 892DE817B200 mov dword ptr [00B217E8], ebp
:0072BF84 892D641BB200 mov dword ptr [00B21B64], ebp
:0072BF8A 7505 jne 0072BF91
:0072BF8C E85FFAFFFF call 0072B9F0 ; 这儿开始干坏事, 前面已经分析过了. 没了, 好累!!!
[注意]APP应用上架合规检测服务,协助应用顺利上架!