Difference between revisions of "Example 8"

From SkullSecurity
Jump to navigation Jump to search
Line 1: Line 1:
{{Construction}}
{{Infobox assembly}}
{{Infobox assembly}}
[[Category: Assembly Examples]]
[[Category: Assembly Examples]]

Revision as of 14:26, 23 March 2007

Assembly Language Tutorial
Please choose a tutorial page:

This is going to be a fairly short tutorial, but it will explain how to grab The IX86...dll files used by Starcraft (and other games) to perform version checking. This will be done on the latest version of Starcraft, since it's the only one that can authenticate to the server.

The most common way to get the files is by downloading them directly from the Battle.net FTP server, but that involves either an external program or reverse engineering. This method will let the game download them for us!

Finding the Deletion

First, load battle.snp in IDA. battle.snp is the library that takes care of battle.net connectivity. Click on the "Names" window and search for "LoadLibraryA". Double-click it, the press ctrl-x to view cross references.

Go through each of the cross references and look for one that loads a variable dll name.

I found the proper one on the fifth cross reference. The code is pretty obvious (although IDA makes some mistakes in this function, we'll talk about that at another time):

.text:19021A02                 push    edx             ; lpLibFileName
.text:19021A03                 call    ds:LoadLibraryA
.text:19021A09                 mov     esi, eax
.text:19021A0B                 cmp     esi, ebx
.text:19021A0D                 mov     [ebp+hLibModule], esi
.text:19021A10                 jz      loc_19021AEE
.text:19021A16                 push    offset aCheckrevision ; "CheckRevision"
.text:19021A1B                 push    esi             ; hModule
.text:19021A1C                 call    ds:GetProcAddress

A variable library is loaded (edx), then the address for a function called CheckRevision is found.

So at this point, the physical file exists. One option is to load this into a debugger and break here, then make a copy of the .dll. But that's no fun, I'd prefer to stop it from being deleted altogether!

Scroll down for awhile, and eventually you'll see this: .text:19021AFB push 32h  ; dwMilliseconds .text:19021AFD call ds:Sleep .text:19021B03 mov esi, ds:DeleteFileA .text:19021B09 push offset byte_1903C108 ; lpFileName .text:19021B0E call esi ; DeleteFileA .text:19021B10 cmp [ebp+NumberOfBytesWritten], bl .text:19021B16 jz short loc_19021B21 .text:19021B18 lea ecx, [ebp+NumberOfBytesWritten] .text:19021B1E push ecx  ; lpFileName .text:19021B1F call esi ; DeleteFileA

Two files are being deleted here. Presumably, one of them is the .mpq and the other is the .dll. We're going to want to skip over both of those calls.

So here's what we have to do:

  • Remove those calls (including the push, otherwise the stack will break)
  • Connect to Battle.net

Removing the Calls

Run Starcraft, and open it in a debugger (I've found that TSearch can't find this version of Starcraft in memory). Search for the address 0x19021b09.

Not there? Uh oh!

The problem we've run into is that battle.snp isn't loaded until Starcraft connects to Battle.net. Loading it with the "Injector" program doesn't even work -- Blizzard's tried hard to break hacks!

But that's fine, we can go one step further and just disable DeleteFileA altogether. It's not like Starcraft really needs to be deleting my files anyways!

Ensuring the game's execution is stopped, go to the disassembly window on your debugger and type "DeleteFileA". It should show you a kernel32 function. Open the memory window and do the same. In the memory window, replace the first three bytes with C2 04 00 (which is "ret 4"). Add 90's to pad it if you end up with weird instructions, although it doesn't really matter.

Once the DeleteFileA call has been removed, go back to the game, and log into Battle.net. The login should succeed (since our patch wasn't in any of the actual Starcraft files). Alt-tab and go into Starcraft's folder. The .mpq and .dll file should be there!

In theory, it's possible to force Starcraft to download the .dll file of your choice, by editing incoming traffic or getting a breakpoint in Battle.snp, but just connecting to Battle.net until you have them all is probably the easiest way.

Removing Protection

I was disassembling Starcraft.exe for the purposes of demonstration. While waiting, I figured I'd check out the main function:

.text:004DF940                   ; int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
.text:004DF940                   _WinMain@16:                            ; CODE XREF: start+17F�p
.text:004DF940 55                                push    ebp
.text:004DF941 8B EC                             mov     ebp, esp
.text:004DF943 56                                push    esi
.text:004DF944 8B 75 08                          mov     esi, [ebp+8]
.text:004DF947 89 35 8C AF 51 00                 mov     dword_51AF8C, esi
.text:004DF94D E8 3E 00 FF FF                    call    sub_4CF990
.text:004DF952 FF 15 F8 D1 4F 00                 call    ds:GetCurrentThreadId
.text:004DF958 68 AC E8 4F 00                    push    offset aSwarclass ; "SWarClass"
.text:004DF95D A3 B8 B9 6C 00                    mov     dword_6CB9B8, eax
.text:004DF962 E8 A9 F8 FF FF                    call    sub_4DF210
.text:004DF967 E8 C4 9E FF FF                    call    sub_4D9830
.text:004DF96C E8 5F F9 FF FF                    call    sub_4DF2D0
.text:004DF971 E8 0A D6 00 00                    call    sub_4ECF80
.text:004DF976 E8 15 F7 FF FF                    call    sub_4DF090
.text:004DF97B E8 30 FD FF FF                    call    loc_4DF6B0

I thought I'd kill time by checking what each of those calls do. The first few are boring, they make sure you can't run more than one Starcraft, and they check system requirements, and other boring stuff.

When I got to checking sub_4DF090, however, my interest was piqued. It was a bunch of different ACL (access control list) functions, and setting authorizations, culminating in a call to SetSecurityInfo! So I had a hunch, and disabled SetSecurityInfo:

  • Run Starcraft through a debugger (you have to do this before Starcraft loads)
  • Search for the function "advapi32!SetSecurityInfo"
  • Disable it by setting the first three bytes to "c2 1c 00" (you can find the number of bytes to pop, 0x1c, by scrolling to the bottom of the function)
  • "Run" the program, and test it. TSearch can now find/modify data, and you can still log onto Battle.net!

Presumably, a loader could take care of this in an automated fashion, but I'm not sure how I would go about writing one.