Pete's game making chronicles

PopsiclePete

Mission programmer
Since we have committed ourselves to giving more frequent updates on our progress, I thought I would offer a glimpse at one of the lesser known aspects of Standoff's development: patch making!

As you know, Standoff is a modification of Secret Ops. Even if SO is much easier to mod than the previous WC games, many aspects of the game were hardcoded into it: the number of guns, number of ships, number of displayed asteroids, etc. To be able to break those limitations, the main game's EXE has to be altered. Those of you who have tried hex-editing their favorite games knows you can't do much using that method. To solve this problem, WC editing guru HCl developed a very effective method: do a very small hack to the EXE so it loads a DLL, and from that DLL rewrite the EXE directly in memory!

Using this trick, HCl has made many amazing patches to WCP/SO, like the hi-res and DVD patches. He also made a number of patches for Unknown Enemy and Standoff... but the really cool thing is that he gave us a formidable tool through which we've been able to add on our own little patches every time a need arises.

At this stage in the Episode 5 development, Standoff includes over 80 patches which allow us to raise the limits of the original SO, add new mission commands and making the game closer to the original Wing Commander 2 gaming experience.

I have prepared a small demonstration explaining a very simple patch I recently made. After hearing people complain about the game's screenshots being overwritten with new images every time the game was reloaded, I decided to make a quick patch. The problem is that when the player hits the "Print Screen" key, the game doesn't check for existing files and starts to save them over what already exists.

Here is a simplified description of how the patching process works.

Doing a quick search in the game's EXE to find where the screenshot's name is chosen is easy (see image, tag 1). If you look at the lines just over the reference to the filename (tag 2), you can see that the EXE retrieves some value, make a copy of it (eax to ecx) then increments the value. This value is then stored back (tag 3). This obviously is the counter.
Standoff patch - ASM example.png


What we'll do is hijack the original code: we'll rewrite the game to load a custom function we made in the DLL. A first function, run immediately after the EXE is loaded into memory, will overwrite two part of the original code to make it call our custom function instead.
Code:
	{
		void * t = (void *) ScreenshotCounter_hook;
		char bridge[] = {0x68, 0,0,0,0, 0xc3};
		memcpy (bridge+1, &t, 4);
		memcpy((void*)0x426890, bridge, 6);
	}
Standoff patch - ASM example2.png


So, now we have the game calling a funtion named "ScreenshotCounter_hook". Now what ? "ScreenshotCounter_hook" will contain assembler code to continue the sequence where we hijacked the EXE. But since I suck at assembler code and I want to code lazily in C++... so while we could have the hooking function do whatever patching we need, we often have it call a nice C++ function. That's what we'll do here. Note that we usually want to restore a few lines of the code we've overwritten; I've done it here even if it wasn't necessary (those with a sharp eye will understand, looking at the code, that our patch will completely disregard the internal screenshot counter, so it's not important to actually read it's value!):
Code:
void __declspec(naked)ScreenshotCounter_hook(void) {
	__asm {
		mov eax, dword ptr[0x4FAD54]	// restore the overwritten code

		call CheckScreenshotNumberExists
		mov ecx, eax				// restore the overwritten code

		push 0x426897   			// return code location
		ret
	}
}

Then comes the C++ code to check is a screenshot file already exists before passing a screenshot number back to the game:
Code:
int screenshotNumber = 0;				// new counter

int __stdcall CheckScreenshotNumberExists() {
	char filenameCheck[32];
	sprintf(filenameCheck, "shot%04d.bmp", screenshotNumber);	
	while(FileExists(filenameCheck))		// as long as the file exists...
		{
			screenshotNumber++;		// ... increment the counter
			sprintf(filenameCheck, "shot%04d.bmp", screenshotNumber); // ...recheck
		}
	return screenshotNumber;			// return the new counter value
}

And voilà! I hope you enjoyed this little peek into the Standoff patching process. Many, many thanks to HCl who developed the technique and made the essential patches that now allow us to go further and make a great mod! Now, I will go back to actually making the game instead of writing stuff...

Oh, and if you want to learn more about DLL patching, HCl has made much more information available on his techniques on his website. Everything is there, from the initial alteration that has to be done to the EXE to complete source of the DLLs for UE and Standoff Episode 1.


Pierre
 
That's insane. I hate looking at any sort of disassembly or machine code for too long, it makes my head hurt. I leave that sort of thing to my boss.

But I'm glad you can do all sorts of things with the DLL hack. Much love to the programmers.
 
Cool, thanks for posting this. I only understand a small bit of that, but I'm in a computer course now and I'm pretty fascinated by these things. I can see some of the similarities between C++ and Java there.
 
How expansive do you think this technique would be to other games (like maybe other orgin games)?

Hmm....I wonder if the Secret ops source code were found in that Mythic stuff, if anybody would even bother making any changes to the exe what will all that has already been done.
 
How expansive do you think this technique would be to other games (like maybe other orgin games)?
In theory, it could be applied to any game EXE.

What do you mean by expansive ? The CPU load it generates ? Of course it depends on the code you insert. In the case of the example I used for this article, the impact is almost inexistent.

Hmm....I wonder if the Secret ops source code were found in that Mythic stuff, if anybody would even bother making any changes to the exe what will all that has already been done.
I am not sure if I get what you mean here either; do you mean that all our DLL patching would go to waste if we'd have SO's source ?

At this stage in Standoff development, even if we were offered the opportunity to get SO source code and recompile it to our need it'd be a bit too late, as the game is almost done now... but even if it was for a whole new game I don't think we'd use the source. See, the source code is the intellectual property of EA, and we don't really have the right to use it. If we ever could recompile any of the old WC source it'd probably be to make patches for the existing existing games, as modding existing games is a "tolerated violation" (for the lack of a better term) of the IP, mainly because you still have to buy the original game to make use of it.

BTW, we can already have a taste of WCP's source with the old alpha build that's on the dev CD that were posted on the forums not long ago. Even if it's too old to be effectively recompiled into an enhanced version of WCP it does however offer a very interesting insight of how things work internally.
 
Well, I meant recompiling the secrets ops source code would be a waste considered the large amount that has already been done. At most, the AI could be improved, but I can't think of any other reason.

It was just an interesting thought I had.
 
This technique has a lot of applications - I believe there's a kernel hook mechanism in Linux that does exactly that for no-overhead probing (when the probe is not in use, the probe code doesn't have a cost). You tell it the symbols you want to override, and it patches the code in-memory so your hook is called. Very neat technique, especially when you can do it on a live, running system (and not just on a binary you can edit before running).

It's a lot easier to do on processors that have fixed instruction length - the number of instructions that need patching is fixed, compared to say, an x86 CPU, where you need to basically find the instruction boundaries and fill in the gaps with NOPs.
 
In theory, it could be applied to any game EXE.

At this stage in Standoff development, even if we were offered the opportunity to get SO source code and recompile it to our need it'd be a bit too late, as the game is almost done now... but even if it was for a whole new game I don't think we'd use the source. See, the source code is the intellectual property of EA, and we don't really have the right to use it. If we ever could recompile any of the old WC source it'd probably be to make patches for the existing existing games, as modding existing games is a "tolerated violation" (for the lack of a better term) of the IP, mainly because you still have to buy the original game to make use of it.

Still, as a code developer myself, I imagine that having the source would be very useful to modders, even if you're not re-compiling it. It's just easier to figure out where to jump in, and what a section of code is doing, if you can read the original source (complete with developer comments)...and to understand why certain things happen the way they do.

Regarding "tolerated violation"...one might be able to make an argument that modding the game in the fashion you have done could well qualify as "Fair Use" of the IP...you're providing a set of "tools" as it were that run on top of the original code and enhancing its functionality. At least, it legally could be interpreted that way. It's interesting...most modders are very careful about not angering the IP holders, and in return most game developers encourage modding (within reasonable limits) as they recognize that the fan community is increasing the replayability, and hence the value, of their product for free, without cutting into the profits that they reap from the IP. I'm actually a little scared that some modders somewhere (or some shortsighted software company lawyer) might be crazy enough to upset this relationship and actually put modding through the legal test (i.e. by trying to charge for their mods)...and then it's just up to the judge that it happens to come to. I'm glad the Standoff team and EA are both so good about this...
 
Still, as a code developer myself, I imagine that having the source would be very useful to modders, even if you're not re-compiling it. It's just easier to figure out where to jump in, and what a section of code is doing, if you can read the original source (complete with developer comments)...and to understand why certain things happen the way they do.
You're absolutely right, that's why in my previous post I refered you to the WCP source code that's already available to us... it's blessing of informations on how things work internally and does help in patching/modding.

Regarding "tolerated violation"...one might be able to make an argument that modding the game in the fashion you have done could well qualify as "Fair Use" of the IP...you're providing a set of "tools" as it were that run on top of the original code and enhancing its functionality. At least, it legally could be interpreted that way. It's interesting...most modders are very careful about not angering the IP holders, and in return most game developers encourage modding (within reasonable limits) as they recognize that the fan community is increasing the replayability, and hence the value, of their product for free, without cutting into the profits that they reap from the IP. I'm actually a little scared that some modders somewhere (or some shortsighted software company lawyer) might be crazy enough to upset this relationship and actually put modding through the legal test (i.e. by trying to charge for their mods)...and then it's just up to the judge that it happens to come to. I'm glad the Standoff team and EA are both so good about this...
Exactly, as long as we offer a mod/patch that requires the original game to play it's pretty safe to assume that the "abuse" will be tolarated because it's a winner-winner situation for both the fans and the IP holder.

This being said, I wouldn't want people to think that it's become useless nor too illegitimate to wish for the game's source and permission to alter/recompile. Being able to alter and recompile the original source code would still be the best way to help our beloved old games pass the test of time. For example, we can imagine that if fans around the world would fix the original games to work on the most current OS, fix it's bugs and tweek their controler scheme for modern input devices then the IP holder (in our case EA), still retaining the rights for it's game, could release a new version of the fixed game to the world, while people currently owning the old game copy could download a patch for free. Almost no cost for the IP holder, no cost for the old-time fans, fun for everyone. Of course this is just an example of how a souce code release could be dealt with, it could be done many other ways, too... including an anonymous release which the IP holder would simply choose to pretend ignoring because it wouldn't officially acknowledge it but in fact would tolerate.

In the meantime, as the sources haven't been made public yet, we'll continue to use that DLL patching technique :)
 
I think the limit is only about how close you are from being a assembler programmer god, really. Look at HCl's amazing WCP multiplayer patch, for example. Without the source code it is very tedious and hard to "map" the in-game objects and code, and hacking it without disrupting the rest of the code is a difficult task in itself; that's why most of my own hacks are pretty simple ones... but if we had more HCls, any complex element of the game could be changed.
 
I think the limit is only about how close you are from being a assembler programmer god, really. Look at HCl's amazing WCP multiplayer patch, for example. Without the source code it is very tedious and hard to "map" the in-game objects and code, and hacking it without disrupting the rest of the code is a difficult task in itself; that's why most of my own hacks are pretty simple ones... but if we had more HCls, any complex element of the game could be changed.

Well either way it is quite impressive!
 
Back
Top