[HN Gopher] Show HN: Tetris, but the blocks are ARM instructions...
___________________________________________________________________
Show HN: Tetris, but the blocks are ARM instructions that execute
in the browser
OFRAK Tetris is a project I started at work about two weeks ago.
It's a web-based game that works on desktop and mobile. I made it
for my company to bring to events like DEF CON, and to promote our
binary analysis and patching framework called OFRAK. In the game,
32-bit, little-endian ARM assembly instructions fall, and you can
modify the operands before executing them on a CPU emulator. There
are two segments mapped - one for instructions, and one for data
(though both have read, write, and execute permissions). Your score
is a four byte signed integer stored at the virtual address pointed
to by the R12 register, and the goal is to use the instructions
that fall to make the score value in memory as high as possible.
When it's game over, you can download your game as an ELF to relive
the glory in GDB on your favorite ARM device. The CPU emulator is
a version of Unicorn (https://www.unicorn-engine.org/) that has
been cross-compiled to WebAssembly
(https://alexaltea.github.io/unicorn.js/), so everything on the
page runs in the browser without the need for any complicated
infrastructure on the back end. Since I've only been working on
this for a short period of time leading up to its debut at DEF CON,
there are still many more features I'd eventually like to
implement. These include adding support for other ISAs besides ARM,
adding an instruction reference manual, and lots of little
cleanups, bug fixes, and adjustments. My highest score is
509,644,979, but my average is about 131,378. I look forward to
feedback, bug reports, feature requests, and strategy discussions!
Author : jstrieb
Score : 428 points
Date : 2023-08-10 23:56 UTC (1 days ago)
(HTM) web link (ofrak.com)
(TXT) w3m dump (ofrak.com)
| shaunxcode wrote:
| Beautiful brutalist ui/ux!
| Lapsa wrote:
| yeah... wanted to leave a comment I dig the aesthetics.
| LoganSnow wrote:
| This is really cool! So far I have a high score of 65612 :)
|
| Some feedback:
|
| - When opening the help menu, it wasn't obvious how to close it
| (I think the only way is by pressing '?')
|
| - I like the Goblin music!
|
| - It's a pretty nice interface to play with the instructions and
| I appreciate the color coding. It would be neat if there was a
| "sandbox mode" where you could preview the effects of running an
| instruction, and maybe modify your program once the game is over.
| I could see this being pretty useful for someone learning ARM
| assembly.
| jstrieb wrote:
| I like the idea of sandbox mode!
|
| I'm definitely much quicker at reading ARM assembly after
| playing a few hours of this game over the course of making it.
| mpeg wrote:
| This is so clever, I couldn't help but smile when I saw "Your
| score is stored in memory at the address pointed to by R12" :)
|
| Thanks for sharing, it does makes me miss DEFCON, maybe next
| year...
| velosol wrote:
| Is the reason for R12 making you smile something you could
| share?
| mpeg wrote:
| It's the fact that the score is handled within the game
| mechanics itself - so the way to get a high score is not just
| to play but to play with the goal of modifying R12 (so it
| points to a high value)
|
| They could have easily made score be handled outside the game
| and you get a point per every executed statement within the
| time limit etc - but that would not be as fun
| Jerry8538 wrote:
| > Your score is stored in memory at the address pointed to by
| R12
|
| As someone who has very little idea of what instructions or
| addresses are, what is this a reference to?
|
| Edit: I had the page loaded before your reply, so I didn't see
| it until I replied, reloading the page lol
| justsid wrote:
| It's not a reference, it's just a really neat game mechanic.
| Normally the high score is guarded by the game and changes
| only if the game deems it fit to change it. In this game,
| because the high score is accessible within the game and you
| can execute arbitrary instructions, you can use that to
| modify the high score.
|
| It's as if in a more normal game the high score was kept in a
| big chest somewhere in the game world and once discovered you
| can start messing with the contents of it all within the
| rules of the world itself.
| __s wrote:
| That game is Zelda on N64
|
| https://www.zeldaspeedruns.com/oot/tech/get-item-
| manipulatio...
|
| https://www.zeldaspeedruns.com/oot/ba/reverse-bottle-
| adventu...
| tiborsaas wrote:
| Very cool concept, but my assembly understanding is really poor
| :)
|
| It says that my score is stored in R12, but then why do I have a
| score of 16 of R12 is zero?
|
| https://imgur.com/a/RY5jhTu
| jstrieb wrote:
| R12 contains the address of your score. In this case, that is
| address 0 - the start of the data segment.
|
| The score register is yellow, and the corresponding memory
| region it points to (the actual bytes of your score) are also
| yellow.
| tiborsaas wrote:
| Thank you, it makes sense now.
|
| If you'd like to do a video tutorial how to play this well
| that could be a great resource to learn assembly intuitively.
| jstrieb wrote:
| So far, I've used two good strategies:
|
| - Spray PC into as many registers as possible, try to add those
| registers together as many times as possible, and store the sum
| at zero (or wherever the score ends up)
|
| - Load an assembled instruction from an old value of PC as an int
| into a register, then do some subtraction to make it non-negative
| (since it's usually negative in my experience), then store in the
| score location
|
| I'm curious what other strategies people have tried?
| stavros wrote:
| I've had a lot of success segfaulting the game, as I don't know
| any assembly.
| alex_suzuki wrote:
| Peak nerddom - awesome.
| ant6n wrote:
| Showing the next instruction would be helpful.
| gmerc wrote:
| Very cool!
| diydsp wrote:
| Trying to figure it out, I got 552 Million :)
|
| Great concept! I'm afraid to show it to my team of C++ developers
| bc they might be tempted to switch over to doing everything in
| Assembly :)
| xtracto wrote:
| This is just amazing :) kudos!
| personjerry wrote:
| I'm computer literate (and know some basic assembly) but wow I
| did not get it
| jstrieb wrote:
| Hey, any specific questions? I'd be happy to explain anything
| that needs clarification.
|
| More broadly, any thoughts on how to make the game clearer? I
| know that a manual describing the instructions would help. But
| other ideas are welcome as well!
| rpgwaiter wrote:
| Maybe a way to break down a game after it happened, or maybe
| a sandbox mode to try arbitrary things
| ithkuil wrote:
| I don't understand what "rotate the instruction order" keys
| do. I tried pressing them in many circumstances and nothing
| happens
| jstrieb wrote:
| Yeah, I may have sacrificed clarity for concision in this
| case.
|
| To answer by way of example, if you are given "add R1, R2,
| R3" rotating to the right will result in "add R2, R3, R4".
| As another example, rotating "mov LR, R0" to the left will
| give "mov R12, SP".
|
| In other words, rotating right changes every register RN in
| the instruction to be the register R(N + 1). Left changes
| RN to R(N - 1).
|
| My hope was that if it was not clear from reading, it would
| be after testing things out. But hearing that this may not
| be the case is helpful feedback!
| jstrieb wrote:
| Oh, my bad, I misread your question.
|
| See a reply to your original comment: it changes the
| order for gadgets larger than one instruction. The
| default is one, but originally it was three, so the
| instructions stuck.
|
| I will make those confusing instructions only show up
| when the gadget size is greater than one! This feels like
| a good change to make based on this feedback.
| rft wrote:
| Just figured it out. If you select "Adjust Difficulty" and
| increase the max gadget size (number of instructions that
| can fall at once) you change their order with these keys.
|
| P.S. thank you for nerd sniping me with this game, I love
| the idea and execution (pun slightly intended)!
| jstrieb wrote:
| Thanks for the kind words! This comment helped me realize
| that I had misunderstood the parent commenter's question.
|
| I have just pushed an update so that the up/down arrow
| keys only show up in the instructions if the max gadget
| size is greater than one.
| joshxyz wrote:
| i code frontend and backend web apps in javascript and
| typescript, very comfy with cloud stufd
|
| but oh boy these assembly stuff these are heiroglyphs to me
| haha
| westurner wrote:
| ASM years ago. MOV'ing without any initial data feels unnerving.
| WASM and JupyterLite would be cool, too.
|
| Category:Instruction_set_listings has x86 but no aarch64:
| https://en.wikipedia.org/wiki/Category:Instruction_set_listi...
|
| /? jupyter asm [kernel]:
|
| - "Introduction to Assembly Language Tutorial.ipynb" w/ the emu86
| jupyter kernel which shows register state after ops:
| https://github.com/gcallah/Emu86/blob/master/kernels/Introdu...
|
| - it looks like emu86 already also supports RISC, MIPS, and WASM
| but not yet ARM:
| https://github.com/gcallah/Emu86/blob/master/assembler/WASM/...
|
| - DeepHorizons/iarm:
| https://github.com/DeepHorizons/iarm/blob/master/iarm_kernel...
| https://github.com/DeepHorizons/iarm/blob/master/iarm/arm_in...
| MOV
| https://github.com/DeepHorizons/iarm/blob/master/tests/iarm/... :
|
| > _IArm is an ARM interpreter for the ARMv6 THUMB instruction set
| (More specifically for the ARM Cortex M0+ CPU). It supports
| almost 100% of the instructions, and some assembler directives.
| There is also its Jupyter kernel counterpart so it can be used
| with Jupyter notebooks._
|
| - JupyterLite > Adding other kernels; emu86, iarm, WASM, :
| https://jupyterlite.readthedocs.io/en/latest/howto/configure...
| [...
| https://github.com/jupyterlite/jupyterlite/discussions/968#d... ]
|
| "Ask HN: How did you learn x86-64 assembly?" (2020) re: HLA, :
| https://news.ycombinator.com/item?id=23931373 re: the Diaphora
| bindiff tool and ghidra, which has GDB support now FWIU:
| https://news.ycombinator.com/item?id=36454485
| [deleted]
| once_inc wrote:
| As a programmer with practically 0 experience in working with
| assembly, this is a pretty cool tool to learn! I've been holding
| a cheatsheet in another tab to find out what each instruction is
| doing.
|
| Kudos for building this, very cool!
|
| edit: getting -4.8 billion as a high score because of my first
| segfault was... a disappointment, though. :-P
| foota wrote:
| Nop is blue bar?
| cushpush wrote:
| My score is -50100627
| [deleted]
| latexr wrote:
| Before trying it I hit "About" and it opened a new page which
| says:
|
| > By continuing to use this site, you agree to the use of
| cookies.
|
| You seem to be in violation of the GDPR. There _must_ be a way to
| refuse the cookies that is as simple as accepting them.
| Especially since yours are not needed for the site to function:
|
| > The Services use cookies and similar technologies such as pixel
| tags, web beacons, clear GIFs and JavaScript (collectively,
| "Cookies") to enable our servers to recognize your web browser,
| tell us how and when you visit and use our Services, analyze
| trends, learn about our user base and operate and improve our
| Services. (...) We may also supplement the information we collect
| from you with information received from third parties, including
| third parties that have placed their own Cookies on your
| device(s).
|
| https://ofrak.com/privacy/#tracking-tools-and-opt-out
|
| Telling people to delete cookies via their browser settings
| (further down that page) is not an acceptable solution.
| chronogram wrote:
| It's not even storing anything illegal on my end, only the game
| settings, so I don't know why it shows that banner.
| fuomag9 wrote:
| Unfortunately this practice has been happening with a lot of
| websites, and many companies are not complaining with the
| cookie law
|
| https://www.cnil.fr/en/refusing-cookies-should-be-easy-accep...
| sabas123 wrote:
| Not sure if it's an error from using autocorrect, but you
| probably want to use complying instead of complaining.
| hooch wrote:
| Telling site visitors to disable cookies via their browser is
| precisely how apple.com does it.
| latexr wrote:
| Even if Apple is in violation, that doesn't make it
| acceptable or within the law. Big companies (notably Meta)
| frequently don't comply with GDPR and are beginning to pay
| the price for it and making changes.
|
| https://noyb.eu/en/5-years-litigation-meta-apparently-
| switch...
|
| I was pleasantly surprised to see Apple's cookie policy is
| considerably less intrusive than the submitted website's.
|
| https://www.apple.com/legal/privacy/en-ww/cookies/
| matsemann wrote:
| GDPR doesn't care about cookies. It depends on what they're
| used for. If they're not used for tracking or storing
| personal information, GDPR doesn't apply.
|
| It's easy to read the original comment as if you need to ask
| permission for any cookie usage. But that's not what they're
| saying. They're saying it applies for this site's cookies, as
| the site specify they use cookies in a way that GDPR would
| say you need consent for.
| runlaszlorun wrote:
| omg, this is awesome. i'd been meaning to pick up some ARM
| assembly. and the fact that you managed to link game mechanics
| with working opcodes is great.
|
| love it!
| hnpl wrote:
| I really like the concept!
|
| The key to achieve high scores seems to be writing 0 to PC. The
| reason is the binary code of new instructions will be "added" to
| the memory region that is visible on the right, then we can
| manipulate R12 to maximize the score.
| ithkuil wrote:
| wow, you can even remap the keys!
| jstrieb wrote:
| It also works with USB gamepads!
|
| At DEF CON where we will have this set up in-person tomorrow,
| we will have people playing on a USB Dance Dance Revolution
| floor pad.
| thisOtterBeGood wrote:
| What an amazing idea.
|
| Another thing to make the entry easier: Create a "Memory"
| label for the memory area. You mention it in the intro text
| but color it in the R12 address color which was confusing for
| me.
|
| Missed that memory space totally while playing the first two
| times.
| murkle wrote:
| Cool! Does that use the Gamepad API or WebHID? I'd like to
| get one working in the browser for one of my projects
| jstrieb wrote:
| Uses the Gamepad API. I found it very easy to work with, in
| large part thanks to the corresponding MDN docs.
|
| The only weird part about the Gamepad API is that you have
| to poll it rather than handling events the way you normally
| would for other, similar stuff in JavaScript. In practice,
| this means that you have to do your own debouncing for
| handling things like key combos, but that doesn't really
| affect individual button presses too much.
| murkle wrote:
| Magic, thanks! Which model mat do you have?
|
| It might be worth trying with WebHID instead of the
| GamePad API. Quick example with a joystick :)
|
| https://murkle.github.io/utils/webhid/logitech_attack3.ht
| ml
| murkle wrote:
| ... and a quick example with a very cheap USB Dance Mat
| https://murkle.github.io/utils/webhid/dance_mat.html
___________________________________________________________________
(page generated 2023-08-12 23:02 UTC)