A crack without craking:
Talonsoft's 'Operational Art of War' (TOAW)
(And a couple of sound advices for all games-demo releasers)
October - November 1998
A crack without craking: Talonsoft's Operational Art of War
This excellent strategic game (out in October 1998) has been published / will be published as
"demo" version on many world magazines' CD-ROM covers in late fall/winter 1998.
My copy is a Cdcover Demo without version number, with a length of 936.448 bytes
If you can't find a magazine with this demo just fetch it for instance from here...
should allow you to play only one of the main campaigns: The Corea war. You should not
be allowed to resume saved games. You should not be able to use the scenario editor.
Yet, as you will see, you will be able to use this "demo"
To play IMMEDIATELY most scenarios
To play -with little work- ALL scenarios
To save and play saved games
To edit and prepare new scenarios with the games' editor
In fact you'll transform this demo in a FULL-FLEDGED (good) strategical game...
Believe me: all options and routines are there, you'll just have to individuate them, 'lock them'
and reverse them... and
the funny part is that in order to play most scenarios you don't even need to 'CRACK'
this demo at all...
it comes with all the necessary code already installed on YOUR own harddisk. It's a 'crack without cracking',
great reversing fun! BTW, I may actually even buy the commercial release, because it is a really good strategical game and because I like to have and read the manuals of the games I really play...
There is, as I said, a 'compulsory demo file'
which is called Korea 50-51.SCE, and you'll find it inside the
\TOAWdemo\scenarios subdirectory on your own harddisk once you have installed the demo. But, remarkably, you will find there something else as well...
Ok, I'm sure you already guessed it all (eh eh) once again a demo comes with (almost)
the COMPLETE version concealed inside... lazy protectors didn't want to spend a little time
preparing a real demo... they just crippled a complete version and hammered it into a
crippled demo... therefore let's have a look at our own harddisk once we have installed... what is this?
Volume in drive L is gamesPC_L
Volume Serial Number is DEAD-BEEF
Directory of L:\TOAWdemo\Scenarios
ORIGIN~1 SCE 68.281 29/09/98 00:00 Original Korea 50-51.SCE ;copy of the original
KOREA5~1 SCE 69.057 21/05/98 10:34 Korea 50-51.SCE ;already renamed a different one :-)
KHARKO~1 XXX 69.057 21/05/98 10:34 Kharkov 42.xxx ;this one :-)
CRETE4~1 SCE 59.800 21/05/98 9:28 Crete 41.SCE ;their turn will come :-)
CRUSAD~1 SCE 68.735 21/05/98 9:43 Crusader 41.SCE ; "
FRANCE~1 SCE 89.399 21/05/98 10:49 France 40.SCE ; "
FULDA5~1 SCE 61.931 21/05/98 10:45 Fulda 55.SCE ; "
ISRAEL~1 SCE 65.329 21/05/98 10:43 Israel 48.SCE ; "
ITALY4~1 SCE 79.866 21/05/98 10:41 Italy 43.SCE ; "
KASSER~1 SCE 57.233 21/05/98 10:35 Kasserine 43.SCE ; "
ARRACO~1 SCE 50.521 21/05/98 10:47 Arracourt 44.SCE ; "
KORSUN~1 SCE 73.122 21/05/98 10:33 Korsun 44.SCE ; "
LUZON4~1 SCE 68.060 21/05/98 10:28 Luzon 41-42.SCE ; "
NORMAN~1 SCE 93.163 21/05/98 12:44 Normandy 44.SCE ; "
PATTON~1 SCE 79.919 21/05/98 10:26 Patton 45.SCE ; "
SICILY~1 SCE 74.995 21/05/98 10:16 Sicily 43.SCE ; "
SOUTHF~1 SCE 84.340 21/05/98 10:14 South Front 42.SCE
TYPHOO~1 SCE 88.090 21/05/98 14:54 Typhoon 41.SCE ;this will be the last one :-)
Yeah: incredible yet true: all
the other scenarii of this nice game are already there, inside
the 'demo' version, loaded on your own harddisk. (Admittedly, some of these
won't have -yet- all the necessary graphics... yet most of them will work
fine with very little 'finetuning'...
Fun isn't it? Of course you may crack the simple protection scheme of
this demo (see below) in order to play "as you should" i.e.
as if you had the full release, but the object of
this small introduction is not "how to crack" this target, but rather how to get
full functionality from
this target WITHOUT ANY NEED TO CRACK IT, see: you actually don't need any
reverse engineering knowledge (just elementary dos rename commands lore): Pace
yourself and believe me: In order to play any campaign of this supposedly
"limited" demo (or any of the zillion scenarios you can download from the web, for that matter), just
rename the campaign you want to play to "Korea 50-51.SCE". Choose your 'Korea' Demo Option and then
play whatever you want...
All images are in plain *.bmp format, so you
can modify them at leasure, which, as you will see, is quite important in order to restore the full functionality of this demo.
The A.I. -as I said- is not bad at all and if you're a strategic buff (like
me :-) you'll have MONTHS of interesting play with this 'demo'!
Why did the Talonsoft guys actually leave all the scenarios inside a supposedly "limited" demo
beats me. There is a famous precedent,
that has made HISTORY when performed by Mindscape with
Panzer General (back in 1996), and all demo-releasers -at least the many perusing
my site- were supposed by now to be immune to this kind of blunders... but
as we have already seen a couple of months ago with Gettysburg (see the very good instructions by +Rezident in
order to turn Sid Meier's demo into a full-fledged release) this kind of 'mistake' is indeed still quite
common. I wonder if I just find them in the strategic oriented games only because these are
almost the only games I really have a look at... in fact I wonder if this kind of blunder
is actually also very common in all other 'limited functionality' (i.e. 'crippled') applications and games that are continuously released? Who knows...
the point is: often enough you don't need actually to 'crack' anything in order to transform a
demo release into a full-fledged software... may be this is intentional...? :-)
Anyway this raises an interesting 'legal' question: let's for a moment admit that the
publishing of an elegant cracking solution for a protection scheme would really damage
the 'material interests' of a software producer... as all my readers know I don't reckon this
to be true at all, since I believe that all warez sites, where you can find any software
COMPLETE AND ALREADY REGGED and all 'SERIAL' sites or lists, where you can find
zillions of stolen serials and
keygenerators, damage those same interests in a 'really tangible' way... anyway, let's concede, for the sake of
this discussion, that the knowledge given out on 'teaching' sites like mine could,
if used with malicious purposes, damage those same interests... (note that this is also true for
all sites that teach programming basics and assembly, in fact for all 'teaching' sites :-) OK, nuff caveats:
now, even if that were true, the big question is:
what about programmers (like Talonsoft here) stuffing your harddidsk with complete sections of their software you
are not supposed to use? (You'r not even supposed to 'know' that you have those files on your harddisk). Who's cheating who in these cases?
An interesting line of thoughts IMO. And I wonder if all demo-releasers reading this will
ever thank us...
A LITTLE REVERSING CANNOT DAMAGE US
Now to the more reversing oriented part of this small essay: As you'll see
we need a little reversing in order to understand some finer points...
* Referenced by a CALL at Addresses:004356AB, :004356FD, :00435761
:00435371 55 push ebp
:00435371 8BEC mov ebp, esp
:00435373 81EC0C010000 sub esp, 0000010C
:00435379 898DF8FEFFFF mov dword ptr [ebp+FFFFFEF8], ecx
:0043537F 8B85F8FEFFFF mov eax, dword ptr [ebp+FFFFFEF8]
:00435385 8985F4FEFFFF mov dword ptr [ebp+FFFFFEF4], eax
:0043538B 83BDF4FEFFFF06 cmp dword ptr [ebp+FFFFFEF4], 6 ;cx bigger than 6? No good
:00435392 0F8740010000 ja 004354D8 ;don't call and ret
:00435398 8B8DF4FEFFFF mov ecx, dword ptr [ebp+FFFFFEF4] ;check cx
:0043539E FF248DE3544300 jmp dword ptr [4*ecx+004354E3] ;jump according to cx
So option cx=4 jumps to the 'hardcoded' Korea 50-51.SCE scenario...
and what would happen, pray, if we would instead jump to 435431 (go ahead nice guy)
on option cx=4?
So the jmp dword ptr [4*ecx+004354E3] above gives:
:004354E3 A5534300 cx=0 DWORD 004353A5
:004354E7 B2534300 cx=1 DWORD 004353B2
:004354EB C1534300 cx=2 DWORD 004353C1
:004354EF CB534300 cx=3 DWORD 004353CB
:004354F3 F3534300 cx=4 DWORD 004353F3 ;the "allowed" korea scenario
:004354F7 77544300 cx=5 DWORD 00435477
:004354FB A7544300 cx=6 DWORD 004354A7
:004353A5 83C9FF cx=0 or ecx, FFFFFFFF ;make sure ecx=1
:004353A8 E8B3FDFFFF call 00435160_peek, getdc, release
:004353AD E928010000 jmp 4354DA_call and ret
:004353B2 B901000000 cx=1 mov ecx, 00000001 ;make sure ecx=1
:004353B7 E8A4FDFFFF call 00435160_peek, getdc, release
:004353BC E919010000 jmp 4354DA_call and ret
:004353C1 E83AFFFFFF cx=2 call 00435300; get release
:004353C6 E90F010000 jmp 4354DA_call and ret
:004353CB 6864E54C00 cx=3 push 004CE564
:004353D0 6868E54C00 push 004CE568
:004353D5 686CE54C00 push 004CE56C
:004353DA 681CB64B00 push 004BB61C ->"Continue"
:004353DF BA28B64B00 mov edx, 004BB628 ->"This feature is|not available in demo"
:004353E4 B958B64B00 mov ecx, 004BB658 ->"DEMO"
:004353E9 E8E2BF0000 call 004413D0 ;show luser window
:004353EE E9E7000000 jmp 4354DA_call and ret
:004353F3 6860B64B00 cx=4 push 004BB660 ;"Korea 50-51.SCE" string to search for
:004353F8 6820DD5E00 push 005EDD20 ;searched string (str1)
:004353FD E80EA90500 call 0048FD10 ;this is a call to strstr, which returns
:00435402 83C408 add esp, 8 ;the first occurrence of str2 in str1
:00435405 85C0 test eax, eax ;zero=no pointer: str2 not found in str1
:00435407 7528 jne 00435431 ;this is the good "Scenarios" routine
:00435409 6870E54C00 push 004CE570 ;warn luser with luser's warning
:0043540E 6874E54C00 push 004CE574
:00435413 6878E54C00 push 004CE578
:00435418 6870B64B00 push 004BB670 ->"Continue"
:0043541D BA7CB64B00 mov edx, 004BB67C ->"Only the Korea|50-51 scenario... "
:00435422 B9A8B64B00 mov ecx, 004BB6A8 ->"DEMO"
:00435427 E8A4BF0000 call 004413D0 ;show luser the above messages
:0043542C E9A9000000 jmp 4354DA_call and ret
* Referenced by a Jump at Address:00435407(C)
:go_ahead nice guy
:00435431 6820DD5E00 push 005EDD20
:00435436 68B0B64B00 push 004BB6B0 ->"Scenarios\%s"
:00435442 FF1578657D00 Call dword ptr [007D6578] ; USER32.wsprintfA, Ord:0264h
:0043546F FF1560657D00 Call dword ptr [007D6560] ;USER32.PostMessageA,
:00435475 EB63 jmp 4354DA_call and ret
As you can see the 'protection' was a simple strstr function on an hardcoded
scenario name. That's the reason you could play just changing it:
wrong name would give a zero, you would jump correctly only if the scenario
name you'r searching (at 5EDD20) matches the hardcoded one (or if you
change the scenario names, or if you just load 1 into eax, for instance
test eax, eax into an inc eax),
or if you choose a more complete patching solution, for instance bypassing completely this
strstr check and landing directly onto the 'go ahead nice guy' part of the code... there are
infinite possibilities... once you understand the code.
Ok, now everybody that will play with this stuff will soon find an apparent flaw... I hear
you all already asking... "Hey reverser+... how comes that even if I now
can play all scenarios, I can see on the screen only PART of the colored
tiles?"; "Man this is not funny: gosth units?"; "Hey, frav, is
it an ugly anti-cracking protection scheme?"; "Woah! Did we trigger a remote
CRC protection somewhere?"
No, friends, I wish it were so (and it would have proved quite an effective
anticracking trick, btw, take note, protectors! :-)
Yet in this case is
nothing of relevance and we'll soon solve this little problem:
have a look inside your target (that's always a good
practice). You should routinely check what's inside your targets...
download the good (old dos) 'strings' program from
my tools.htm page) and you'll see, using the command
strings -o -6 opart_md.exe
that your target is calling a LOT of graphic files!
Here the relevant strings:
bf61: units_1_blue_0 bf71: units_1_blue_1
bf81: units_1_blue_2 bf91: units_1_blue_3
bfa1: units_1_blue_4 bfb1: units_1_brown_0
bfc1: units_1_brown_1 bfd1: units_1_brown_2
bfe1: units_1_brown_3 bff1: units_1_brown_4
c001: units_1_gray_0 c011: units_1_gray_1
c021: units_1_gray_2 c031: units_1_gray_3
c041: units_1_gray_4 c051: units_1_green_0
c061: units_1_green_1 c071: units_1_green_2
c081: units_1_green_3 c091: units_1_green_4
c0a1: units_1_red_0 c0b1: units_1_red_1
c0c1: units_1_red_2 c0d1: units_1_red_3
c0e1: units_1_red_4 c0f1: units_1_bluelt_0
c105: units_1_bluelt_1 c119: units_1_bluelt_2
c12d: units_1_bluelt_3 c141: units_1_bluelt_4
c155: units_1_white_0 c165: units_1_white_1
c175: units_1_white_2 c185: units_1_white_3
c195: units_1_white_4 c1a5: units_1_yellow_0
c1b9: units_1_yellow_1 c1cd: units_1_yellow_2
c1e1: units_1_yellow_3 c1f5: units_1_yellow_4
c209: units_1_tan_0 c219: units_1_tan_1
c229: units_1_tan_2 c239: units_1_tan_3
c249: units_1_tan_4 c259: units_1_greenlt_0
c26d: units_1_greenlt_1 c281: units_1_greenlt_2
c295: units_1_greenlt_3 c2a9: units_1_greenlt_4
c2bd: units_1_greendk_0 c2d1: units_1_greendk_1
c2e5: units_1_greendk_2 c2f9: units_1_greendk_3
c30d: units_1_greendk_4 c321: s_units_1_blue_0
c335: s_units_1_blue_1 c349: s_units_1_blue_2
c35d: s_units_1_blue_3 c371: s_units_1_blue_4
c385: s_units_1_brown_0 c399: s_units_1_brown_1
c3ad: s_units_1_brown_2 c3c1: s_units_1_brown_3
c3d5: s_units_1_brown_4 c3e9: s_units_1_gray_0
c3fd: s_units_1_gray_1 c411: s_units_1_gray_2
c425: s_units_1_gray_3 c439: s_units_1_gray_4
c44d: s_units_1_green_0 c461: s_units_1_green_1
c475: s_units_1_green_2 c489: s_units_1_green_3
c49d: s_units_1_green_4 c4b1: s_units_1_red_0
c4c1: s_units_1_red_1 c4d1: s_units_1_red_2
c4e1: s_units_1_red_3 c4f1: s_units_1_red_4
c501: s_units_1_bluelt_0 c515: s_units_1_bluelt_1
c529: s_units_1_bluelt_2 c53d: s_units_1_bluelt_3
c551: s_units_1_bluelt_4 c565: s_units_1_white_0
c579: s_units_1_white_1 c58d: s_units_1_white_2
c5a1: s_units_1_white_3 c5b5: s_units_1_white_4
c5c9: s_units_1_yellow_0 c5dd: s_units_1_yellow_1
c5f1: s_units_1_yellow_2 c605: s_units_1_yellow_3
c619: s_units_1_yellow_4 c62d: s_units_1_tan_0
c63d: s_units_1_tan_1 c64d: s_units_1_tan_2
c65d: s_units_1_tan_3 c66d: s_units_1_tan_4
c67d: s_units_1_greenlt_0 c691: s_units_1_greenlt_1
c6a5: s_units_1_greenlt_2 c6b9: s_units_1_greenlt_3
c6cd: s_units_1_greenlt_4 c6e1: s_units_1_greendk_0
c6f5: s_units_1_greendk_1 c709: s_units_1_greendk_2
c71d: s_units_1_greendk_3 c731: s_units_1_greendk_4
Quite a lot of stuff, as you see. Now most of these files are
missing in the demo version: the protectors left all the working code, they even left
all the scenarios, but they decided to spare on the (easy to reproduce) *.bmp graphics... go figure...
Now, if you want to play the various scenarios,
you'll have to fake these colored tiles. The best solution is to "recreate"
them using PSP and the "edit palette" function,
since in the 'graphics' directory of the demo you'll find some tiles
("s_units are special units"), have a look through psp, just
browsing the graphic files inside your toawdemo/graphics subdirectory...:
Of course -instead of recreating them editing palettes- you could also steal the missing
units tiles from any complete version, but then you could just steal the whole game as well, and that's not
the point of our work at all: we don't want to steal anything: we want simply to use some
material that has already been stuffed on our harddisks... besides it's way more fun
to change colors on your own using your own fantasy... :-)
Of course now you'r ready to play (almost) ANY scenario, see, for instance those at
Well, now you'r all set, from a strategical point of view, for the next 10 years...
wonder what will come next :-)
Last but not least on the 'wargalmer' site mentioned above (and elsewhere)
you will also find Ralph Loewen's zipped file counters.zip with all
possible tile sets and graphics
if you'r really lazy. Take note that some of the terrain tiles are also missing in the demo, you'll encounter
some funny effects playing the 'israelo-arab' wars, for instance, because the desert tiles are
Ah yes, the "load saved game" function is
disabled in the demo... this is not funny, since some scenarios are huge, and you cannot
just play the whole night for the sake of it. But you are (supposed to be) a
reverser, and this is a classical case of 'crippled target functionality', which is
pretty easy to implement... much too easy in my (biased) opinion: the strings
immediately reveal it...
As you can easily see, the 'opening scenario' (Load_whatever)
relevant routines are all at:
:004720F0 833DD0BC740000 cmp dword ptr [0074BCD0], 0 ;is it a bad guy?
:004720F7 7525 jne 0047211E ;~no, so go to "load_whatever"
:004720F9 6834FE4C00 push 004CFE34 ;~yes so beggar off...
:004720FE 6838FE4C00 push 004CFE38 ; ...with the following
:00472103 683CFE4C00 push 004CFE3C ; ...little demo window
:00472108 68802D4C00 push 004C2D80 ;->"Continue"
:0047210D BA8C2D4C00 mov edx, 004C2D8C ;->"This feature is not avail..."
:00472112 B9BC2D4C00 mov ecx, 004C2DBC ;->"DEMO"
:00472117 E8B4F2FCFF call 004413D0 ;show message to luser and
:0047211C EB1C jmp 0047213A ;don't execute following 'good' code
*__Load Whatever__* Referenced by a Jump at Address:004720F7(C)
:0047211E 33C9 xor ecx, ecx
:00472120 E81BB1FBFF call 0042D240
:00472125 85C0 test eax, eax
:00472127 7411 je 0047213A
:00472129 33D2 xor edx, edx
:0047212B B9C42D4C00 mov ecx, 004C2DC4 ;->"Opening scenario. Please Wait"
:00472130 E82BD9FCFF call 0043FA60
:00472135 E8D6EB0000 call 00480D10
An easy patch of the simple code snippet above will land you to the load_whatever part and
present you a small window for opening
SCENARIOS (the *.SCE files), yet you will
be able to easily open your
(or others') saved games as well:
just (1) navigate to the 'saves' subdirectory
and then (2) type *.* (or directly *.sav) as a query mask... yes,
it works (of course)...
I'll leave as a (relatively) easy exercise for the reader 'how to get the FULL
editor functionality back'... great fun (and worth your reversing time)...
you'll actually get a complete working
and reversed copy of this very good game at the end... but, and this suits my teaching
you'll have to work a little on your own and you will have to understand (at least part of)
the code... hint: use a flow editor like smartcheck :-)
MY ADVICE TO THE GAMES PROGRAMMERS
The first obvious lesson you should have learned long ago (seen the
incredible success of the unsurpassed Steel Panther I, the best ever strategical/tactical game that
is now -fall 1998- appearing for next to free, complete, on
some magazine CD-ROM: BUY IT!) is that you should, by all means, give for free
With them you SHOULD offer to the masses the possibility to play home-made scenarios.
A good protection scheme, that would at the same time work well for the SPREADING of your
strategic game would therefore be, IMO: give with the demo a couple of scenarii and the
ability to create (and play) any scenario, PROVIDED THE USER HIMSELF HAS MADE IT. The
demo will NOT allow the playing of scenarios created by a third party (a very easy
to implement protection scheme). So the user will have
a great game (hopefully :-) and he will probably create
a lot of home-made scenarii for the greater glory of the 'regular' user community,
in fact only those that will have UPDATED TO THE REAL VERSION will be able to play third-party
scenarii. The demo users will NOT be able to play scenarii made by a third party
(well, unless they crack
the protection scheme, of course, but we are speaking here of normal placid demo-users, not
of reversers :-)
lotta people playing the hell out of it (but with a great incentive to register)
and AT THE SAME TIME working a lot for free in order to spread your game, with
lotta scenarii coming out and a great incentive
to update... if you give a good written documentation and if you keep
the update price low enough, as you should IMO.
Of course even that can be cracked if necessary, yet note that that would basically
be THE CONTRARY of what Talonsoft did with this target. Here they
didn't give anyone the possibility to
create scenarii with the demo (which would have actually helped the spreading of their
game) and yet -a silly mistake- gave away with this demo the possibility to play de facto
any scenario, something that will not help them much actually... a mistake, IMHO.
You are deep inside reverser's page of reverse engineering,
choose your way out:
(c) reverser 1995, 1996, 1997, 1998. All rights reserved