📜 ⬆️ ⬇️

How to make a Laser Squad from XCOM: etude for GDB in OSX

image

This is how the Laser Squad game now looks like, which I saw a long time ago. Then it was simpler in every sense and looked like this:

image
')
At the same time, fundamentally the game has not changed. It just got harder: a bunch of types of resources, a lot of options for their use, plus “inflation”: each next workshop, laboratory or satellite channel costs more than the previous ones. On the one hand, all this makes it possible to play with different development strategies, but sometimes you just want to play just Laser Squad! Therefore…

So I went to the App Store and bought XCOM for some $ 29. The hack method of resources in games has not changed since the advent of the First Save: save, change the amount of the target resource, save again, run the hex editor, find the place where the first control value has changed to the second control value, write there a significant integer (which something like 0x7FFF) - and enjoy the dramatically simplified gameplay.

But here I was waiting for a bummer. Even two: first, successively saved files differed in size. Secondly, in the part of the file that referred to the conditional header, the corresponding values ​​were, but changing them resulted in XCOM complaining about the broken files: obviously, the format provides for some checksums that do not match after such a rough making changes.

Well then. So, it’s time to take the debugger in your hands: it’s impossible to edit the files, then we’ll edit the memory immediately. Here the method is slightly different:

  1. launched the game;
  2. clung to the debugger;
  3. looked at the amount of the target resource;
  4. found a set of addresses in the process memory with this value and saved it;
  5. changed the amount of the target resource;
  6. found a new set of addresses in memory and crossed (set intersection) with the previous one;
  7. repeated paragraphs. 5 and 6 is not yet a single address;
  8. recorded at this address the desired amount of the target resource.

But there are difficulties. The first is that, in the general case, the virtual memory of the process in all modern operating systems is not continuous, and it is too long to go through the whole space of possible addresses. Fortunately, OS X has a wonderful vmmap junk that, at the output, gives a detailed process memory card in the form:
% vmmap 15552
...
shared memory 3afff000-3b000000 [4K] rw- / rw- SM = SHM
MALLOC_SMALL 3b000000-3b800000 [8192K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
MALLOC_LARGE 3b800000-3b84c000 [304K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
shared memory 3b84c000-3b854000 [32K] rw- / rw- SM = SHM
IOKit 3b85d000-3b866000 [36K] rw- / rw- SM = ALI
MALLOC_LARGE 3b866000-3b891000 [172K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
shared memory 3b891000-3b899000 [32K] rw- / rw- SM = SHM
MALLOC_LARGE 3b8a2000-3b8ee000 [304K] rw- / rwx SM = PRV DefaultMallocZone_0x4816000
...


The second difficulty is that there can be a lot of such memory segments as in the example above. For example, in my case there were more than two and a half thousand of them, so manually scanning them all will not work.

From the point of view of the task and the current difficulties, GDB is perfect: it is scripted This means that it can be run in batch mode and fed to it lists of commands either from a file or from the command line.

In general, two things are done with GDB: finding the address (s), and writing down the desired value at a given address. Finding addresses of a desired value is done in GDB by the find command (surprise!). For one of the above ranges and the value 100 the command will look like this: find / w 0x3b800000, 0x3b84c000 100 . If the address we need is 0x3b800004, then the command to write the value 200 to this address will be: set {int} 0x3b800000 = 200 .

In theory, everything is transparent. But already on trying to join the process, I had another bummer: GDB received head-on segfault and fell into the crust. I checked the rights: the id of the effective user for the debugger and the game are the same - mine. I tried to join the top, launched in the next shell - it turned out only from the root. Joining the XCOM process, even from the root - does not work, segfault ...

Further investigation clarified two things:



Lyrical digression: various malicious programs try to either not have their own separate process, or disguise themselves as a system, or hide their process. The first two approaches boil down to the possibility of “jumping up” into the process of an honest program and further creating dark things on its good name. The third usually requires "jumping" into the kernel of the operating system. So, in OS X, I even succeeded in joining a neighboring process running with my rights, after I read the article in which this process is described in detail. In short, when calling certain APIs, the kernel first makes sure that the code that made this call is signed with the proper certificate. Therefore, in order for our approach to work, it is necessary:

  1. create a local self-signed certificate to sign the code with the highest level of trust;
  2. put a new GDB;
  3. sign the gdb executable file with the newly created certificate.


In case I wanted to get away from using gdb and write to the XCOM address space from my process, I would need an additional Info.plist, which I need to compile into the executable file. For a detailed description of the approach I send to the article , from which I learned all this mechanics. Another good article, in which the mechanics of code signing and right-cutting the process is well written, lies right on Habré .

After all these dance steps, GDB was finally able to join the game process and I was able to test the search manually. Since there was a lot of data (lists of even several dozens of addresses can be tiring if compared with their eyes), a binding was written over vmmap and GDB, which automated the process of searching and editing values ​​in memory.

I'm still not sure from what more satisfaction was obtained: from playing the good old Laser Squad or from the process of turning XCOM into it.

Source: https://habr.com/ru/post/255787/


All Articles