[Share/Tutorial] TRose.exe v149 without gameguard

On miércoles, 29 de diciembre de 2010 0 comentarios

Hi again, seems like new clients appears more offen than i visit the toilet these days.
So i'll write a complete guide and share my latest TRose.exe v149 without gameguard.

I thought i'd do a better release this time around, last time was a real patchjob.
Firstly, what you need todo this time, is to remove gameguard from ever loading.
For you who know programming, you use CreateProcessA to make a new application appear from your own application. This is also possible in Delphi with ShellExecute or the normal WinAPI Run.

Which case, what we want todo this time around is to make gameguard not to load.
And then remove the check which will check if gameguard has been loaded.
Because normally, if gameguard has not been loaded, TRose.exe will close.

Removing gameguard.des from loading:

You want to find this line:

  1. .text:0058F90E                 test    eax, eax        ; Logical Compare
  2. .text:0058F910                 jle     short loc_58F93C ; Jump if Less or Equal
  3. .text:0058F912                 mov     edi, [esp+30h+Buffer]
  4. .text:0058F916                 mov     [esp+30h+var_14], eax
  5.  

and change it to
  1. .text:0058F90E                 test    eax, eax        ; Logical Compare
  2. .text:0058F910                 jge     short loc_58F93C ; Jump if Greater or Equal
  3. .text:0058F912                 mov     edi, [esp+30h+Buffer]
  4. .text:0058F916                 mov     [esp+30h+var_14], eax
  5.  


Why, am i doing this?

Because at the address 0058F93C the coding for launching gameguard.des exists.
We do not want that to load. The value being compared, is always less than the the compare value.
Hence it will jump when the value is less or equal than the eax-value.
AHA! So that means if we change it to jump if greater or equal, the jump will never take place right?
Thats totaly correct. The value will never be greater than the value compared, and when we change jle to jge, the jump will never be made. Cool huh?
This is how the CreateProcessA code-section looks like:

  1. .text:0058F93C loc_58F93C:                             ; CODE XREF: sub_58EDC0+B50 j
  2. .text:0058F93C                 lea     ecx, [esp+30h+CommandLine] ; Load Effective Address
  3. .text:0058F943                 mov     byte ptr [esi], 0
  4. .text:0058F946                 push    ecx             ; int
  5. .text:0058F947                 push    offset dword_6BE460 ; int
  6. .text:0058F94C                 push    ebp             ; NumberOfBytesWritten
  7. .text:0058F94D                 call    sub_5907D0      ; Call Procedure
  8. .text:0058F952                 add     esp, 0Ch        ; Add
  9. .text:0058F955                 lea     edx, [esp+30h+hThread] ; Load Effective Address
  10. .text:0058F959                 lea     eax, [esp+30h+StartupInfo] ; Load Effective Address
  11. .text:0058F95D                 lea     ecx, [esp+30h+CommandLine] ; Load Effective Address
  12. .text:0058F964                 push    edx             ; lpProcessInformation
  13. .text:0058F965                 push    eax             ; lpStartupInfo
  14. .text:0058F966                 push    0               ; lpCurrentDirectory
  15. .text:0058F968                 push    0               ; lpEnvironment
  16. .text:0058F96A                 push    0               ; dwCreationFlags
  17. .text:0058F96C                 push    1               ; bInheritHandles
  18. .text:0058F96E                 push    0               ; lpThreadAttributes
  19. .text:0058F970                 push    0               ; lpProcessAttributes
  20. .text:0058F972                 lea     edx, [esp+50h+Filename] ; Load Effective Address
  21. .text:0058F979                 push    ecx             ; lpCommandLine
  22. .text:0058F97A                 push    edx             ; lpApplicationName
  23. .text:0058F97B                 call    ds:CreateProcessA ; Indirect Call Near Procedure
  24. .text:0058F981                 test    eax, eax        ; Logical Compare
  25. .text:0058F983                 jnz     short loc_58F9C5 ; Jump if Not Zero (ZF=0)
  26. .text:0058F985                 lea     eax, [esp+30h+String] ; Load Effective Address
  27. .text:0058F98C                 push    eax             ; int
  28. .text:0058F98D                 call    ds:GetLastError ; Indirect Call Near Procedure
  29. .text:0058F993                 lea     ecx, [esp+34h+Filename] ; Load Effective Address
  30. .text:0058F99A                 push    eax             ; int
  31. .text:0058F99B                 push    ecx             ; int
  32. .text:0058F99C                 push    offset dword_6BE438
  33. .text:0058F9A1                 call    sub_596250      ; Call Procedure
  34. .text:0058F9A6                 add     esp, 4          ; Add
  35. .text:0058F9A9                 push    eax             ; int
  36. .text:0058F9AA                 push    ebp             ; NumberOfBytesWritten
  37. .text:0058F9AB                 call    sub_5907D0      ; Call Procedure
  38. .text:0058F9B0                 add     esp, 14h        ; Add
  39. .text:0058F9B3                 mov     eax, 0AAh
  40. .text:0058F9B8                 pop     edi
  41. .text:0058F9B9                 pop     esi
  42. .text:0058F9BA                 pop     ebp
  43. .text:0058F9BB                 pop     ebx
  44. .text:0058F9BC                 add     esp, 10B4h      ; Add
  45. .text:0058F9C2                 retn    4               ; int
  46.  


Removing the gameguard.des check:

You want to find this line:
  1. .text:005331D9                 cmp     ds:dword_6D4CDC, 1 ; Compare Two Operands
  2. .text:005331E0                 jnz     short loc_5331E7 ; Jump if Not Zero
  3. .text:005331E2                 call    sub_539B48      ; Call Procedure
  4. .text:0053320C
  5. .text:0053320C loc_53320C:                             ; CODE XREF: .text:00533205 j
  6. .text:0053320C                 push    dword ptr [esp+4]
  7. .text:00533210                 call    sub_5399A7      ; Call Procedure
  8. .text:00533215                 push    0FFh
  9. .text:0053321A                 call    sub_535605      ; Call Procedure
  10.  

and change it to
  1. .text:005331D9                 cmp     ds:dword_6D4CDC, 1 ; Compare Two Operands
  2. .text:00533205                 jz     short loc_53320C ; Jump if Zero
  3. .text:005331E2                 call    sub_539B48      ; Call Procedure
  4. .text:0053320C
  5. .text:0053320C loc_53320C:                             ; CODE XREF: .text:00533205 j
  6. .text:0053320C                 push    dword ptr [esp+4]
  7. .text:00533210                 call    sub_5399A7      ; Call Procedure
  8. .text:00533215                 push    0FFh
  9. .text:0053321A                 call    sub_535605      ; Call Procedure
  10.  


Why, am i doing this?
Well simply put. At call sub_535605 it jumps to ExitProcess. We do not want the process to Exit.
Hence we change the code never to get to the place where the call is made.
Meaning this place:
  1. .text:005331D9                 cmp     ds:dword_6D4CDC, 1 ; Compare Two Operands
  2. text:00533205                 jnz     short loc_53320C ; Jump if Not Zero


If it turns out that the compare equals 1 it will jump and exit the process.
We just change the jnz to jz because we know, it always will be 1.
And when Jump Zero never gets a 0 compare value, the jump never will be made.

You could of course also change the cmp ds:dword_6D4CDC, 1 ; to cmp ds:dword_6D4CDC, 0 ;
I just changed the actual jump because, that's what i felt like :P

Removing the check for which controls if gameguard.des exists

We'll probably have to remove the check, which controls if gameguard.dex exists right?
Along with all those other weird checks which will appear when something is wrong with gameguard.

Find: jz short loc_52F507
  1. .text:0052F4E7                 cmp     edx, ds:dword_67CEE8 ; Compare Two Operands
  2. .text:0052F4ED                 jz      short loc_52F507 ; Jump if Zero
  3. .text:0052F4EF                 mov     [ebx+4], esi
  4. .text:0052F4F2                 mov     eax, esi
  5.  

replace with:
  1. .text:0052F4E7                 cmp     edx, ds:dword_67CEE8 ; Compare Two Operands
  2. .text:0052F4ED                 jnz      short loc_52F507 ; Jump if Not Zero
  3. .text:0052F4EF                 mov     [ebx+4], esi
  4. .text:0052F4F2                 mov     eax, esi
  5.  


Here you once again just change the jump offset never to take place.
dword_67CEE8 holds the value 755h(Something you recognize perhaps?)
Yes thats the Gameguard Is Valid number. Edx in the compare function does in this case hold 262
which is the not valid number in Gameguard. Meaning, in this case edx since we do not have gameguard, edx will get loaded with 262. And when it does a compare with 755 it will notice they are not the same and flag us with diffrent warning messages. Since the value is not the same, the result will be 0, and JZ (Jump if Zero) will take place. We simply change the Jump to jump if not zero
meaning the jump will never take place since it will always be Zero.

You could use JE(Jump Equal) but the result will be the same.
You could also change cmp edx, ds:dword_67CEE8
to cmp edx, 262h instead. Because then, it would also make sure the jump is never taken.

But, how do i change?
Either you use OllyDBG, or a hex editor.
Im quite sure some of you will have no clue still what im talking about.
It will require some minior hexing knowledge.
And if you use Ollydbg you can simple use the Menu alternative: Assemble
to rewrite the new function.

And from Olly save the changes directly.


Enjoy!

Nevyn

0 comentarios:

Publicar un comentario