foone,
@foone@digipres.club avatar

wow, this is not a problem I run into that often: the game I want to reverse engineer is, in fact, easy to dig into, with lots of easily decompiled classes!

except I can't read any of them, because they're named in Finnish.

class HuoneenNroPaivitysScripti
class KakkosTalonTapahtumat
class MrspookKontrlScript

foone,
@foone@digipres.club avatar

important languages to learn for reverse engineering:

  • C
  • C++
  • Javascript
  • Java
  • x86 assembly
  • ARM assembly
  • PowerPC assembly
  • MIPS assembly
  • Finnish
a13cui,

@foone

  • Chinese
ecsd,
@ecsd@commons.whatiwanttoknow.org avatar

@foone

don't forget HTROF.

foone,
@foone@digipres.club avatar

@ecsd I'm not into Pokémon

ecsd,
@ecsd@commons.whatiwanttoknow.org avatar

@foone

try

HTROF
pop pop pop pop pop

mhoye,
@mhoye@mastodon.social avatar

@foone "... in order of obscurity"?

fuchsiii,
@fuchsiii@oxytodon.com avatar

@foone oh god… not Finnish

kkarhan,
@kkarhan@mstdn.social avatar

@fuchsiii @foone wasn't there someone who literally made a languague to generate "correct" fan translations into Finnish?

bjompen,
@bjompen@mastodon.nu avatar

@foone
Järjestelmänvalvoja. I dont think Sami Laiho is here on mastodon yet ;)
https://www.youtube.com/watch?v=3JHko3mDJ0E

xgebi,
@xgebi@hachyderm.io avatar

@foone All simple languages, except for C. My fear was that Czech would be on the list

grandpariley,

@foone finnish as in the ability to finish a project you start 😭😭😭

foone,
@foone@digipres.club avatar

@grandpariley well I certainly don't have that

petealexharris,
@petealexharris@mastodon.scot avatar

@foone
perkele!

ZILtoid1991,

@foone How can I utilize Finnish in my reverse engineering endeavors?

AnonymooseGuy,
@AnonymooseGuy@mas.to avatar

@foone
That's my biggest coding failure.

I can never Finnish.

sol_hsa,
@sol_hsa@mastodon.online avatar

@foone 7 out of 9, what do I win? Oh wait, I've done reverse engineering already..

AlgoCompSynth,
@AlgoCompSynth@ravenation.club avatar

@foone I've done fairly well with just x86 assembly, gdb, and the complete Sibelius tone poems. 😉

foxxo,

@foone Russian is also important for reverse engineering.

foone,
@foone@digipres.club avatar

@foxxo I don't think I've run into any Russian games yet but I suppose it's only a matter of time

ethulhu,
@ethulhu@chaos.social avatar

@foone my favorite is when the Computer Words are still in English, like <Finnish word><Finnish word>AbstractFactoryModuleProvider

RL_Dane,
@RL_Dane@fosstodon.org avatar

@foone

> important languages to learn for reverse engineering:
>
> * C
Cool!
> * C++
Ok.
> * Javascript
Uhhh..
> * Java
Ummmm...
> * x86 assembly
Umm, ok?
> * ARM assembly
Uhhhh.
> * PowerPC assembly
Cool.
> * MIPS assembly
Interesting.
> * Finnish
I'm out. 🤣

In all fairness, Finnish is a beautiful language. But I think I've got a better chance at learning to program the ENIAC. ;)

foone, (edited )
@foone@digipres.club avatar

oh my god this localizes too early

so instead of just doing "if (current_room=='kitchen')", and showing different strings for "kitchen" depending on which language the user selected, it has to do:

if (current_room == "Kitchen" || current_room == "кухня" || current_room == "부엌" || current_room == "Cocina"){
...
}

kawa,
@kawa@mas.to avatar

@foone holy shit

XenoPhage,

@foone Sounds like a developer who got paid per character..

unlambda,
@unlambda@hachyderm.io avatar

@foone ah, the perils of stringly-typed programming in localized software.

gom,
@gom@chaos.social avatar

@foone
CPU cycles in production are cheap, the customers are paying for CPUs and energy -.-

eyesquash,
@eyesquash@mastodon.world avatar

@foone if (current_room == lang['kitchen'])

jamesholden,
@jamesholden@mas.to avatar

@foone That’s some junior dev shit right there.

foone,
@foone@digipres.club avatar

meaning that every time they add a new language, they have to update the logic in a bunch of places or it'll cause basic game functionality to fail in some languages

foone,
@foone@digipres.club avatar

private List<int> numbersToChooseFrom

oh I'm sure that's just a badly named member and it won't be used terribly. scrolls down
this.numbersToChooseFrom = new List<int>((IEnumerable<int>) new int[46]
{
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
....

foone,
@foone@digipres.club avatar

WHY ARE YOU STATICALLY INITIALIZING AN ARRAY OF NUMBERS FROM 0 TO 50

wait. 0 to 50? and it has 46 elements? uhhhh

foone,
@foone@digipres.club avatar

yeah 27,30,37,38,and 39 are missing

foone,
@foone@digipres.club avatar

you might say "but foone! surely this is just an enumeration that didn't survive decompilation!"

NOPE, THIS IS C#, enumerations come through fine.

sebboh,

@foone I did, in fact, come here to say that this and prior messages look like decompilation artifacts.. But, ok, if you say so! C# decompilers work well, is that what I am hearing?

foone,
@foone@digipres.club avatar

according to google translate, this AikaEteneeJaJotainTapahtuu coroutine means "Time Moves On And Something Happens" which is a perfectly valid name, I guess.

talon,
@talon@dragonscave.space avatar

@foone I’m now getting a shirt with that phrase.

foone,
@foone@digipres.club avatar

oh god this reverse engineering tool (dotpeek) doesn't let me leave annotations/comments.
that's going to make this basically impossible for someone with as much ADHD as me, even before we get to the problem of "I DON'T SPEAK THE LANGUAGE THIS CODE IS WRITTEN IN"

gsuberland, (edited )
@gsuberland@chaos.social avatar

@foone not sure if it supports comments (will go check) but I'd recommend switching to dnSpy. it's basically dotPeek but newer and better maintained, and has a lot of the old Telerik folks working on it after JustDecompile stopped being maintained. it decompiles all the fancy new language features and .NET 7 stuff, too. and has built in assembly editing features so no more relying on old Reflexil plugins.

edit: original dnSpy is archived; look for the dnSpyEx community fork repo.

ChlorideCull,

@gsuberland @foone Is there a maintained fork I'm unaware of?

gsuberland,
@gsuberland@chaos.social avatar

@ChlorideCull @foone sorry yes, I meant to say dnSpyEx.

https://github.com/dnSpyEx/dnSpy

brouhaha,
@brouhaha@mastodon.social avatar

@gsuberland @foone In 2017 I had to reverse-engineer a dot net tool in the Cypress Semiconductor EZ-PD toolchain. The chip was a PSoC with a Cortex-M core and the USBC PD interface. For some crazy reason they required a second, undocumented checksum in the gramming file, and their programmer tool checked for that. Maybe they wanted to prevent interoperable third-party tools? I had to binary patch the output of their toolchain for other reasons, so I needed to recompute the checksum.

foone,
@foone@digipres.club avatar

@gsuberland cool, I'll try it out! thanks.

gsuberland,
@gsuberland@chaos.social avatar

@foone make sure you grab 6.4.0 from dnSpyEx repo rather than the older 6.3.0 from the original dnSpy repo :)

gsuberland, (edited )
@gsuberland@chaos.social avatar

@foone no comment support, unfortunately. will raise a github issue. (might need a bunch of work though, 'cos the comments need to be stored somewhere but the tool doesn't have the concept of projects or anything like that)

update: issue raised on the dnSpyEx repo.

https://github.com/dnSpyEx/dnSpy/issues/239

foone,
@foone@digipres.club avatar

okay so I looked more into what this numbersToChooseFrom array does: It's a list of different events that can happen in the game.
Every time the game needs a random event, it picks a number from this list, then deletes out that entry in the list. So it might pick 7 the first time, but then it deletes 7 from the list so 7 can't happen again

foone,
@foone@digipres.club avatar

some numbers are missing because those events have apparently been disabled.

but for extra fun: they're still present in the code that activates events.

foone, (edited )
@foone@digipres.club avatar

so there's still code here to trigger an Event-27, even though the current state of the numbersToChooseFrom array means that Event-27 cannot be trigger naturally.

foone,
@foone@digipres.club avatar

of course, some punk could inject new code into the executable or just edit the array in RAM, and suddenly these removed events start happening again

foone,
@foone@digipres.club avatar

ah-ha! they're not permanently left out. Just temporarily: there's a function LisaaPahatMonsut (add bad... something?) that puts them back in.
It's triggered at 2:00, which I think means in-game time?

So you can't get the bad-something-events until after 2:00 am (the game runs from midnight to 6am)

gsuberland,
@gsuberland@chaos.social avatar

@foone add bad monsoons. DeepL Translate is generally better than Google Translate for short variable names like this.

slothdude,
@slothdude@mastodon.online avatar

@gsuberland @foone Doesn’t get it quite right, though. That’s “add evil monsters”, where the “monsu” is Finglish slang for monster.

gsuberland,
@gsuberland@chaos.social avatar

@slothdude @foone ah, slang. that explains the bad translation!

gsuberland,
@gsuberland@chaos.social avatar

@slothdude @foone it did also suggest "evil" as the middle word, but with the context of "monsoons" it didn't seem right. I've flagged it as incorrect on the site.

foone,
@foone@digipres.club avatar

@slothdude @gsuberland ahh, thanks

foone,
@foone@digipres.club avatar

kumahdusAanet on kellonKumahduksetSours is one that google is having trouble translating.

It's clearly sound related, being used to play the clock ding-dong noises at the top of each hour, but google is translating it as the "bulging Sound" array on the "Clock's Gloom Sours" object

zouppen,
@zouppen@chaos.social avatar

@foone I'd translate kumahdusAanet as boomSounds and kellonKumahdukset as bellTolls. Not sure what "Sours" is, perhaps misspelled "source" in English?

foone,
@foone@digipres.club avatar

AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH CODING IS HARD AND LOOKING AT OTHER PEOPLE'S TERRIBLE CODING HURTS MY BRAIN

foone,
@foone@digipres.club avatar

on the plus side, in several cases it seems to use 69 as a placeholder.

which is, of course, nice.

foone,
@foone@digipres.club avatar

that terrible screenshot is used to figure out what name to call the current scene, which is then set using this wonderful code:

this.camTegsti.text = this.mikaScene != 2 ? (this.mikaScene != 1 ? (this.mikaScene != 3 ? "camera_bedroom" : "cámara_dormitorio") : "카메라_침실") : "камера_спальная_комната";

foone,
@foone@digipres.club avatar

ugh.
the way the "camera missing" anomaly is implement is by infinite recursion and two checks that cause it to break out early.

I'm gonna be sick

foone,
@foone@digipres.club avatar

there's a different class for each language the game is translated into. it has all the logic copy-pasted, but the start-game menu option loads a different scene.

so like, in english it loads 2p0, in spanish it loads 2p0esp, in korean it loads 2p0korea, and... I can't find where the russian level is loaded.
Oh, the russian files are named completely differently. it's 2p0rus

foone,
@foone@digipres.club avatar

I think the function that's called when you do a report and the intruder starts wiggling in front of the camera is named "TaysAutismiLol" which... yeah that's not a great name

foone,
@foone@digipres.club avatar

persKommunismiKomennotLillillil

communism? WHAT? THIS IS A HORROR GAME ABOUT ANOMALIES IN A HAUNTED HOUSE

WHAT DOES ANY OF THIS HAVE TO DO WITH COMMUNISM

foone,
@foone@digipres.club avatar

the game also logs latitude and longitude into the debug console, which turn out to be a spot about 200 miles south-west of Guam

foone,
@foone@digipres.club avatar

so I thought it might be good to catalog the anomalies in a google sheets, because I could use the built in google translate support to try and help me translate it.
but "keittioTuolinAnim" turns into "tubing".
regular google translate says "kitchenChairAnim".

the fuck?

foone,
@foone@digipres.club avatar

(this.kellonAika.text == "03:30" || this.kellonAika.text == "03:31" || this.kellonAika.text == "03:32" || this.kellonAika.text == "03:33" || this.kellonAika.text == "03:34" || this.kellonAika.text == "03:35" || this.kellonAika.text == "03:36" || this.kellonAika.text == "03:37" || this.kellonAika.text == "03:38" || this.kellonAika.text == "03:39")

tml,
@tml@urbanists.social avatar

@foone With code that idiotic, is the actual gameplay still interesting and fun?

foone,
@foone@digipres.club avatar

this is only one clause in this if statement

foone,
@foone@digipres.club avatar

the worst part is that there's a reference to the clock object which also has to determine if the time is between 3:30 and 3:39.

so they could have just made a clock.isWitchingHour() function and made everyone's lives easier

foone,
@foone@digipres.club avatar

"partsin" turns out to be a false friend: it means "balcony" (genitive of partsi)

ticho,

@foone Amazing thread, thanks for the ... I guess "unbelieving laugh"?

You should post the whole thing to thedailywtf.com :)

foone,
@foone@digipres.club avatar

I'm now working on a plugin. lord help me, monkeypatching C# at runtime is never fun

foone,
@foone@digipres.club avatar

it's the stage-3 of reverse engineering:
static analysis is over
dynamic analysis is over
now it's onto fucking up the program and seeing what exactly breaks

foone,
@foone@digipres.club avatar

what's this function do?
well, replace all the calls to it with a NOP and see what changes

kn100,

@foone a low level form of ScreamOps

foone,
@foone@digipres.club avatar

@kn100 exactly.
if you don't know what a part of a program does, stab it and see where the screams come from

dpnash,

@foone @kn100 Screams come from the server room or a room full of software engineers: possibly recoverable

Screams come from the board room: oh dear, you should probably work on that resume pronto

foone,
@foone@digipres.club avatar

so it turns out MrspookKontrlScript (Mr Spooky Control Script) and PikkuMonsuScripti (Little Monster Script) do exactly the same thing, just with different names.

PROGRAMMERS STOP USING COPY-PASTE CHALLENGE: ALWAYS FAILED

foone,
@foone@digipres.club avatar

the three important variables in this function are h, k, and LiikaaAnomalioitaJotenLoppuhanSeKoittaa

luisfcorreia,
@luisfcorreia@mastodon.social avatar

@foone Too Many Anomalies So The End Will Come

InfiniteNutshell,
@InfiniteNutshell@mastodon.social avatar

@foone a spectre is haunting europe

foone,
@foone@digipres.club avatar

@InfiniteNutshell all right, that tracks

michel,
@michel@masto.nu avatar

@foone I’ve got the popcorn out

miunau,
@miunau@meow.social avatar

@foone the slang and mistypings in these makes me think it was specifically written to fuck with non finnish speakers

owenblacker,
@owenblacker@dataare.cool avatar

@foone 😱😱😱

bison,
@bison@mastodon.social avatar

@foone what is dis abomination?!

grs,

@foone What, the actual fuck, is that. If I was off my tits on quaaludes, I'd still write better code than that.

crobbler,
@crobbler@mastodon.social avatar

@foone Are we absolutely, positively sure we got a copy of the active scene? Better add another one just for good measure.

Is this a human-written if statement or is it a decompiled switch statement gone awry?

davesh,
@davesh@hachyderm.io avatar

@foone awww yeah video game code at its finest

thorsummoner,

@foone this must be real code from a real video game, right?

foone,
@foone@digipres.club avatar

@thorsummoner yup. I'm on observation duty 1

thorsummoner,

@foone tbh I'm helping yandere dev flashbacks

vildis,

@foone kumahdusAanet is really "Kumahdus äänet" which means thumping sounds

foone,
@foone@digipres.club avatar

@vildis Thanks!

czr,
@czr@fosstodon.org avatar

@foone kumahdus = bong / thump (probably bell bong re context), Aanet (äänet) = sounds. kellonKumahduksetSours ~= bell's bongs source (sours is how one would write in rally-english, not a word in Finnish). the choice of expressions (between slang and leet-speak) makes me thing that the person who wrote this wasn't very mature or was writing a joke on purpose.

sebbs,

@foone

I tried in Bing Translate

  • kellon kumahdukset = ringing off the clock
  • kellon kumahdukset sours = bell chimes sours
  • kellon kumahdukset hours = clock ticks hours
  • kellon kumahdukset soida = the ringing of the bell

Tried looking up similar words with accented vowels and didn't find anything. I'm guessing either a typo or an attempt to spell "source"

jope,
@jope@mastodon.social avatar

@foone monsut=monsterit=monsters. Kumahdus i the gong of a bell. Sours is probably finglish for source. Not sure if you wanted this, I don't know when I am allowed to post help on mastodon or not.

dist,

@foone AddBadMonsters or AddToughMonsters or AddEvilMonsters

ddlyh,
@ddlyh@topspicy.social avatar

@foone
... This is Five Nights at Freddie's code, isn't it?

foone,
@foone@digipres.club avatar

@ddlyh close! I'm On Observation Duty 1

tommi,
@tommi@jontka.fi avatar

@foone "Add bad monsters"

fernsehmuell,
@fernsehmuell@chaos.social avatar

@foone you had me at „some punk“!

hendric,
@hendric@astronomy.city avatar

@foone Some Finnish dev somewhere: "We don't talk about 38"

dascandy42,
@dascandy42@mastodon.social avatar

@foone What does it do when it runs out of random events?

foone,
@foone@digipres.club avatar

@dascandy42 I don't think that's possible given how the game works, but if you cheated, and I think the answer is... crash?

scottgal,
@scottgal@hachyderm.io avatar

@foone If you export the project you can edit at your leisure in the likes of VSCOde.

foone,
@foone@digipres.club avatar

@scottgal might be a good idea, yeah.

RedstoneLP2,
@RedstoneLP2@redstonelp2.com avatar

@foone deep thoughts in code

parsingphase,
@parsingphase@m.phase.org avatar

@foone It’s literally a doSomething() function? I didn’t know those bred viably in the wild.

andrea,
@andrea@ubuntu.social avatar

@foone hahaha, I love this. I'm gonna write a function like that in the future 😂

kaia,
@kaia@brotka.st avatar

@foone
you think you cracked the finnofuscation, but the finnofuscation is cracking you :HazeSmug:

RoryMaybe,
@RoryMaybe@mastodon.social avatar

@foone these numbers just suck, sorry to say, and should be left out clearly.

jaykass,

@foone all of these numbers do not exist in the Finnish language

Landa,
@Landa@graz.social avatar

@foone nobody likes those numbers anyway 😂

cpgorski,

@foone sounds like somebody dropped the ball on code reviews

gsuberland,
@gsuberland@chaos.social avatar

@foone for a moment I was wondering if they were trying to avoid excess memory usage via const reference folding (same trick Redis uses for integer values - if you add a hundred million keys pointing to small numbers, the keys just point to const values rather than a new int64 for every key, saving 800MB of RAM) but then realised that in order to do that in .NET you'd need boxed references to the constant integers which sorta defeats the point (unless you're using object collections already)

tedmielczarek,
@tedmielczarek@mastodon.social avatar

@foone are they compiling that code from a different language that enumerates the localized names, do you think? Either way it feels ridiculous!

foone,
@foone@digipres.club avatar

@tedmielczarek pretty sure not, no. There's a lot of manual stuff here that suggests the developer was not exactly the most experienced C# developer, so I doubt this got transpiled from something else

alys,

@foone i try to cut game developers slack since they often don't have the opportunity to refactor, but this part of localization seems basically solved? 😬

baykanguru,

@foone amazing way to enforce good localization, to be honest :)

miki,
@miki@dragonscave.space avatar

@foone There was a thread once in which somebody asked if there’s a tool that would automatically translate all the class names in their app to English, as they were expanding internationally and wanted to hire programmers from other countries. Somebody jokingly replied that the tool they were after was called an intern, but the OP was confused (thinking intern had something to do with internationalization perhaps) and said that Googling for “intern Java” and such didn’t actually bring any useful results and requested a link to the actual tool itself.

TheHerpaDerpaSherpa,

@foone this whole thread is such a joy, probably my favorite thing I've read on mastodon since joining!

thorsummoner,

@foone nature's encryption

kkolakowski,
@kkolakowski@mastodon.social avatar

@foone Hahah! This reminds me pf one of my game porting work, of a very famous PlayStation 1 racing game to Android...

We got sources, which were already ported from PS1 to PSP to iOS, and those original sources were in weird japano-english , with Japanese comments that after all those ports became gibberish because original non-UTF text encoding were lost 😅😅

foone,
@foone@digipres.club avatar

@kkolakowski ahh, yikes. I've had to deal with some source that was shift-jis so funky that it crashes compilers, but eventually I was able to convert it to unicode, nothing was actually lost.

kkolakowski,
@kkolakowski@mastodon.social avatar

@foone I don't remember in details right now, but I tried "simple" stuff, like changing text encoding in Visual Studio 🤔

Comments weren't that helpful anyway (we used quite good abstraction layer called Marmalade back then, and it was already ported to GLES for iOS port)

dist,

@foone
class RoomNumberUpdateScript
class HouseTwoEvents (or SecondHouseEvents)
class uhh what

Who is Mr Spook and what Kontrls him?

hypolite,

@foone There's a classic cryptographic tale that says that the only secret code to never have been deciphered was the language Native Americans spies from the Union used during the American Civil War.

mjfgates,

@foone Kind of a shame they didn't use Hungarian notation in Finnish.

acsawdey,
@acsawdey@fosstodon.org avatar

@foone A different kind of “code talker” … to make reverse engineering annoying, employ programmers who speak uncommon languages and encourage them to use that in their class/function names.

vildis,

@foone
HuoneenNroPaivitysScripti = room number update script
KakkosTalonTapahtumat = second house events
MrspookKontrlScript = monster control script

momo,

@foone
So when they've been asked to finish the game, this is what they came up with?

MishaVanMollusq,
@MishaVanMollusq@sfba.social avatar

@foone omg! Finnish!

rivetgeek,
@rivetgeek@dice.camp avatar

@foone I once administered SQL Server databases for an app that was originally written in Swedish. So it had gems like Slutdatum, Slutid, and Programkanal.

Canageek,
@Canageek@wandering.shop avatar

@foone remind me of a problem someone I knew in grad school had, he was a nuclear physicist needed code to do something, and his professor was like, don't worry I wrote some code for that in grad school.

Send him a Fortran program where all the comments are in Polish.

notecharlie,
@notecharlie@social.bigcavemaps.com avatar

@foone I have spent an unreasonable amount of time reading MetaPost written in Slovak... And that's open-source code.

cvoid,

@foone No one controls Mr. Spook!

r2000,

@foone

  1. RoomNumberUpdateScript
  2. HouseTwoEvents
  3. The 3rd one is basically just English ‘Mrs. Pook Control Script’
drdnar,
@drdnar@hachyderm.io avatar

@foone This is actually the most effective way of keeping out Russian hackers.

neocturne,
@neocturne@chaos.social avatar

@foone Obfuscation tool that replaces all identifiers with Finnish

ely,
@ely@mastodon.green avatar

@foone
Try transliterated Bulgarian.

sundew,
@sundew@mstdn.social avatar

@foone Hmm - "Mr Spook" or "Mrs Pook"?

foone,
@foone@digipres.club avatar

@sundew given that it's a horror game (I'm On Observation Duty 1) I'm pretty sure it's Mr Spook, despite the bad capitalization

rpsu,
@rpsu@mas.to avatar

@foone If you need I can help with the translation. Acronyms are hard to translate unless you actually know the language (I do).
The third one is not in Finnish, though, but looks fairly clear to me anyway.

hamatti,
@hamatti@mastodon.world avatar

@foone I'm gonna start naming my classes as KakkosTalonTapahtumat from now on.

devlin,
@devlin@topspicy.social avatar

@foone to which you say "perkele (pear-ke-le)" and then dig out your favourite translation tool :3

Androp0v,

@foone It would have taken me a while to realize the class names weren’t obfuscated 😂

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • GTA5RPClips
  • DreamBathrooms
  • thenastyranch
  • magazineikmin
  • Durango
  • cubers
  • Youngstown
  • mdbf
  • slotface
  • rosin
  • ngwrru68w68
  • kavyap
  • tacticalgear
  • ethstaker
  • JUstTest
  • InstantRegret
  • Leos
  • normalnudes
  • everett
  • khanakhh
  • osvaldo12
  • cisconetworking
  • modclub
  • anitta
  • tester
  • megavids
  • provamag3
  • lostlight
  • All magazines