Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

A little more RE

I've been holding onto a file for almost a decade now. To be exact, very late 2010, maybe early 2011. We're soon approaching a full nine years, and I've been holding onto this file essentially since I was a dumb kid in the hopes that one day I'll be able to do something with it.

The file doesn't even technically work. It's a trainer for Call of Duty: Black Ops which was made shortly after the game came out (only allegedly worked for Campaign/Solo zombies) and was shortly patched thereafter. Sure, it looked sort of cool, design-wise:
[Image: 1f0f862259d53fadca7c9eb0b674aaa8.png]

But otherwise, it was patched, and thus, did not even work.
I kept this file throughout the years for one reason alone: to figure out how to extract the music file.

I cannot find this version of the song anywhere online, since lots of demoscene music generally is pretty obscure (think of late 90s/early 00s chiptune in trainers/keygens) and even the song itself is relatively obscure: The NeverEnding Story by Limahl (the theme to the movie.)

So over the years, as I'd learn more about programming or general computer science, I'd think of ways that maybe I could use something to help me figure out how to take this program apart, and hopefully something will finally make the dent I needed.

Now, LinGon is long gone, can't find any new handle and his social media/old accounts haven't been touched since like 2013 at latest. So asking him for help would have been out of the question.

The file in question is here, for anyone's will to follow along with the process:

Before you ever run a program on your computer, especially something that can be considered a hack tool, you should scan it with VirusTotal or something. For me, as a hobbyist, I've found that tons of samples will come back infected despite being clean because of strange function calls, and that it's also incredibly easy to make a sample that doesn't get detected. Weird world, so instead of trusting the results of a bunch of AVs, I use HybridAnalysis to get clues about what the program does, then I make the decision of actually running/debugging the program myself.

At the time of playing CoD:BO, I was running Windows 7 in those days, and I only had 4GB of RAM so I figured using the 32bit options on HA would be fine to test. After all, I'm not looking for detections, I'm looking for clues.
[Image: ec81fcfd874435088221e4f95a624917.png]

Unfortunately, HA thinks the file is malicious:

Because allegedly it reads 'terminal service related keys'
And apparently RDP programs do that.
You know what else does that?
Trainers (and game-hacking tools.)
Because you need to get around anticheat somehow, buddy.

This was the only mainly concerning aspect of the analysis done, and it's easily explained. There's no web-traffic or any networking whatsoever (it doesn't even import the necessary networking libraries) so it's unlikely anything malicious is going on. 

There were a few things that stood out to me from the analysis though:
Written/Compiled with VisualBasic 6.0
Packed with PECompact
Barely any discernable strings (reinforces the packed idea)
Strange API imports (likely due to the packing)
No files extracted

VisualBasic means that maybe we can do some dotnet RE which would make life easier.
PECompact gives us at least the name of what we're looking for when we want to unpack it.
No files means that the resources section of the file is also packed. I was hoping to maybe get an MP3 from this, but I suppose not.

Since it's allegedly written in VB6, we should try to decompile to VB6 (even if it's undiscernable initially,) so I plugged the file into dotPeek, a free .Net decompiler. It works on .exes, .dlls, or any binary for that matter as long as it's written in a .NET language, like VB.
[Image: 0bc1d942a3874607eceb361ca308977f.png]
No go.
Guess not.

So now, we need to bring out the big guns. A real debugger, since although it's importing all the .Net stuff, it's hidden so there's probably lots of native code surrounding it.
Enter x64dbg (or x32dbg in my case.)

x64dbg (known as xdbg from here-on-in) is essentially the spiritual successor to the world-famous OllyDBG, except that Olly has way less features and doesn't work for 64bit binaries, making it a little too useless in the modern-day. xdbg also supports 32bit binaries, and is entirely free, making it a great choice for us right now.

So I downloaded the binaries, started up x32dbg (the 32bit version obviously,) and plugged in the Trainer file I've been saving for today.
[Image: db463ba19d642e76d94d979a194cc42a.png]
And it seems to work fine. It hits a system breakpoint and stops execution, allowing me to start poking around.
First, to understand most packing schemes, there's very little you need to know. Most packing/obfuscation schemes operate sort of similar to this pseudo-ASM code:

0x401000 ---- jmp 0x601000 ;entry point of the binary, jumps to arbitrary location, assume this instruction is 5 bytes
0x401005 ---- ;garbled nonsense spanning the majority of the file
0x601000 ---- call decryptGarbled ;decryption function for the above garbled mess
0x601004 ---- add ebp,5 ;adjust execution stack pointer by 5 bytes, ie. makes 0x401000 into 0x401005, changing the base
0x601010 ---- jmp [0x0] ;starts execution from where the garbled was, now decrypted code.

So realistically, we just need to follow the trail.
First, in xdbg, we need to find that entry point for the program (currently the breakpoint is highlighted, also in a different section than the program itself, so we need to poke around more. The logs show us something interesting:
[Image: 40a9a0a007799c1f3232ee8355967e20.png]

And there it is, also neatly hyperlinked for our convenience!
Clicking it starts off our journey:
[Image: 50638429cf8b9831728a73218a813a06.png]

And just our luck, there's a new address being pushed into the accumulator.
First, I'll assemble that one instruction and note it down in case I need the value later:
mov eax, 0x8E42B0
Let's see where that takes us:
[Image: 0d92e39018722baa3b921cb4c5b332bf.png]

So this time, an integer (32bit) is being pushed into the accumulator. Nothing really to follow here, especially when there's a ret instruction shortly after, so we need to actually think back to the explanation I gave earlier of how packers work.
They jump around, decrypt, then jump around again. It looks like the accumulator is also being used as 'storage' for where the instruction pointer should jump around to, so let's see what returns when I search for:
jmp eax
[Image: c0501a1d2a5b9f7164a1128ede560eb8.png]
[Image: 6f301682502925c912054dcee67ce359.png]

Two results only. That narrows it down quite a bit.
Now let's go back to our noted down asm instruction:
mov eax, 0x8E42B0

0x8E42B0 is much bigger than 0x8DFB5B, so that probably won't be it.
Instead, I'll attach a breakpoint to the second option, since it does come after where we just were.
And now, all that's left to do is hit the 'Run' button at the top.

You see, although we're in this weird disassembly mode, we're not trying to get a disassembled raw source; we're looking for the original source. At some point in this program's execution, that original source will be visible, even for an instant, because the program needs to decrypt it first then start execution. So we let the program handle the heavy-lifting and reap the rewards, hence we just start running it.

So hit run/step a few times until we get to the jmp eax instruction. What you'll notice is that in the comment beside (that x64dbg generates on its own,) is that eax = the original EntryPoint we had, just as I predicted.
[Image: 20028fffa11510533536a6b1158b49ab.png]

Now, just take one more (single-instruction) step to get to the real Entry Point of the application:
[Image: a9df71761ad67e3cfea3ce94e92a24a1.png]
And now, we actually recognize a few things on the screen. There are actual function names, for a start. This is the real packed program. Now all that's left to do is dump it.
So we open the Scylla toolkit. Keep 'Attach to Active Process' selected, since it's what we're debugging. And since Scylla has some decent automation, we just hit IAT Autosearch.

IAT means the import address table, ie. all the libraries and whatnot that are being imported.

Then, smash 'Get Imports'
[Image: 94087bb6374caf8311a0cf7b3f8a92c7.png]

Okay, there are errors. For whatever reason, whatever we dump probably won't run properly.
f*** it, the trainer was already broken. I'm looking to extract a resource, not fixing the f*** code.
Hit dump, save the file, and get out of there, since we're done with the debugger.

That was the worst of it. Now we have a few options:
--Since the file was packed, it didn't open in dotPeek. The resources were also hidden in ResourceHacker.
--I can binwalk/search for file headers with a hex editor.

First I tried dotPeek:
[Image: dfc2640065b551b230818bd5405ef509.png]
Two in a row. One more failure and I get a hat trick.
Next, ResourceHacker:
[Image: 696c0467f91f8966851e5e9da9596b62.png]

I noticed that there are a couple of WAVE (.wav) files there, a total of five. There are also some custom files, but they don't seem to dump properly with reshacker, so that's a no-go.
When looking through a file to find different types of files, we need to look for file signatures, ie. magic numbers. It's usually the first four to eight bytes which define what a filetype is and how to open it. Funnily enough, the .zip magic numbers are used for almost everything, but that's a story for another time.

When searching WikiPedia's list of file signatures, I found .wav:
The 4 dots represent a 32bit integer for the size of the file.

I know there are five of these files embedded in the .exe. So let's pop it into my favourite Windows hex editor, HxD, and try to find these headers:
[Image: 3734acf453e9dafa9dc0d840329d80a0.png]
Okay, the first one is at 0x3D4AE0. I highlighted the four bytes between RIFF and WAVE which represent the file size. On the right-side, I highlighted the int32 number: 147494
And from 0x3D4AE0 to 0x3D4AE0+dec(147494), I copied and pasted the data into a new file, saved it as Untitled.wav and played it in WinAMP.

And you know what I got?
A f*** Windows Vista error/info sound.
The developer of this trainer used them as the sound effects for turning cheats on/off, or as extra sounds.
And every single .wav file was like this.
Almost defeated, on the last .wav file, as I was selecting the block for the file size, I saw something:
[Image: 9a4c24df1247e29556a16cf9eeff99c8.png]

And I was f*** ecstatic. Honestly I still am, it's been almost nine f*** years.
After a quick google search, I found that Extended Module refers to a demoscene file format, .xm, which was popular back in the day of music trackers (what came before FL Studio.)
And after another search, I found a download of FastTracker, the one used to make this track:

So I downloaded it and got the .exe
And it only runs on MSDOS, it's that old.
Nothing an emulator can't fix, but that means more setup.
There was another file included, XM.txt
And just my luck: it was the entire documentation of the .xm file format, like all its file header information and how the data is structured.
God bless the demoscene, absolute madmen.

So after reviewing the docs and putting everything together, I finally extracted the full file from the unpacked .exe.
And I was going to go find a program that plays .xm files, but I realized that WinAMP has that support built-in, so I don't even need to reconfigure.
Absolutely amazing.

And now I'm going to convert this to a .wav or .flac and keep it safe for the rest of my life so I never need to go through that process again.
Here's the download link:
It'll play natively in WinAMP, as mentioned. Not sure about other programs, but you can also install xmp (google it) as an alternative.

Maybe you won't like the song as much as I do. To be honest, it's lost a bit of its lustre, but it still held that sentimental value of playing Black Ops with the boys back in middle school, and that's a d*** good feeling.
that's a great write up lain, filled with lots of detail and a positive ending, which is always good.

you ever consider writing posts for a blog or something similar?
"I reject your reality and subsitute my own." - Adam Savage, Mythbusters
[Image: 5.jpg]
(October 25th, 2019 at 9:56 PM)SpookyZalost Wrote: that's a great write up lain, filled with lots of detail and a positive ending, which is always good.

you ever consider writing posts for a blog or something similar?

I'm actually a freelance writer while I'm not in class, studying, or doing stupid shit like this haha

But maintaining my own blog seems sort of weird because I'd want to get people to read it, and advertising isn't my specialty. Hard to be good at ads when you have such a burning hatred for them, and it's hard to get people to read a blog if you're not constantly sharing each article everywhere, thus posting in a certain specific circle is a lot more enjoyable for me.

it's partly why I just blog on my own website instead and stick to there and the occasional forum post.
"I reject your reality and subsitute my own." - Adam Savage, Mythbusters
[Image: 5.jpg]
Excellent, very thorough! Very impressive Lain. Thank you for sharing this with us!

Users browsing this thread: 1 Guest(s)

Makestation Theme/Design Selector

Contact Us | Makestation | Return to Top | Lite (Archive) Mode | RSS Syndication 
Proudly powered by MyBB 1.8, © 2002-2020
Forum design by Makestation Team © 2020 - a modern day time capsule | Makestation Ajax Chat Hosting