Results 1 to 10 of 16

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    Forsaken World client analyzing, debugging, protection

    Let’s play with Forsaken World.

    Some lyrics before we start. When the FW became available I and other people noticed that this client is different than Perfect World. What exactly? Improved protection and tricky anti-debug technique: hooked API, encrypted files etc. OllyDbg will crash or client goes into infinity loop… Sweet.
    This is a draft, smattering explanation with some notes regarding FW protection and anti-debug techniques.

    Ok. At the beginning we should check our “minefield” with pogo stick…
    1. We start Ollydbg and run FW client. FW freezes
    2. We start client, run olly and attach debugger to the client… my olly 2 crashed with lots of exceptions; olly 1.10 with Strong plugin stopped here
     0D650000   /EB 10              jmp     short 0D650012
    0D650002 |6A 00 push 0x0
    0D650004 |6A FE push -0x2
    0D650006 |FF15 0E00650D call dword ptr [0xD65000E] ; ntdll.RtlExitUserThread
    0D65000C ^|EB F4 jmp short 0D650002
    0D65000E |9B wait
    0D65000F |14 96 adc al, 0x96
    0D650011 |7C 68 jl short 0D65007B
    0D650013 2000 and byte ptr [eax], al
    0D650015 65:0D 33C064FF or eax, 0xFF64C033
    0D65001B 306489 20 xor byte ptr [ecx+ecx*4+0x20], ah
    0D65001F CC int3
    => 0D650020 90 nop
    0D650021 ^ EB DF jmp short 0D650002


    3. Now we will load game.exe under clean ollydbg and execute it… and will receive message box with some, as I think, good words about our try. Reload game.exe
     00DC4325  /> \C645 C8 01        MOV BYTE PTR SS:[EBP-38],1
    00DC4329 |. C745 FC 00000000 MOV DWORD PTR SS:[EBP-4],0
    => 00DC4330 |. CD 2D INT 2D
    00DC4332 |. 33C0 XOR EAX,EAX
    00DC4334 |. 83C0 02 ADD EAX,2
    00DC4337 |. C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-4],-1
    00DC433E \. EB 14 JMP SHORT 00DC4354
    00DC4340 /. B8 01000000 MOV EAX,1
    00DC4345 \. C3 RETN
    00DC4346 /. 8B65 E8 MOV ESP,DWORD PTR SS:[EBP-18]
    00DC4349 |. C645 C8 00 MOV BYTE PTR SS:[EBP-38],0
    00DC434D |. C745 FC FFFFFFFF MOV DWORD PTR SS:[EBP-4],-1
    00DC4354 |> 8B45 C8 MOV EAX,DWORD PTR SS:[EBP-38]
    00DC4357 |. 25 FF000000 AND EAX,000000FF
    00DC435C |. 85C0 TEST EAX,EAX
    00DC435E |. 74 03 JE SHORT 00DC4363
    00DC4360 |. 58 POP EAX
    00DC4361 |. 5A POP EDX
    00DC4362 |. 5E POP ESI
    00DC4363 |> 833D 10CD0901 00 CMP DWORD PTR DS:[109CD10],0
    00DC436A |. 75 3F JNE SHORT 00DC43AB
    => 00DC436C |. FF15 00D0FC00 CALL DWORD PTR DS:[<&KERNEL32.IsDebuggerPresent>] ; [KERNEL32.IsDebuggerPresent
    00DC4372 |. 85C0 TEST EAX,EAX
    00DC4374 |. 75 1C JNE SHORT 00DC4392
    00DC4376 |. E8 D52D0000 CALL 00DC7150
    00DC437B |. 25 FF000000 AND EAX,000000FF
    00DC4380 |. 85C0 TEST EAX,EAX
    00DC4382 |. 75 0E JNE SHORT 00DC4392
    00DC4384 |. E8 472E0000 CALL 00DC71D0
    00DC4389 |. 25 FF000000 AND EAX,000000FF
    00DC438E |. 85C0 TEST EAX,EAX
    00DC4390 |. 74 19 JE SHORT 00DC43AB
    00DC4392 |> 6A 00 PUSH 0
    00DC4394 |. 68 2C610C01 PUSH 010C612C
    00DC4399 |. 68 08610C01 PUSH 010C6108
    00DC439E |. 6A 00 PUSH 0
    our message box => 00DC43A0 |. FF15 48D1FC00 CALL DWORD PTR DS:[<&USER32.MessageBoxA>] 00DC43A6 |. E9 B82C0000 JMP 00DC7063


    You can bypass IsDebuggerPresent and INT 2D;
    Some words about INT 2D: this instruction can be used as a general purpose debugger detection method, because when executing the instruction, if no debugger is present, an exception will occur. However, if a debugger is present, no exception will occur, and things get interesting based on the debugger you are using. OllyDbg will actually skip a byte in its disassembly and will cause the analysis to go wrong.

    you can nop some JNE and make JMP on 00DC4390
    00DC4372  |.  85C0              TEST EAX,EAX
    00DC4374 90 NOP
    00DC4375 90 NOP
    00DC4376 |. E8 D52D0000 CALL 00DC7150
    00DC437B |. 25 FF000000 AND EAX,000000FF
    00DC4380 |. 85C0 TEST EAX,EAX
    00DC4382 90 NOP
    00DC4383 90 NOP
    00DC4384 |. E8 472E0000 CALL 00DC71D0
    00DC4389 |. 25 FF000000 AND EAX,000000FF
    00DC438E |. 85C0 TEST EAX,EAX
    00DC4390 EB 19 JMP SHORT 00DC43AB


    Actually, this isn’t interesting or useful When we run game.exe, it recreates itself as a child process and Finita la comedia. If we trace execution routine, after long-long decryption cycles and memory copying parts, we will get
     00DC6E04    E8 57C4FFFF         call    00DC3260
    00DC6E09 83C4 04 add esp, 0x4
    00DC6E0C 8B15 04EC0F01 mov edx, dword ptr [0x10FEC04]
    00DC6E12 52 push edx
    00DC6E13 A1 B00B0901 mov eax, dword ptr [0x1090BB0]
    00DC6E18 05 BC3B0000 add eax, 0x3BBC
    => 00DC6E1D FFD0 call eax ; proccess already created
    00DC6E1F 8D4D 84 lea ecx, dword ptr [ebp-0x7C]
    00DC6E22 51 push ecx
    00DC6E23 6A 00 push 0x0
    00DC6E25 8B15 14E00801 mov edx, dword ptr [0x108E014]
    00DC6E2B 52 push edx
    00DC6E2C 68 103FDD00 push 00DD3F10

    At this moment child game.exe process is already created and suspended. And now what? Nothing, it was a long prelude…

    How to bypass anti-debugger (anti-attach) protection and how does it works when debugger attaching to the debugee? Anytime a debugger is attaching itself to an aim process (debugee), system creates a new thread, which starts at DbgUiRemoteBreakin (ntdll!DbgUiRemoteBreakin) function in debugee's process space.
    When the process is about to be debugged, ntdll!DbgUiDebugActiveProcess calls ntdll!DbgUiIssueRemoteBreakin and this one creates a thread that starts at ntdll!DbgUiRemoteBreakin. The new thread is created via a call to ntdll!RtlCreateUserThread. When started, ntdll!DbgUiRemoteBreakin calls ntdll!DbgBreakPoint which is actually just a pair of 2 instructions: int3 and ret.
    So, if application hooks the entry point of the function, it can control the flow of the code being executed…

    Let’s approve our statement about hooked DbgUiRemoteBreakin by Forsaken World client.
     7C94FFE3 >  C2 0C00         retn    0xC
    7C94FFE6 F8 clc
    7C94FFE7 0095 7CE8BCE8 add byte ptr [ebp-0x17431784], dl
    7C94FFED FB sti
    7C94FFEE FF64A1 18 jmp dword ptr [ecx+0x18]
    7C94FFF2 0000 add byte ptr [eax], al
    7C94FFF4 008B 40308078 add byte ptr [ebx+0x78803040], cl
    7C94FFFA 0200 add al, byte ptr [eax]
    7C94FFFC 75 09 jnz short 7C950007
    7C94FFFE F605 D402FE7F 0>test byte ptr [0x7FFE02D4], 0x2
    7C950005 74 20 je short 7C950027
    7C950007 8365 FC 00 and dword ptr [ebp-0x4], 0x0
    7C95000B E8 FE11FBFF call DbgBreakPoint
    7C950010 EB 11 jmp short 7C950023

    Yeah, instead
     7C94FFE3 >  6A 08           push    0x8
    7C94FFE5 68 3000957C push 7C950030
    7C94FFEA E8 BCE8FBFF call 7C90E8AB

    we have retn 0xC. Restoring DbgUiRemoteBreakin will give you opportunity to attach debuggers... but this is only one small part of FW protection


    How to open FW client under debugger with hooked DbgUiRemoteBreakin…
    Let’s debug the debugger… soon (maybe)


    Note: If I forgot something, or if someone wants something to add, you are welcome
    Note: Any materials only for educational purpose
    by Dwar
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •