diff options
author | Clément Gallet <clement.gallet@ens-lyon.org> | 2024-02-15 16:02:36 +0100 |
---|---|---|
committer | Clément Gallet <clement.gallet@ens-lyon.org> | 2024-02-15 16:02:36 +0100 |
commit | b633f9923deb77f30895d80a81c097624a68011a (patch) | |
tree | f3704a2caa14a29d52022c84e0accbf57dd9cfa1 | |
parent | 95a71ae759ac369c866f80c2dfac92b9e28a5ea8 (diff) |
Hook getrandom()
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/library/fileio/URandom.cpp | 25 | ||||
-rw-r--r-- | src/library/fileio/URandom.h | 4 | ||||
-rw-r--r-- | src/library/general/randomwrappers.cpp | 12 | ||||
-rw-r--r-- | src/library/general/randomwrappers.h | 5 |
5 files changed, 38 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d32ade5..268667d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Autodetect game engine and enforce some settings * [ImGui] When detached, game window can be resized * Disable a dotnet speed check (#590) +* Hook getrandom() ### Changed diff --git a/src/library/fileio/URandom.cpp b/src/library/fileio/URandom.cpp index 6c9ac2fa..2d250ddd 100644 --- a/src/library/fileio/URandom.cpp +++ b/src/library/fileio/URandom.cpp @@ -35,21 +35,28 @@ static int writefd = -1; static FILE* stream = nullptr; static uint64_t prng_state = 0; -static void urandom_handler(int signum) +uint64_t urandom_rand() { - debuglogstdio(LCF_FILEIO | LCF_RANDOM, "Filling urandom fd"); if (!prng_state) prng_state = Global::shared_config.initial_time_sec; + /* Use xorshift64* algorithm to generate pseudo-random values */ + uint64_t r = prng_state; /* The state must be seeded with a nonzero value. */ + r ^= r >> 12; + r ^= r << 25; + r ^= r >> 27; + prng_state = r; + r *= 0x2545F4914F6CDD1DULL; + return r; +} + +static void urandom_handler(int signum) +{ + debuglogstdio(LCF_FILEIO | LCF_RANDOM, "Filling urandom fd"); + int err = 0; do { - /* Use xorshift64* algorithm to generate pseudo-random values */ - uint64_t r = prng_state; /* The state must be seeded with a nonzero value. */ - r ^= r >> 12; - r ^= r << 25; - r ^= r >> 27; - prng_state = r; - r *= 0x2545F4914F6CDD1DULL; + uint64_t r = urandom_rand(); err = write(writefd, &r, sizeof(uint64_t)); } while (err != -1); } diff --git a/src/library/fileio/URandom.h b/src/library/fileio/URandom.h index 0195649f..711f0d39 100644 --- a/src/library/fileio/URandom.h +++ b/src/library/fileio/URandom.h @@ -21,9 +21,13 @@ #define LIBTAS_URANDOM_H_INCLUDED #include <cstdio> +#include <cstdint> namespace libtas { +/* Generate a single random 64-bit value */ +uint64_t urandom_rand(); + /* Creates a fd implementing our own deterministic /dev/urandom */ int urandom_create_fd(); diff --git a/src/library/general/randomwrappers.cpp b/src/library/general/randomwrappers.cpp index e5aaf672..7af2d666 100644 --- a/src/library/general/randomwrappers.cpp +++ b/src/library/general/randomwrappers.cpp @@ -21,12 +21,24 @@ #include "logging.h" #include "hook.h" +#include "fileio/URandom.h" namespace libtas { DEFINE_ORIG_POINTER(random) DEFINE_ORIG_POINTER(rand) +/* Override */ ssize_t getrandom (void *buffer, size_t length, unsigned int flags) +{ + char* buf = static_cast<char*>(buffer); + /* We use the same PRNG as in URandom, because it is supposed to get the same values */ + for (size_t l = 0; l < length; l += 8) { + uint64_t r = urandom_rand(); + memcpy(buf+l, &r, std::min((size_t)8, length-l)); + } + return length; +} + /* Override */ long int random (void) __THROW { static int count = 0; diff --git a/src/library/general/randomwrappers.h b/src/library/general/randomwrappers.h index 38b93f75..91f7272c 100644 --- a/src/library/general/randomwrappers.h +++ b/src/library/general/randomwrappers.h @@ -24,9 +24,14 @@ #include <cstdint> #include <cstddef> +#include <sys/types.h> // ssize_t namespace libtas { +/* Write LENGTH bytes of randomness starting at BUFFER. Return the + number of bytes written, or -1 on error. */ +OVERRIDE ssize_t getrandom (void *buffer, size_t length, unsigned int flags); + /* These are the functions that actually do things. The `random', `srandom', `initstate' and `setstate' functions are those from BSD Unices. The `rand' and `srand' functions are required by the ANSI standard. |