Version 1.08 with public source code release.

This commit is contained in:
icex2
2020-10-03 20:56:55 +02:00
parent 656148121d
commit 762bf140c0
555 changed files with 55502 additions and 3 deletions
+50
View File
@@ -0,0 +1,50 @@
#include "hook/core/options.h"
#include "util/options.h"
#define HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file"
#define HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level"
const struct util_options_def hook_core_options_def[] = {
{
.name = HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE,
.description = "Print the log output to the specified file",
.param = 'o',
.type = UTIL_OPTIONS_TYPE_STR,
.default_value.str = "pumptools.log",
},
{
.name = HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL,
.description = "Set the log level (0-4)",
.param = 'l',
.type = UTIL_OPTIONS_TYPE_INT,
.default_value.i = LOG_LEVEL_DEBUG,
},
};
const struct util_options_defs hook_core_options_defs = {
.usage_header = "",
// Just use something because this is not relevant/required here
.usage_param = '\r',
.defs = hook_core_options_def,
.ndefs = lengthof(hook_core_options_def)
};
void hook_core_options_init(int argc, char** argv, struct hook_core_options* options)
{
log_assert(argv);
log_assert(options);
struct util_options_opts* options_opt;
util_options_init(argc, argv);
options_opt = util_options_get(&hook_core_options_defs);
if (!options_opt) {
return;
}
options->log.file = util_options_get_str(options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE);
options->log.level =
(enum util_log_level) util_options_get_int(options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL);
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef HOOK_CORE_OPTIONS_H
#define HOOK_CORE_OPTIONS_H
#include "util/log.h"
struct hook_core_options {
struct log {
const char* file;
enum util_log_level level;
} log;
};
void hook_core_options_init(int argc, char** argv, struct hook_core_options* options);
#endif
+133
View File
@@ -0,0 +1,133 @@
#define LOG_MODULE "hook-core-piu-utils"
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include "hook/core/options.h"
#include "util/fs.h"
#include "util/glibc.h"
#include "util/log.h"
#include "util/proc.h"
#include "util/str.h"
#include "util/sys-info.h"
static void hook_core_piu_log_application_args(int argc, char** argv)
{
const char* sep = "\n";
char* str = util_str_dup("");
char* tmp;
for (int i = 0; i < argc; i++) {
if (strlen(str) > 0) {
tmp = util_str_merge(str, sep);
free(str);
str = tmp;
}
tmp = util_str_merge(str, argv[i]);
free(str);
str = tmp;
}
log_info("Application arguments (%d):\n%s", argc, str);
free(str);
}
void hook_core_piu_log_init(int argc, char** argv)
{
struct hook_core_options options;
hook_core_options_init(argc, argv, &options);
util_log_set_file(options.log.file, false);
util_log_set_level(options.log.level);
}
void hook_core_piu_log_info(int argc, char** argv)
{
log_info("\n"
" _ _ \n"
" _ __ _ _ _ __ ___ _ __ | |_ ___ ___ | |___ \n"
" | '_ \\| | | | '_ ` _ \\| '_ \\| __/ _ \\ / _ \\| / __|\n"
" | |_) | |_| | | | | | | |_) | || (_) | (_) | \\__ \\\n"
" | .__/ \\__,_|_| |_| |_| .__/ \\__\\___/ \\___/|_|___/\n"
" |_| |_| ");
log_info("Pumptools build " __DATE__ " " __TIME__ " gitrev %s", STRINGIFY(GITREV));
util_sys_info_log();
util_proc_log_info();
util_glibc_info_log();
hook_core_piu_log_application_args(argc, argv);
}
char* hook_core_piu_utils_get_and_verify_game_data_path(int argc, char** argv)
{
if (argc < 2) {
log_error("Missing game data path, usage for piu (stock args): piu <game folder> (e.g. piu ./game)");
exit(0);
}
char* game_data_path = util_str_dup(argv[1]);
log_info("Game data path: %s", game_data_path);
/* remove trailing / for the hook. however, the game crashes without it */
if (util_str_ends_with(game_data_path, "/")) {
game_data_path[strlen(game_data_path) - 1] = '\0';
} else {
log_error("Game data path '%s' does not end with a trailing /, exiting because the game is going to "
"crash anyway!", game_data_path);
exit(0);
}
/* depending on the version, the game also just crashes if the game folder or files within it were not found */
if (!util_fs_path_exists(game_data_path)) {
log_error("Game data path '%s' does not exist, exiting", game_data_path);
exit(0);
}
return game_data_path;
}
void hook_core_piu_utils_verify_root_user()
{
log_info("Verifying process is running as root user.");
if (!util_proc_is_running_as_root()) {
log_error("Process not running as root which is required for the game to work correctly.");
//exit(0);
}
}
void hook_core_piu_utils_fix_locale()
{
log_info("Fixing locale settings.");
if (setenv("LC_ALL", "C", 1) != 0) {
log_warn("Setting locale LC_ALL failed.");
}
if (unsetenv("LANGUAGE") != 0) {
log_warn("Unsetting LANGUAGE env var failed.");
}
}
bool hook_core_piu_block_non_piu_process_recursion(int argc, char** argv)
{
/* Sanity check for arguments. If further child processes are started
from the current process, and using LD_PRELOAD on the current process,
all children are also getting the preloaded library. This causes
multiple calls to the trap main function and just crashes our
application at some point.
The executable file is required to contain the "piu" substring to make
this work properly */
if (!strstr(argv[0], "piu")) {
log_warn("Not attaching to non piu process %s", argv[0]);
return true;
} else {
return false;
}
}
+53
View File
@@ -0,0 +1,53 @@
#ifndef HOOK_CORE_PIU_UTILS_H
#define HOOK_CORE_PIU_UTILS_H
/**
* Initialize the logging system as early as possible to allow recording everything to a log file as well.
*/
void hook_core_piu_log_init(int argc, char** argv);
/**
* Log process and system relevant information.
*/
void hook_core_piu_log_info(int argc, char** argv);
/**
* Check and verify the game data path argument passed to the game via argv
*
* Executes various checks and catches errors that might result in the game
* simply crashing without any error indication.
*
* @param argc Argc from piu main
* @param argv Argv from piu main
* @return New string with game data path extracted from argv (caller has to free)
*/
char* hook_core_piu_utils_get_and_verify_game_data_path(int argc, char** argv);
/**
* Verify that the current process is running as root user because the game
* needs access to various devices that require higher privileges.
*
* Does not return and errors if not running as root user.
*/
void hook_core_piu_utils_verify_root_user();
/**
* Fix the locale configuration for Fiesta 2 and newer.
*/
void hook_core_piu_utils_fix_locale();
/**
* If further child processes are started from the current process, and using
* LD_PRELOAD on the current process, all children are also getting the preloaded
* library. This causes multiple calls to the trap main function and just crashes our
* application at some point. The executable file is required to contain the "piu"
* substring to make this work properly.
*
* @param argc Argc from piu main
* @param argv Argv from piu main
* @return True if we have to block this call by another process,
* false if the process calling this is the piu process.
*/
bool hook_core_piu_block_non_piu_process_recursion(int argc, char** argv);
#endif