Chapter III - Revealing a hidden gameplay

In the previous chapter we reversed the comparison routine of two doublewords in memory. We got its disassembly with Softice. When I looked at the whole "function" I wondered what's going on with all the other addresses the routine is dealing with:


017F:00401C37  5E                  POP     ESI
017F:00401C38  5B                  POP     EBX
017F:00401C39  C3                  RET
017F:00401C3A  833D8C45410000      CMP     DWORD PTR [0041458C],00	<- What is going on here ?
017F:00401C41  7530                JNZ     00401C73
017F:00401C43  A1742F4100          MOV     EAX,[00412F74]			<- Copy scorepoints to eax
017F:00401C48  3905A82F4100        CMP     [00412FA8],EAX			<- and compare it with the value stored inside 412FA8
017F:00401C4E  7723                JA      00401C73

Look at the code at 401C3A. I do not know what it is for so far... so let's just try it out. The code compares the value inside 41458C to zero. So we could patch it with any value different from zero. Let's rerun the game, and just patch the address with a value different from zero. I took "1". Use the map32 command again to get the data segment:

:map32 loogie


   LOOGIE .text 0001 017F:00401000 0000DB9F CODE RO
   LOOGIE .rdata 0002 0187:0040F000 00000340 IDATA RO
   LOOGIE .data 0003 0187:00410000 00004714 IDATA RW
   LOOGIE .idata 0004 0187:00415000 00000EA4 IDATA RW
   LOOGIE .rsrc 0005 0187:00416000 00026BB4 IDATA RO
   LOOGIE .reloc 0006 0187:0043D000 000017EE IDATA RO

And patch it with the value "1" (you can do this by typing "e <address> <value>" in Softice):

:e 187:41458c 1


If you switch back to the game you will notice that the display of the game changed a bit:

from

to

And not only the display, also the gameplay !! You can play as long as you want.. until you hock the headmaster/principal with a loogie. He will then run into the school and catch you, as the game will quit then (maybe it was supposed to be a debug-version or an earlier version of that game). Wow, amazing what you can find out by just patching a memory address and see what happens - this would be nearly impossible without knowledge of asm in combination with a debugger or disassembler ;) Great, now we need a new function which will be able to poke a value or some bytes into an address (in our example "1" to 41458C). I extended the engine a bit again with Engine_Pke:

Engine_Pke Proc lpWndCap: DWORD, lpBaseAddress: DWORD, nNewVal: DWORD


lpWndCap is a pointer to a string containing the window's caption (e.g.: WndCap db  'Beavis & Butt-head Hock-a-Loogie',0).
lpBaseAddress is a pointer to the address holding the value we want to patch.
nNewVal is the new value to be poked into *lpBaseAddress.

	invoke	GetAsyncKeyState,VK_F9			    ;Was F9 pressed?
	.IF eax==TRUE

	    invoke  Engine_Pke,addr WndCap, GamePlay,1	    ;Ok, so poke some value into some memory
	.endif

You see above that I didn't use F10 as hotkey. Why? That's simple.. F10 is used by Windows as a "shortcut" to the main-menu in a window. Have a look at the sources - sources and binaries.