Friday, January 18, 2008

Hacking Neverwinter Nights 2 - Pt. 1 of 2

Todays post will be the first of a two part segment on exposing the relevant pieces of NWN2's game code in order to find, or in this particular case make, an exploit. The principals can be applied to any software, but for the purposes of this article we will be using a video game, where the exploit we make won't endanger or cause harm to anyone. Additionally, game's make excellent subjects for this type of lesson because the game world is a very easily controlled environment. Virtually everything we may want to change can be provoked by simple gameplay, and before the game's tutorial mode ends we should have a working money hack.

The first thing that must be addressed is whether or not we have the right tools to perform the task. Generally, the only tool you will need is L. Spiro's Memory Hacking Software (a link to his downloads page is available on the sidebar of this blog). It combines a Memory Scanner, a Debugger and Disassembler, as well as several very helpful misc utilities. Some of you more experienced people may remember SoftICE - and may even at one point in time been infatuated with the "auto-assembler" feature in which you could input any assembler code and it would give you the resulting hex bytes. MHS has resurrected this functionality, and rightfully so. If you intend to write a stand-alone hack to distribute to friends, alas I will not be covering injectable DLL's or trainers in this article. We will strictly be dealing with interpreting and rewriting game code. It should also be noted that I won't be explaining the basics of Assembler, Hex, or how to use a Debugger. If these concepts are foriegn to you, it may be in your best interests to Google them before continuing.

Start NWN2 and create a new game with a new character (it doesn't have to be a specific type of character, just so long as you start out with the default inventory). Go through the game as usual until you've finished speaking with Georg in the village square. You should now have 10 gold pieces and Daeghun's furs. Open up MHS (be sure to set nwn2main.exe as the opened process) and do a DWORD search for "10". You should get an astronomical amount of results. Go talk to Galen the Merchant and sell him Daeghun's furs (resulting in 170 gold pieces). Return to MHS and do a subsearch for "170". This narrows my list to 3 (which is within acceptable parameters). If your list still has too many results, buy the bow and sieve for the result. If you still have too many, you probably did something wrong and should start over. When you are ready to proceed, place a different value in each slot (Ex: 167, 168, and 169). This helps us identify which address actually holds the data we want (the other two are pointers, and get reset by the game). Once the results have been narrowed down to 1, right click on the address and select "Find out what writes this address". Go back to Galen and buy the bow (If you already bought the bow, sell your armor and then buy it back). The debugger should have landed on the following code:

MOV EAX, DWORD PTR [ESP+0x1C]
MOV DWORD PTR [EDI+0x800], EAX

This shows the game moving a function's parameter into EAX, and then EAX into the buffer the game has allocated dynamically at runtime for the player's gold. NWN2 is different from most games in that it has different functions for handling buy/sell events. The above code is for buy events. We want to change the two instructions above into the following:

MOV DWORD PTR [EDI+0x800], 100000
NOP
NOP
NOP

This will cause NWN2 to set your gold level to an absurdly high amount everytime you BUY something! Try it out by selling and then repurchasing your armor. One of the perks to the way in which we wrote this hack is that the game still believes you paid for the armor, and even displays the message that you lost 50 gold pieces! Furthermore, since we are setting the value instead of adding to it, we don't have to worry about a buffer overflow occurring after too many buy events. One thing to remember is that you need to be aware of what code you over-write and how it effects the game. Luckily for us the code we wrote is exactly the same size in bytes as the original two instructions in the game's code. In the event that this is not the case, it's important to remember to use code caves (MHS does this for you, but it is preferable to learn to do it yourself) - though that is a lesson for another day.

No comments: