Post subject: WiP Hourglass Linux Edition
Joined: 7/4/2016
Posts: 1
This is my attempt to recreate Hourglass for Linux. Currently it doesn't do much except dumping some cpu registers of a specified process. Help is very much apreciated, since I am pretty much a noob when it comes to linux (switched to it a few weeks ago). Source is located here if you want to see updates and contribute: https://github.com/newchild/Hourglass-Linux
Warepire
He/Him
Editor
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
First of all you want to research debuggers. Second of all, to achieve any form of stability, you need to launch the process instead of attaching to it, so that you have control from the start. You most likely want control in multiple ways, for Linux you don't need to do any hooking hackery which is nice, just write your replacement .so and LD_PRELOAD it with the debugged process. You will need to do some sort of API replacement to achieve the necessary determinism required to do input replay etc across systems. Thirdly ... how did you end up requiring sudo? gdb doesn't and it can do the same things.
morningpee
They/Them
Player (56)
Joined: 11/28/2013
Posts: 119
Warepire wrote:
You will need to do some sort of API replacement to achieve the necessary determinism required to do input replay etc across systems.
That is recreating a lot of things that linux containers have already achieved. Being more strict, requiring the TASer to simplify his own environment or play a game in a lxc may not be nice, but it simplifies the process of recreating Hourglass for Linux. Hourglass for Windows accepts most executables and fails 95% of the time.
Warepire wrote:
Thirdly ... how did you end up requiring sudo? gdb doesn't and it can do the same things.
Running everything in userspace might take awhile because you start using tricks like "LD_PRELOAD" before you hit any dead ends. If he starts top-down, using linux containers, he can keep requiring sudo without exposing his system.
Projects: Tetris DS Genesis Toys: Let the Toy Wars Begin
Warepire
He/Him
Editor
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
morningpee wrote:
Warepire wrote:
You will need to do some sort of API replacement to achieve the necessary determinism required to do input replay etc across systems.
That is recreating a lot of things that linux containers have already achieved. Being more strict, requiring the TASer to simplify his own environment or play a game in a lxc may not be nice, but it simplifies the process of recreating Hourglass for Linux. Hourglass for Windows accepts most executables and fails 95% of the time.
He'll still need to override reads from /dev/random etc to a pseudo-rng with a seed he can control. It's probably easier to LD_PRELOAD that than creating his own device-node to link in as /dev/random, /dev/urandom etc in a contained environment. But a lot can probably be achieved through the container infrastructure, assuming the kernel can handle a container being ripped out of existence and replaced with an earlier/later version.
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11475
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Editor, Player (44)
Joined: 7/11/2010
Posts: 1029
I'd recommend using system call interception rather than LD_PRELOAD. I've had some experiments in this direction myself. Containers are definitely the way to go in order to get a lot of reproducibility for free. (For things like /dev/random, I suspect the simplest method is to put a FIFO there – you're in a container so you have control over the filesystem – and attach the not-an-emulator to the other end of the FIFO. You could arguably even just make it a regular file with contents determined by the TASer, most games won't notice.) More difficult is making things like the memory map reproducible. Linux actually has system calls for this (see prctl); you probably also want to look into the personality system call, that you can use to turn off ASLR. The hardest part, though, and the one that gives me the most trouble and pretty much stalled my project, is scheduling. Linux isn't very good at giving userspace control over scheduling because it's hard to know, before you try to run it, whether a system call will block or not, and you need to know that to schedule correctly; I'm actually considering trying to handle the problem with a kernel patch (I think that it'd be possible to persuade the Linux developers to accept it, because there are several different scenarios in which the patch in question would be useful). Unfortunately, you're necessarily going to end up facing multiple processes with pretty much any game because X is a separate process. Some games can run without X, but tend to be buggy without it (e.g. Battle for Wesnoth has obvious graphical glitches), so some way to simulate X is needed. I'd recommend throwing xvfb into the container rather than trying to emulate X yourself. All this does is handle half the problem of making a TASing system, that of giving you deterministic behaviour given fixed inputs. (Recording and playback is pretty easy once you have that, so I don't really count it as a major part of the problem.) The other half is handling rerecording, that is, the savestating and loadstating. There are two separate ways to do this; nethack-tas-tools (which is all about savestates and loadstates, really) uses a VM, whereas CRIU attempts to do it directly in loadstating (and is something dwangoAC is considering for the future of nethack-tas-tools).