summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Gallet <clement.gallet@ens-lyon.org>2024-02-15 16:02:36 +0100
committerClément Gallet <clement.gallet@ens-lyon.org>2024-02-15 16:02:36 +0100
commitb633f9923deb77f30895d80a81c097624a68011a (patch)
treef3704a2caa14a29d52022c84e0accbf57dd9cfa1
parent95a71ae759ac369c866f80c2dfac92b9e28a5ea8 (diff)
Hook getrandom()
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/library/fileio/URandom.cpp25
-rw-r--r--src/library/fileio/URandom.h4
-rw-r--r--src/library/general/randomwrappers.cpp12
-rw-r--r--src/library/general/randomwrappers.h5
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.