1

foone (@Foone): "OKAY SKIFREE This is a game originally from 1991, develope...

 2 years ago
source link: https://nitter.net/Foone/status/1536053690368348160
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

"OKAY SKIFREE This is a game originally from 1991, developed by Chris Pirih, and included on one of the Windows Entertainment Packs. There's a modern 32bit version by the original developer, on the official site

OKAY SKIFREE This is a game originally from 1991, developed by Chris Pirih, and included on one of the Windows Entertainment Packs. There's a modern 32bit version by the original developer, on the official site: ski.ihoc.net/
media%2FFVEocc8VsAAAALX.png%3Fname%3Dsmall

Jun 12, 2022 · 6:31 PM UTC · Twitter Web App

1,457
it's windows only and it's not got the source available. which is a shame. crossplatform skifree, skifree mods/improvements would be cool, right?
I've also got the original 16bit EXE and some intermediate versions. but the 32bit version is much easier to analyze, so I'm gonna focus on that one.
It's all in one big ol' EXE. and by "big" I mean it's 116 kilobytes. So there's no image files or anything.
media%2FFVEpPw_VUAAul2P.png%3Fname%3Dsmall
So let's run wrestool on the EXE and see what we've got. So, a ton of bitmaps...
media%2FFVEpc9FVEAEhkIU.png%3Fname%3Dsmall
and some icons.
media%2FFVEpjMlUYAAQtT-.png%3Fname%3Dsmall

So, icons. We've got this icon, which is available in three variants. 2 color, 16 colors, and 16 colors again. I think it's just 16 colors (but windows standard) and 16 colors (but custom).

This is the original icon, designed by Chris Pirih.

media%2FFVEqJ0lVUAAiJDe.png%3Fname%3Dsmall
Then there's the other icon, which was designed by someone at Microsoft. Apparently they didn't like the original icon, and had someone design a fancier icon before it got into the entertainment pack. same as before: 2 color, 16 color, 16 color but fancy.
media%2FFVEqtD-VUAAbEsz.png%3Fname%3Dsmall
then there's 8 files that weren't able to be decoded by wrestool. I think they're supposed to be icons? but they don't work. I'll leave them alone for now.
Then we've got 89 bitmaps which make up the rest of the game's graphics.
media%2FFVEre1uVsAAv4cH.png%3Fname%3Dsmall
and despite this being the 32bit version, you can tell that these were designed for 16-color displays. They're manually dithered.
media%2FFVErov9UcAAubOk.png%3Fname%3Dsmall
OKAY SO now it's time to look for code. We've got an entry point (which'd be WinMain) and then 9 groupings of functions, based on their addresses. 401 through 409.
media%2FFVEsYAkVsAA6M3w.png%3Fname%3Dsmall
401 has 19 functions 402 has 25 functions 403 has 11 functions 404 has 16 functions 405 has 15 functions 406 has 23 functions 407 has 22 functions 408 has 11 functions 409 has 5 functions
so we have a total of 147 functions in the EXE.
that's a bunch. but it's doable to reverse engineer these one by one, right? and reimplement them? giving us a source-available clone of SkiFree?
at first that'd just give us a win32 version of skifree, which... we have. but then the use of the win32 api could be replaced with SDL or similar, creating an identical but cross-platform skifree.
so we can figure out a lot of things by doing basic puzzle-solving logic. like let's look at FUN_00405a40. it sets a bunch of global variables, then calls a function, and if the result is 0, it calls another function with a string, which is basically "can't load bitmaps"
media%2FFVEu8j2VEAADKJu.png%3Fname%3Dsmall
so clearly FUN_00405ab0 has something to do with loading bitmaps, and FUN_00404950 displays messages.
and if we check FUN_00404950, it calls some other function to get a caption, then calls MessageBoxA, a win32 API to display a message box, if you couldn't guess.
media%2FFVEvUBZUcAATwOi.png%3Fname%3Dsmall
SO let's rename this. FUN_00404950 is DisplayMessageBox.
FUN_00401cf0 is a little more complicated. But if we look into this, it seems that DAT_0040c61c is a global variable which is an array of pointers to strings, indexed by param_1.
media%2FFVEv9t_VsAAz1Ox.png%3Fname%3Dsmall
if the entry is filled (non-NULL), it simply returns that string. if it's not filled, it uses LoadStringA to go get it, then allocates some memory for it, puts it in the slot, and then returns it.
so this is just a cache around LoadStringA

LoadStringA pulls strings out of the specified EXE/module (it could be a DLL or something).

I'm gonna guess that it's actually pulling them out of this EXE, since there's no DLLs or anything else to load from.

The module instance it's using is DAT_0040c61c. Let's see where that's set.
So it's read from 4 places and written from one. Time to check out where it's written.
media%2FFVEwx91VsAAGwOY.png%3Fname%3Dsmall
so it's set to param1 of FUN_004052d0, which is a big call that does a bunch of things. Who calls this?
media%2FFVEw_izVIAAkrMk.png%3Fname%3Dsmall
It's called in only one place, by FUN_004047e0, which calls it with... its own param1. UGH. Let's see how calls this!
media%2FFVExJXOUYAAsqIF.png%3Fname%3Dsmall

It's called in one place, by the entry function, which passes pHVar5, which is the result of GetModuleHandleA(NULL)

That returns the current module instance.

media%2FFVExZB4VUAI9rCb.png%3Fname%3Dsmall
so, rewind the investigation stack. DAT_0040c61c, the data we were looking at, it's a global variable pointing to the HMODULE handle to the current EXE.
So now we can rewind back to that string-caching function, and name (and type) the DAT_0040c61c data. It's now SkifreeEXE, and we can see it passed to LoadStringA.
media%2FFVEyAgZUYAAs4P7.png%3Fname%3Dsmall

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK