chore: CRLF to LF

This commit is contained in:
smpn2
2022-12-16 23:18:35 +09:00
parent b7a60638a4
commit 6c914266d9
725 changed files with 131020 additions and 131020 deletions
+177 -177
View File
@@ -1,177 +1,177 @@
#include "analogs.h"
#include <functional>
#include "external/rapidjson/document.h"
#include "misc/eamuse.h"
#include "cfg/analog.h"
#include "launcher/launcher.h"
#include "games/io.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
Analogs::Analogs() : Module("analogs") {
functions["read"] = std::bind(&Analogs::read, this, _1, _2);
functions["write"] = std::bind(&Analogs::write, this, _1, _2);
functions["write_reset"] = std::bind(&Analogs::write_reset, this, _1, _2);
analogs = games::get_analogs(eamuse_get_game());
}
/**
* read()
*/
void Analogs::read(api::Request &req, Response &res) {
// check analog cache
if (!analogs) {
return;
}
// add state for each analog
for (auto &analog : *this->analogs) {
Value state(kArrayType);
Value analog_name(analog.getName().c_str(), res.doc()->GetAllocator());
Value analog_state(GameAPI::Analogs::getState(RI_MGR, analog));
Value analog_enabled(analog.override_enabled);
state.PushBack(analog_name, res.doc()->GetAllocator());
state.PushBack(analog_state, res.doc()->GetAllocator());
state.PushBack(analog_enabled, res.doc()->GetAllocator());
res.add_data(state);
}
}
/**
* write([name: str, state: float], ...)
*/
void Analogs::write(Request &req, Response &res) {
// check analog cache
if (!analogs)
return;
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 2) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
if (!param[1].IsFloat() && !param[1].IsInt()) {
error_type(res, "state", "float");
continue;
}
// get params
auto analog_name = param[0].GetString();
auto analog_state = param[1].GetFloat();
// write analog state
if (!this->write_analog(analog_name, analog_state)) {
error_unknown(res, "analog", analog_name);
continue;
}
}
}
/**
* write_reset()
* write_reset([name: str], ...)
*/
void Analogs::write_reset(Request &req, Response &res) {
// check analog cache
if (!analogs)
return;
// get params
auto params = req.params.GetArray();
// write_reset()
if (params.Size() == 0) {
if (analogs != nullptr) {
for (auto &analog : *this->analogs) {
analog.override_enabled = false;
}
}
return;
}
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 1) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
// get params
auto analog_name = param[0].GetString();
// write analog state
if (!this->write_analog_reset(analog_name)) {
error_unknown(res, "analog", analog_name);
continue;
}
}
}
bool Analogs::write_analog(std::string name, float state) {
// check analog cache
if (!this->analogs) {
return false;
}
// find analog
for (auto &analog : *this->analogs) {
if (analog.getName() == name) {
analog.override_state = CLAMP(state, 0.f, 1.f);
analog.override_enabled = true;
return true;
}
}
// unknown analog
return false;
}
bool Analogs::write_analog_reset(std::string name) {
// check analog cache
if (!analogs) {
return false;
}
// find analog
for (auto &analog : *this->analogs) {
if (analog.getName() == name) {
analog.override_enabled = false;
return true;
}
}
// unknown analog
return false;
}
}
#include "analogs.h"
#include <functional>
#include "external/rapidjson/document.h"
#include "misc/eamuse.h"
#include "cfg/analog.h"
#include "launcher/launcher.h"
#include "games/io.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
Analogs::Analogs() : Module("analogs") {
functions["read"] = std::bind(&Analogs::read, this, _1, _2);
functions["write"] = std::bind(&Analogs::write, this, _1, _2);
functions["write_reset"] = std::bind(&Analogs::write_reset, this, _1, _2);
analogs = games::get_analogs(eamuse_get_game());
}
/**
* read()
*/
void Analogs::read(api::Request &req, Response &res) {
// check analog cache
if (!analogs) {
return;
}
// add state for each analog
for (auto &analog : *this->analogs) {
Value state(kArrayType);
Value analog_name(analog.getName().c_str(), res.doc()->GetAllocator());
Value analog_state(GameAPI::Analogs::getState(RI_MGR, analog));
Value analog_enabled(analog.override_enabled);
state.PushBack(analog_name, res.doc()->GetAllocator());
state.PushBack(analog_state, res.doc()->GetAllocator());
state.PushBack(analog_enabled, res.doc()->GetAllocator());
res.add_data(state);
}
}
/**
* write([name: str, state: float], ...)
*/
void Analogs::write(Request &req, Response &res) {
// check analog cache
if (!analogs)
return;
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 2) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
if (!param[1].IsFloat() && !param[1].IsInt()) {
error_type(res, "state", "float");
continue;
}
// get params
auto analog_name = param[0].GetString();
auto analog_state = param[1].GetFloat();
// write analog state
if (!this->write_analog(analog_name, analog_state)) {
error_unknown(res, "analog", analog_name);
continue;
}
}
}
/**
* write_reset()
* write_reset([name: str], ...)
*/
void Analogs::write_reset(Request &req, Response &res) {
// check analog cache
if (!analogs)
return;
// get params
auto params = req.params.GetArray();
// write_reset()
if (params.Size() == 0) {
if (analogs != nullptr) {
for (auto &analog : *this->analogs) {
analog.override_enabled = false;
}
}
return;
}
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 1) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
// get params
auto analog_name = param[0].GetString();
// write analog state
if (!this->write_analog_reset(analog_name)) {
error_unknown(res, "analog", analog_name);
continue;
}
}
}
bool Analogs::write_analog(std::string name, float state) {
// check analog cache
if (!this->analogs) {
return false;
}
// find analog
for (auto &analog : *this->analogs) {
if (analog.getName() == name) {
analog.override_state = CLAMP(state, 0.f, 1.f);
analog.override_enabled = true;
return true;
}
}
// unknown analog
return false;
}
bool Analogs::write_analog_reset(std::string name) {
// check analog cache
if (!analogs) {
return false;
}
// find analog
for (auto &analog : *this->analogs) {
if (analog.getName() == name) {
analog.override_enabled = false;
return true;
}
}
// unknown analog
return false;
}
}
+28 -28
View File
@@ -1,28 +1,28 @@
#pragma once
#include <vector>
#include "api/module.h"
#include "api/request.h"
#include "cfg/api.h"
namespace api::modules {
class Analogs : public Module {
public:
Analogs();
private:
// state
std::vector<Analog> *analogs;
// function definitions
void read(Request &req, Response &res);
void write(Request &req, Response &res);
void write_reset(Request &req, Response &res);
// helper
bool write_analog(std::string name, float state);
bool write_analog_reset(std::string name);
};
}
#pragma once
#include <vector>
#include "api/module.h"
#include "api/request.h"
#include "cfg/api.h"
namespace api::modules {
class Analogs : public Module {
public:
Analogs();
private:
// state
std::vector<Analog> *analogs;
// function definitions
void read(Request &req, Response &res);
void write(Request &req, Response &res);
void write_reset(Request &req, Response &res);
// helper
bool write_analog(std::string name, float state);
bool write_analog_reset(std::string name);
};
}
+28 -28
View File
@@ -1,28 +1,28 @@
#pragma once
#include <vector>
#include "api/module.h"
#include "api/request.h"
#include "cfg/api.h"
namespace api::modules {
class Buttons : public Module {
public:
Buttons();
private:
// state
std::vector<Button> *buttons;
// function definitions
void read(Request &req, Response &res);
void write(Request &req, Response &res);
void write_reset(Request &req, Response &res);
// helper
bool write_button(std::string name, float state);
bool write_button_reset(std::string name);
};
}
#pragma once
#include <vector>
#include "api/module.h"
#include "api/request.h"
#include "cfg/api.h"
namespace api::modules {
class Buttons : public Module {
public:
Buttons();
private:
// state
std::vector<Button> *buttons;
// function definitions
void read(Request &req, Response &res);
void write(Request &req, Response &res);
void write_reset(Request &req, Response &res);
// helper
bool write_button(std::string name, float state);
bool write_button_reset(std::string name);
};
}
+82 -82
View File
@@ -1,82 +1,82 @@
#include "capture.h"
#include <functional>
#include "external/rapidjson/document.h"
#include "hooks/graphics/graphics.h"
#include "util/crypt.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
static thread_local std::vector<uint8_t> CAPTURE_BUFFER;
Capture::Capture() : Module("capture") {
functions["get_screens"] = std::bind(&Capture::get_screens, this, _1, _2);
functions["get_jpg"] = std::bind(&Capture::get_jpg, this, _1, _2);
}
/**
* get_screens()
*/
void Capture::get_screens(Request &req, Response &res) {
// aquire screens
std::vector<int> screens;
graphics_screens_get(screens);
// add screens to response
for (auto &screen : screens) {
res.add_data(screen);
}
}
/**
* get_jpg([screen=0, quality=70, downscale=0, divide=1])
* screen: uint specifying the window
* quality: uint in range [0, 100]
* reduce: uint for dividing image size
*/
void Capture::get_jpg(Request &req, Response &res) {
CAPTURE_BUFFER.reserve(1024 * 128);
// settings
int screen = 0;
int quality = 70;
int divide = 1;
if (req.params.Size() > 0 && req.params[0].IsUint())
screen = req.params[0].GetUint();
if (req.params.Size() > 1 && req.params[1].IsUint())
quality = req.params[1].GetUint();
if (req.params.Size() > 2 && req.params[2].IsUint())
divide = req.params[2].GetUint();
// receive JPEG data
uint64_t timestamp = 0;
int width = 0;
int height = 0;
graphics_capture_trigger(screen);
bool success = graphics_capture_receive_jpeg(screen, [] (uint8_t byte) {
CAPTURE_BUFFER.push_back(byte);
}, true, quality, true, divide, &timestamp, &width, &height);
if (!success) {
return;
}
// encode to base64
auto encoded = crypt::base64_encode(
CAPTURE_BUFFER.data(),
CAPTURE_BUFFER.size());
// clear buffer
CAPTURE_BUFFER.clear();
// add data to response
Value data;
data.SetString(encoded.c_str(), encoded.length(), res.doc()->GetAllocator());
res.add_data(timestamp);
res.add_data(width);
res.add_data(height);
res.add_data(data);
}
}
#include "capture.h"
#include <functional>
#include "external/rapidjson/document.h"
#include "hooks/graphics/graphics.h"
#include "util/crypt.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
static thread_local std::vector<uint8_t> CAPTURE_BUFFER;
Capture::Capture() : Module("capture") {
functions["get_screens"] = std::bind(&Capture::get_screens, this, _1, _2);
functions["get_jpg"] = std::bind(&Capture::get_jpg, this, _1, _2);
}
/**
* get_screens()
*/
void Capture::get_screens(Request &req, Response &res) {
// aquire screens
std::vector<int> screens;
graphics_screens_get(screens);
// add screens to response
for (auto &screen : screens) {
res.add_data(screen);
}
}
/**
* get_jpg([screen=0, quality=70, downscale=0, divide=1])
* screen: uint specifying the window
* quality: uint in range [0, 100]
* reduce: uint for dividing image size
*/
void Capture::get_jpg(Request &req, Response &res) {
CAPTURE_BUFFER.reserve(1024 * 128);
// settings
int screen = 0;
int quality = 70;
int divide = 1;
if (req.params.Size() > 0 && req.params[0].IsUint())
screen = req.params[0].GetUint();
if (req.params.Size() > 1 && req.params[1].IsUint())
quality = req.params[1].GetUint();
if (req.params.Size() > 2 && req.params[2].IsUint())
divide = req.params[2].GetUint();
// receive JPEG data
uint64_t timestamp = 0;
int width = 0;
int height = 0;
graphics_capture_trigger(screen);
bool success = graphics_capture_receive_jpeg(screen, [] (uint8_t byte) {
CAPTURE_BUFFER.push_back(byte);
}, true, quality, true, divide, &timestamp, &width, &height);
if (!success) {
return;
}
// encode to base64
auto encoded = crypt::base64_encode(
CAPTURE_BUFFER.data(),
CAPTURE_BUFFER.size());
// clear buffer
CAPTURE_BUFFER.clear();
// add data to response
Value data;
data.SetString(encoded.c_str(), encoded.length(), res.doc()->GetAllocator());
res.add_data(timestamp);
res.add_data(width);
res.add_data(height);
res.add_data(data);
}
}
+18 -18
View File
@@ -1,18 +1,18 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Capture : public Module {
public:
Capture();
private:
// function definitions
void get_screens(Request &req, Response &res);
void get_jpg(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Capture : public Module {
public:
Capture();
private:
// function definitions
void get_screens(Request &req, Response &res);
void get_jpg(Request &req, Response &res);
};
}
+17 -17
View File
@@ -1,17 +1,17 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Card : public Module {
public:
Card();
private:
// function definitions
void insert(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Card : public Module {
public:
Card();
private:
// function definitions
void insert(Request &req, Response &res);
};
}
+20 -20
View File
@@ -1,20 +1,20 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Coin : public Module {
public:
Coin();
private:
// function definitions
void get(Request &req, Response &res);
void set(Request &req, Response &res);
void insert(Request &req, Response &res);
void blocker_get(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Coin : public Module {
public:
Coin();
private:
// function definitions
void get(Request &req, Response &res);
void set(Request &req, Response &res);
void insert(Request &req, Response &res);
void blocker_get(Request &req, Response &res);
};
}
+180 -180
View File
@@ -1,180 +1,180 @@
#include "control.h"
#include <csignal>
#include <functional>
#include "external/rapidjson/document.h"
#include "launcher/shutdown.h"
#include "util/logging.h"
#include "util/crypt.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
struct SignalMapping {
int signum;
const char* name;
};
static SignalMapping SIGNAL_MAPPINGS[] = {
{ SIGABRT, "SIGABRT" },
{ SIGFPE, "SIGFPE" },
{ SIGILL, "SIGILL" },
{ SIGINT, "SIGINT" },
{ SIGSEGV, "SIGSEGV" },
{ SIGTERM, "SIGTERM" },
};
static inline bool acquire_shutdown_privs() {
// check if already acquired
static bool acquired = false;
if (acquired)
return true;
// get process token
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return false;
// get the LUID for the shutdown privilege
TOKEN_PRIVILEGES tkp;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// get the shutdown privilege for this process
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
// check for error
bool success = GetLastError() == ERROR_SUCCESS;
if (success)
acquired = true;
return success;
}
Control::Control() : Module("control", true) {
functions["raise"] = std::bind(&Control::raise, this, _1, _2);
functions["exit"] = std::bind(&Control::exit, this, _1, _2);
functions["restart"] = std::bind(&Control::restart, this, _1, _2);
functions["session_refresh"] = std::bind(&Control::session_refresh, this, _1, _2);
functions["shutdown"] = std::bind(&Control::shutdown, this, _1, _2);
functions["reboot"] = std::bind(&Control::reboot, this, _1, _2);
}
/**
* raise(signal: str)
*/
void Control::raise(Request &req, Response &res) {
// check args
if (req.params.Size() < 1)
return error_params_insufficient(res);
if (!req.params[0].IsString())
return error_type(res, "signal", "string");
// get signal
auto signal_str = req.params[0].GetString();
int signal_val = -1;
for (auto mapping : SIGNAL_MAPPINGS) {
if (_stricmp(mapping.name, signal_str) == 0) {
signal_val = mapping.signum;
break;
}
}
// check if not found
if (signal_val < 0)
return error_unknown(res, "signal", signal_str);
// raise signal
if (::raise(signal_val))
return error(res, "Failed to raise signo " + to_string(signal_val));
}
/**
* exit()
* exit(code: int)
*/
void Control::exit(Request &req, Response &res) {
// exit()
if (req.params.Size() == 0) {
launcher::shutdown();
}
// check code
if (!req.params[0].IsInt())
return error_type(res, "code", "int");
// exit
launcher::shutdown(req.params[0].GetInt());
}
/**
* restart()
*/
void Control::restart(Request &req, Response &res) {
// restart launcher
launcher::restart();
}
/**
* session_refresh()
*/
void Control::session_refresh(Request &req, Response &res) {
// generate new password
uint8_t password_bin[128];
crypt::random_bytes(password_bin, std::size(password_bin));
std::string password = bin2hex(&password_bin[0], std::size(password_bin));
// add to response
Value password_val(password.c_str(), res.doc()->GetAllocator());
res.add_data(password_val);
// change password
res.password_change(password);
}
/**
* shutdown()
*/
void Control::shutdown(Request &req, Response &res) {
// acquire privileges
if (!acquire_shutdown_privs())
return error(res, "Unable to acquire shutdown privileges");
// exit windows
if (!ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,
SHTDN_REASON_MAJOR_APPLICATION |
SHTDN_REASON_MINOR_MAINTENANCE))
return error(res, "Unable to shutdown system");
// terminate this process
launcher::shutdown(0);
}
/**
* reboot()
*/
void Control::reboot(Request &req, Response &res) {
// acquire privileges
if (!acquire_shutdown_privs())
return error(res, "Unable to acquire shutdown privileges");
// exit windows
if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE,
SHTDN_REASON_MAJOR_APPLICATION |
SHTDN_REASON_MINOR_MAINTENANCE))
return error(res, "Unable to reboot system");
// terminate this process
launcher::shutdown(0);
}
}
#include "control.h"
#include <csignal>
#include <functional>
#include "external/rapidjson/document.h"
#include "launcher/shutdown.h"
#include "util/logging.h"
#include "util/crypt.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
struct SignalMapping {
int signum;
const char* name;
};
static SignalMapping SIGNAL_MAPPINGS[] = {
{ SIGABRT, "SIGABRT" },
{ SIGFPE, "SIGFPE" },
{ SIGILL, "SIGILL" },
{ SIGINT, "SIGINT" },
{ SIGSEGV, "SIGSEGV" },
{ SIGTERM, "SIGTERM" },
};
static inline bool acquire_shutdown_privs() {
// check if already acquired
static bool acquired = false;
if (acquired)
return true;
// get process token
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return false;
// get the LUID for the shutdown privilege
TOKEN_PRIVILEGES tkp;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// get the shutdown privilege for this process
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
// check for error
bool success = GetLastError() == ERROR_SUCCESS;
if (success)
acquired = true;
return success;
}
Control::Control() : Module("control", true) {
functions["raise"] = std::bind(&Control::raise, this, _1, _2);
functions["exit"] = std::bind(&Control::exit, this, _1, _2);
functions["restart"] = std::bind(&Control::restart, this, _1, _2);
functions["session_refresh"] = std::bind(&Control::session_refresh, this, _1, _2);
functions["shutdown"] = std::bind(&Control::shutdown, this, _1, _2);
functions["reboot"] = std::bind(&Control::reboot, this, _1, _2);
}
/**
* raise(signal: str)
*/
void Control::raise(Request &req, Response &res) {
// check args
if (req.params.Size() < 1)
return error_params_insufficient(res);
if (!req.params[0].IsString())
return error_type(res, "signal", "string");
// get signal
auto signal_str = req.params[0].GetString();
int signal_val = -1;
for (auto mapping : SIGNAL_MAPPINGS) {
if (_stricmp(mapping.name, signal_str) == 0) {
signal_val = mapping.signum;
break;
}
}
// check if not found
if (signal_val < 0)
return error_unknown(res, "signal", signal_str);
// raise signal
if (::raise(signal_val))
return error(res, "Failed to raise signo " + to_string(signal_val));
}
/**
* exit()
* exit(code: int)
*/
void Control::exit(Request &req, Response &res) {
// exit()
if (req.params.Size() == 0) {
launcher::shutdown();
}
// check code
if (!req.params[0].IsInt())
return error_type(res, "code", "int");
// exit
launcher::shutdown(req.params[0].GetInt());
}
/**
* restart()
*/
void Control::restart(Request &req, Response &res) {
// restart launcher
launcher::restart();
}
/**
* session_refresh()
*/
void Control::session_refresh(Request &req, Response &res) {
// generate new password
uint8_t password_bin[128];
crypt::random_bytes(password_bin, std::size(password_bin));
std::string password = bin2hex(&password_bin[0], std::size(password_bin));
// add to response
Value password_val(password.c_str(), res.doc()->GetAllocator());
res.add_data(password_val);
// change password
res.password_change(password);
}
/**
* shutdown()
*/
void Control::shutdown(Request &req, Response &res) {
// acquire privileges
if (!acquire_shutdown_privs())
return error(res, "Unable to acquire shutdown privileges");
// exit windows
if (!ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,
SHTDN_REASON_MAJOR_APPLICATION |
SHTDN_REASON_MINOR_MAINTENANCE))
return error(res, "Unable to shutdown system");
// terminate this process
launcher::shutdown(0);
}
/**
* reboot()
*/
void Control::reboot(Request &req, Response &res) {
// acquire privileges
if (!acquire_shutdown_privs())
return error(res, "Unable to acquire shutdown privileges");
// exit windows
if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE,
SHTDN_REASON_MAJOR_APPLICATION |
SHTDN_REASON_MINOR_MAINTENANCE))
return error(res, "Unable to reboot system");
// terminate this process
launcher::shutdown(0);
}
}
+22 -22
View File
@@ -1,22 +1,22 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Control : public Module {
public:
Control();
private:
// function definitions
void raise(Request &req, Response &res);
void exit(Request &req, Response &res);
void restart(Request &req, Response &res);
void session_refresh(Request &req, Response &res);
void shutdown(Request &req, Response &res);
void reboot(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Control : public Module {
public:
Control();
private:
// function definitions
void raise(Request &req, Response &res);
void exit(Request &req, Response &res);
void restart(Request &req, Response &res);
void session_refresh(Request &req, Response &res);
void shutdown(Request &req, Response &res);
void reboot(Request &req, Response &res);
};
}
+19 -19
View File
@@ -1,19 +1,19 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Info : public Module {
public:
Info();
private:
// function definitions
void avs(Request &req, Response &res);
void launcher(Request &req, Response &res);
void memory(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Info : public Module {
public:
Info();
private:
// function definitions
void avs(Request &req, Response &res);
void launcher(Request &req, Response &res);
void memory(Request &req, Response &res);
};
}
+176 -176
View File
@@ -1,176 +1,176 @@
#include "keypads.h"
#include <functional>
#include <windows.h>
#include "avs/game.h"
#include "external/rapidjson/document.h"
#include "misc/eamuse.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
struct KeypadMapping {
char character;
uint16_t state;
};
static KeypadMapping KEYPAD_MAPPINGS[] = {
{ '0', 1 << EAM_IO_KEYPAD_0 },
{ '1', 1 << EAM_IO_KEYPAD_1 },
{ '2', 1 << EAM_IO_KEYPAD_2 },
{ '3', 1 << EAM_IO_KEYPAD_3 },
{ '4', 1 << EAM_IO_KEYPAD_4 },
{ '5', 1 << EAM_IO_KEYPAD_5 },
{ '6', 1 << EAM_IO_KEYPAD_6 },
{ '7', 1 << EAM_IO_KEYPAD_7 },
{ '8', 1 << EAM_IO_KEYPAD_8 },
{ '9', 1 << EAM_IO_KEYPAD_9 },
{ 'A', 1 << EAM_IO_KEYPAD_00 },
{ 'D', 1 << EAM_IO_KEYPAD_DECIMAL },
};
Keypads::Keypads() : Module("keypads") {
functions["write"] = std::bind(&Keypads::write, this, _1, _2);
functions["set"] = std::bind(&Keypads::set, this, _1, _2);
functions["get"] = std::bind(&Keypads::get, this, _1, _2);
}
/**
* write(keypad: uint, input: str)
*/
void Keypads::write(Request &req, Response &res) {
// check params
if (req.params.Size() < 2) {
return error_params_insufficient(res);
}
if (!req.params[0].IsUint()) {
return error_type(res, "keypad", "uint");
}
if (!req.params[1].IsString()) {
return error_type(res, "input", "string");
}
// get params
auto keypad = req.params[0].GetUint();
auto input = std::string(req.params[1].GetString());
// process all chars
for (auto c : input) {
uint16_t state = 0;
// find mapping
bool mapping_found = false;
for (auto &mapping : KEYPAD_MAPPINGS) {
if (_strnicmp(&mapping.character, &c, 1) == 0) {
state |= mapping.state;
mapping_found = true;
break;
}
}
// check for error
if (!mapping_found) {
return error_unknown(res, "char", std::string("") + c);
}
/*
* Write input to keypad.
* We try to make sure it was accepted by waiting a bit more than two frames.
*/
DWORD sleep_time = 70;
if (avs::game::is_model("MDX")) {
// cuz fuck DDR
sleep_time = 150;
}
// set
eamuse_set_keypad_overrides(keypad, state);
Sleep(sleep_time);
// unset
eamuse_set_keypad_overrides(keypad, 0);
Sleep(sleep_time);
}
}
/**
* set(keypad: uint, key: char, ...)
*/
void Keypads::set(Request &req, Response &res) {
// check keypad
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsUint()) {
return error_type(res, "keypad", "uint");
}
auto keypad = req.params[0].GetUint();
// iterate params
uint16_t state = 0;
auto params = req.params.GetArray();
for (size_t i = 1; i < params.Size(); i++) {
auto &param = params[i];
// check key
if (!param.IsString()) {
error_type(res, "key", "char");
}
if (param.GetStringLength() < 1) {
error_size(res, "key", 1);
}
// find mapping
auto key = param.GetString();
bool mapping_found = false;
for (auto &mapping : KEYPAD_MAPPINGS) {
if (_strnicmp(&mapping.character, key, 1) == 0) {
state |= mapping.state;
mapping_found = true;
break;
}
}
// check for error
if (!mapping_found) {
return error_unknown(res, "key", key);
}
}
// set keypad state
eamuse_set_keypad_overrides(keypad, state);
}
/**
* get(keypad: uint)
*/
void Keypads::get(Request &req, Response &res) {
// check keypad
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsUint()) {
return error_type(res, "keypad", "uint");
}
auto keypad = req.params[0].GetUint();
// get keypad state
auto state = eamuse_get_keypad_state(keypad);
// add keys to response
for (auto &mapping : KEYPAD_MAPPINGS) {
if (state & mapping.state) {
Value val(&mapping.character, 1);
res.add_data(val);
}
}
}
}
#include "keypads.h"
#include <functional>
#include <windows.h>
#include "avs/game.h"
#include "external/rapidjson/document.h"
#include "misc/eamuse.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
struct KeypadMapping {
char character;
uint16_t state;
};
static KeypadMapping KEYPAD_MAPPINGS[] = {
{ '0', 1 << EAM_IO_KEYPAD_0 },
{ '1', 1 << EAM_IO_KEYPAD_1 },
{ '2', 1 << EAM_IO_KEYPAD_2 },
{ '3', 1 << EAM_IO_KEYPAD_3 },
{ '4', 1 << EAM_IO_KEYPAD_4 },
{ '5', 1 << EAM_IO_KEYPAD_5 },
{ '6', 1 << EAM_IO_KEYPAD_6 },
{ '7', 1 << EAM_IO_KEYPAD_7 },
{ '8', 1 << EAM_IO_KEYPAD_8 },
{ '9', 1 << EAM_IO_KEYPAD_9 },
{ 'A', 1 << EAM_IO_KEYPAD_00 },
{ 'D', 1 << EAM_IO_KEYPAD_DECIMAL },
};
Keypads::Keypads() : Module("keypads") {
functions["write"] = std::bind(&Keypads::write, this, _1, _2);
functions["set"] = std::bind(&Keypads::set, this, _1, _2);
functions["get"] = std::bind(&Keypads::get, this, _1, _2);
}
/**
* write(keypad: uint, input: str)
*/
void Keypads::write(Request &req, Response &res) {
// check params
if (req.params.Size() < 2) {
return error_params_insufficient(res);
}
if (!req.params[0].IsUint()) {
return error_type(res, "keypad", "uint");
}
if (!req.params[1].IsString()) {
return error_type(res, "input", "string");
}
// get params
auto keypad = req.params[0].GetUint();
auto input = std::string(req.params[1].GetString());
// process all chars
for (auto c : input) {
uint16_t state = 0;
// find mapping
bool mapping_found = false;
for (auto &mapping : KEYPAD_MAPPINGS) {
if (_strnicmp(&mapping.character, &c, 1) == 0) {
state |= mapping.state;
mapping_found = true;
break;
}
}
// check for error
if (!mapping_found) {
return error_unknown(res, "char", std::string("") + c);
}
/*
* Write input to keypad.
* We try to make sure it was accepted by waiting a bit more than two frames.
*/
DWORD sleep_time = 70;
if (avs::game::is_model("MDX")) {
// cuz fuck DDR
sleep_time = 150;
}
// set
eamuse_set_keypad_overrides(keypad, state);
Sleep(sleep_time);
// unset
eamuse_set_keypad_overrides(keypad, 0);
Sleep(sleep_time);
}
}
/**
* set(keypad: uint, key: char, ...)
*/
void Keypads::set(Request &req, Response &res) {
// check keypad
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsUint()) {
return error_type(res, "keypad", "uint");
}
auto keypad = req.params[0].GetUint();
// iterate params
uint16_t state = 0;
auto params = req.params.GetArray();
for (size_t i = 1; i < params.Size(); i++) {
auto &param = params[i];
// check key
if (!param.IsString()) {
error_type(res, "key", "char");
}
if (param.GetStringLength() < 1) {
error_size(res, "key", 1);
}
// find mapping
auto key = param.GetString();
bool mapping_found = false;
for (auto &mapping : KEYPAD_MAPPINGS) {
if (_strnicmp(&mapping.character, key, 1) == 0) {
state |= mapping.state;
mapping_found = true;
break;
}
}
// check for error
if (!mapping_found) {
return error_unknown(res, "key", key);
}
}
// set keypad state
eamuse_set_keypad_overrides(keypad, state);
}
/**
* get(keypad: uint)
*/
void Keypads::get(Request &req, Response &res) {
// check keypad
if (req.params.Size() < 1) {
return error_params_insufficient(res);
}
if (!req.params[0].IsUint()) {
return error_type(res, "keypad", "uint");
}
auto keypad = req.params[0].GetUint();
// get keypad state
auto state = eamuse_get_keypad_state(keypad);
// add keys to response
for (auto &mapping : KEYPAD_MAPPINGS) {
if (state & mapping.state) {
Value val(&mapping.character, 1);
res.add_data(val);
}
}
}
}
+19 -19
View File
@@ -1,19 +1,19 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Keypads : public Module {
public:
Keypads();
private:
// function definitions
void write(Request &req, Response &res);
void set(Request &req, Response &res);
void get(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Keypads : public Module {
public:
Keypads();
private:
// function definitions
void write(Request &req, Response &res);
void set(Request &req, Response &res);
void get(Request &req, Response &res);
};
}
+36 -36
View File
@@ -1,36 +1,36 @@
#include "lcd.h"
#include "external/rapidjson/document.h"
#include "games/shared/lcdhandle.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
LCD::LCD() : Module("lcd") {
functions["info"] = std::bind(&LCD::info, this, _1, _2);
}
/*
* info()
*/
void LCD::info(Request &req, Response &res) {
// get allocator
auto &alloc = res.doc()->GetAllocator();
// build info object
Value info(kObjectType);
info.AddMember("enabled", games::shared::LCD_ENABLED, alloc);
info.AddMember("csm", StringRef(games::shared::LCD_CSM.c_str()), alloc);
info.AddMember("bri", games::shared::LCD_BRI, alloc);
info.AddMember("con", games::shared::LCD_CON, alloc);
info.AddMember("bl", games::shared::LCD_BL, alloc);
info.AddMember("red", games::shared::LCD_RED, alloc);
info.AddMember("green", games::shared::LCD_GREEN, alloc);
info.AddMember("blue", games::shared::LCD_BLUE, alloc);
// add info object
res.add_data(info);
}
}
#include "lcd.h"
#include "external/rapidjson/document.h"
#include "games/shared/lcdhandle.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
LCD::LCD() : Module("lcd") {
functions["info"] = std::bind(&LCD::info, this, _1, _2);
}
/*
* info()
*/
void LCD::info(Request &req, Response &res) {
// get allocator
auto &alloc = res.doc()->GetAllocator();
// build info object
Value info(kObjectType);
info.AddMember("enabled", games::shared::LCD_ENABLED, alloc);
info.AddMember("csm", StringRef(games::shared::LCD_CSM.c_str()), alloc);
info.AddMember("bri", games::shared::LCD_BRI, alloc);
info.AddMember("con", games::shared::LCD_CON, alloc);
info.AddMember("bl", games::shared::LCD_BL, alloc);
info.AddMember("red", games::shared::LCD_RED, alloc);
info.AddMember("green", games::shared::LCD_GREEN, alloc);
info.AddMember("blue", games::shared::LCD_BLUE, alloc);
// add info object
res.add_data(info);
}
}
+17 -17
View File
@@ -1,17 +1,17 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class LCD : public Module {
public:
LCD();
private:
// function definitions
void info(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class LCD : public Module {
public:
LCD();
private:
// function definitions
void info(Request &req, Response &res);
};
}
+179 -179
View File
@@ -1,179 +1,179 @@
#include "lights.h"
#include <functional>
#include "external/rapidjson/document.h"
#include "misc/eamuse.h"
#include "cfg/light.h"
#include "launcher/launcher.h"
#include "games/io.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
Lights::Lights() : Module("lights") {
functions["read"] = std::bind(&Lights::read, this, _1, _2);
functions["write"] = std::bind(&Lights::write, this, _1, _2);
functions["write_reset"] = std::bind(&Lights::write_reset, this, _1, _2);
lights = games::get_lights(eamuse_get_game());
}
/**
* read()
*/
void Lights::read(api::Request &req, Response &res) {
// check light cache
if (!this->lights) {
return;
}
// add state for each light
for (auto &light : *this->lights) {
Value state(kArrayType);
Value light_name(light.getName().c_str(), res.doc()->GetAllocator());
Value light_state(GameAPI::Lights::readLight(RI_MGR, light));
Value light_enabled(light.override_enabled);
state.PushBack(light_name, res.doc()->GetAllocator());
state.PushBack(light_state, res.doc()->GetAllocator());
state.PushBack(light_enabled, res.doc()->GetAllocator());
res.add_data(state);
}
}
/**
* write([name: str, state: float], ...)
*/
void Lights::write(Request &req, Response &res) {
// check light cache
if (!this->lights) {
return;
}
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 2) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
if (!param[1].IsFloat() && !param[1].IsInt()) {
error_type(res, "state", "float");
continue;
}
// get params
auto light_name = param[0].GetString();
auto light_state = param[1].GetFloat();
// write light state
if (!this->write_light(light_name, light_state)) {
error_unknown(res, "light", light_name);
continue;
}
}
}
/**
* write_reset()
* write_reset([name: str], ...)
*/
void Lights::write_reset(Request &req, Response &res) {
// check light cache
if (!this->lights) {
return;
}
// get params
auto params = req.params.GetArray();
// write_reset()
if (params.Size() == 0) {
if (lights != nullptr) {
for (auto &light : *this->lights) {
light.override_enabled = false;
}
}
return;
}
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 1) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
// get params
auto light_name = param[0].GetString();
// write analog state
if (!this->write_light_reset(light_name)) {
error_unknown(res, "analog", light_name);
continue;
}
}
}
bool Lights::write_light(std::string name, float state) {
// check light cache
if (!this->lights) {
return false;
}
// find light
for (auto &light : *this->lights) {
if (light.getName() == name) {
light.override_state = CLAMP(state, 0.f, 1.f);
light.override_enabled = true;
return true;
}
}
// unknown light
return false;
}
bool Lights::write_light_reset(std::string name) {
// check light cache
if (!this->lights) {
return false;
}
// find light
for (auto &light : *this->lights) {
if (light.getName() == name) {
light.override_enabled = false;
return true;
}
}
// unknown light
return false;
}
}
#include "lights.h"
#include <functional>
#include "external/rapidjson/document.h"
#include "misc/eamuse.h"
#include "cfg/light.h"
#include "launcher/launcher.h"
#include "games/io.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
Lights::Lights() : Module("lights") {
functions["read"] = std::bind(&Lights::read, this, _1, _2);
functions["write"] = std::bind(&Lights::write, this, _1, _2);
functions["write_reset"] = std::bind(&Lights::write_reset, this, _1, _2);
lights = games::get_lights(eamuse_get_game());
}
/**
* read()
*/
void Lights::read(api::Request &req, Response &res) {
// check light cache
if (!this->lights) {
return;
}
// add state for each light
for (auto &light : *this->lights) {
Value state(kArrayType);
Value light_name(light.getName().c_str(), res.doc()->GetAllocator());
Value light_state(GameAPI::Lights::readLight(RI_MGR, light));
Value light_enabled(light.override_enabled);
state.PushBack(light_name, res.doc()->GetAllocator());
state.PushBack(light_state, res.doc()->GetAllocator());
state.PushBack(light_enabled, res.doc()->GetAllocator());
res.add_data(state);
}
}
/**
* write([name: str, state: float], ...)
*/
void Lights::write(Request &req, Response &res) {
// check light cache
if (!this->lights) {
return;
}
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 2) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
if (!param[1].IsFloat() && !param[1].IsInt()) {
error_type(res, "state", "float");
continue;
}
// get params
auto light_name = param[0].GetString();
auto light_state = param[1].GetFloat();
// write light state
if (!this->write_light(light_name, light_state)) {
error_unknown(res, "light", light_name);
continue;
}
}
}
/**
* write_reset()
* write_reset([name: str], ...)
*/
void Lights::write_reset(Request &req, Response &res) {
// check light cache
if (!this->lights) {
return;
}
// get params
auto params = req.params.GetArray();
// write_reset()
if (params.Size() == 0) {
if (lights != nullptr) {
for (auto &light : *this->lights) {
light.override_enabled = false;
}
}
return;
}
// loop parameters
for (Value &param : req.params.GetArray()) {
// check params
if (!param.IsArray()) {
error(res, "parameters must be arrays");
return;
}
if (param.Size() < 1) {
error_params_insufficient(res);
continue;
}
if (!param[0].IsString()) {
error_type(res, "name", "string");
continue;
}
// get params
auto light_name = param[0].GetString();
// write analog state
if (!this->write_light_reset(light_name)) {
error_unknown(res, "analog", light_name);
continue;
}
}
}
bool Lights::write_light(std::string name, float state) {
// check light cache
if (!this->lights) {
return false;
}
// find light
for (auto &light : *this->lights) {
if (light.getName() == name) {
light.override_state = CLAMP(state, 0.f, 1.f);
light.override_enabled = true;
return true;
}
}
// unknown light
return false;
}
bool Lights::write_light_reset(std::string name) {
// check light cache
if (!this->lights) {
return false;
}
// find light
for (auto &light : *this->lights) {
if (light.getName() == name) {
light.override_enabled = false;
return true;
}
}
// unknown light
return false;
}
}
+28 -28
View File
@@ -1,28 +1,28 @@
#pragma once
#include <vector>
#include "api/module.h"
#include "api/request.h"
#include "cfg/api.h"
namespace api::modules {
class Lights : public Module {
public:
Lights();
private:
// state
std::vector<Light> *lights;
// function definitions
void read(Request &req, Response &res);
void write(Request &req, Response &res);
void write_reset(Request &req, Response &res);
// helper
bool write_light(std::string name, float state);
bool write_light_reset(std::string name);
};
}
#pragma once
#include <vector>
#include "api/module.h"
#include "api/request.h"
#include "cfg/api.h"
namespace api::modules {
class Lights : public Module {
public:
Lights();
private:
// state
std::vector<Light> *lights;
// function definitions
void read(Request &req, Response &res);
void write(Request &req, Response &res);
void write_reset(Request &req, Response &res);
// helper
bool write_light(std::string name, float state);
bool write_light_reset(std::string name);
};
}
+233 -233
View File
@@ -1,233 +1,233 @@
#include "memory.h"
#include <functional>
#include <mutex>
#include "external/rapidjson/document.h"
#include "util/fileutils.h"
#include "util/libutils.h"
#include "util/memutils.h"
#include "util/sigscan.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
// global lock to prevent simultaneous access to memory
static std::mutex MEMORY_LOCK;
Memory::Memory() : Module("memory", true) {
functions["write"] = std::bind(&Memory::write, this, _1, _2);
functions["read"] = std::bind(&Memory::read, this, _1, _2);
functions["signature"] = std::bind(&Memory::signature, this, _1, _2);
}
/**
* write(dll_name: str, data: hex, offset: uint)
*/
void Memory::write(Request &req, Response &res) {
std::lock_guard<std::mutex> lock(MEMORY_LOCK);
// check params
if (req.params.Size() < 3) {
return error_params_insufficient(res);
}
if (!req.params[0].IsString()) {
return error_type(res, "dll_name", "str");
}
if (!req.params[1].IsString() || (req.params[1].GetStringLength() & 1)) {
return error_type(res, "data", "hex string");
}
if (!req.params[2].IsUint()) {
return error_type(res, "offset", "uint");
}
// get params
auto dll_name = req.params[0].GetString();
auto dll_path = MODULE_PATH / dll_name;
auto data = req.params[1].GetString();
intptr_t offset = req.params[2].GetUint();
// convert data to bin
size_t data_bin_size = strlen(data) / 2;
auto data_bin = std::make_unique<uint8_t[]>(data_bin_size);
hex2bin(data, data_bin.get());
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return error(res, "Couldn't find " + dll_path.string());
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return error(res, "Couldn't find module.");
}
// convert offset to RVA
offset = libutils::offset2rva(dll_path, offset);
if (offset == ~0) {
return error(res, "Couldn't convert offset to RVA.");
}
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(MODULEINFO))) {
return error(res, "Couldn't get module information.");
}
// check bounds
if (offset + data_bin_size >= (size_t) module_info.lpBaseOfDll + module_info.SizeOfImage) {
return error(res, "Data out of bounds.");
}
auto data_pos = reinterpret_cast<uint8_t *>(module_info.lpBaseOfDll) + offset;
// replace data
memutils::VProtectGuard guard(data_pos, data_bin_size);
memcpy(data_pos, data_bin.get(), data_bin_size);
}
/**
* read(dll_name: str, offset: uint, size: uint)
*/
void Memory::read(Request &req, Response &res) {
std::lock_guard<std::mutex> lock(MEMORY_LOCK);
// check params
if (req.params.Size() < 3) {
return error_params_insufficient(res);
}
if (!req.params[0].IsString()) {
return error_type(res, "dll_name", "str");
}
if (!req.params[1].IsUint()) {
return error_type(res, "offset", "uint");
}
if (!req.params[2].IsUint()) {
return error_type(res, "size", "uint");
}
// get params
auto dll_name = req.params[0].GetString();
auto dll_path = MODULE_PATH / dll_name;
intptr_t offset = req.params[1].GetUint();
auto size = req.params[2].GetUint();
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return error(res, "Couldn't find " + dll_path.string());
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return error(res, "Couldn't find module.");
}
// convert offset to RVA
offset = libutils::offset2rva(dll_path, offset);
if (offset == ~0) {
return error(res, "Couldn't convert offset to RVA.");
}
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(MODULEINFO))) {
return error(res, "Couldn't get module information.");
}
// check bounds
auto max = offset + size;
if ((size_t) max >= (size_t) module_info.lpBaseOfDll + module_info.SizeOfImage) {
return error(res, "Data out of bounds.");
}
// read memory to hex (without virtual protect)
std::string hex = bin2hex((uint8_t*) module_info.lpBaseOfDll + offset, size);
Value hex_val(hex.c_str(), res.doc()->GetAllocator());
res.add_data(hex_val);
}
/**
* signature(
* dll_name: str,
* signature: hex,
* replacement: hex,
* offset: uint,
* usage: uint)
*
* Both signature and replacement will ignore bytes specified as "??" in the hex string.
* The offset specifies the offset between the found signature and the position to write the replacement to.
* The resulting integer is the file offset where the replacement was written to.
*/
void Memory::signature(Request &req, Response &res) {
std::lock_guard<std::mutex> lock(MEMORY_LOCK);
// check params
if (req.params.Size() < 5) {
return error_params_insufficient(res);
}
if (!req.params[0].IsString()) {
return error_type(res, "dll_name", "string");
}
if (!req.params[1].IsString() || (req.params[1].GetStringLength() & 1)) {
return error_type(res, "signature", "hex string");
}
if (!req.params[2].IsString() || (req.params[2].GetStringLength() & 1)) {
return error_type(res, "replacement", "hex string");
}
if (!req.params[3].IsUint()) {
return error_type(res, "offset", "uint");
}
if (!req.params[4].IsUint()) {
return error_type(res, "usage", "uint");
}
// get params
auto dll_name = req.params[0].GetString();
auto dll_path = MODULE_PATH / dll_name;
auto signature = req.params[1].GetString();
auto replacement = req.params[2].GetString();
auto offset = req.params[3].GetUint();
auto usage = req.params[4].GetUint();
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return error(res, "Couldn't find " + dll_path.string());
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return error(res, "Couldn't find module.");
}
// execute
auto result = replace_pattern(
module,
signature,
replacement,
offset,
usage
);
// check result
if (!result) {
return error(res, std::string("Pattern not found in memory of ") + dll_name);
}
// convert to offset
auto rva = result - reinterpret_cast<intptr_t>(module);
result = libutils::rva2offset(dll_path, rva);
if (result == -1) {
return error(res, "Couldn't convert RVA to file offset.");
}
// add result
Value result_val(result);
res.add_data(result_val);
}
}
#include "memory.h"
#include <functional>
#include <mutex>
#include "external/rapidjson/document.h"
#include "util/fileutils.h"
#include "util/libutils.h"
#include "util/memutils.h"
#include "util/sigscan.h"
#include "util/utils.h"
using namespace std::placeholders;
using namespace rapidjson;
namespace api::modules {
// global lock to prevent simultaneous access to memory
static std::mutex MEMORY_LOCK;
Memory::Memory() : Module("memory", true) {
functions["write"] = std::bind(&Memory::write, this, _1, _2);
functions["read"] = std::bind(&Memory::read, this, _1, _2);
functions["signature"] = std::bind(&Memory::signature, this, _1, _2);
}
/**
* write(dll_name: str, data: hex, offset: uint)
*/
void Memory::write(Request &req, Response &res) {
std::lock_guard<std::mutex> lock(MEMORY_LOCK);
// check params
if (req.params.Size() < 3) {
return error_params_insufficient(res);
}
if (!req.params[0].IsString()) {
return error_type(res, "dll_name", "str");
}
if (!req.params[1].IsString() || (req.params[1].GetStringLength() & 1)) {
return error_type(res, "data", "hex string");
}
if (!req.params[2].IsUint()) {
return error_type(res, "offset", "uint");
}
// get params
auto dll_name = req.params[0].GetString();
auto dll_path = MODULE_PATH / dll_name;
auto data = req.params[1].GetString();
intptr_t offset = req.params[2].GetUint();
// convert data to bin
size_t data_bin_size = strlen(data) / 2;
auto data_bin = std::make_unique<uint8_t[]>(data_bin_size);
hex2bin(data, data_bin.get());
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return error(res, "Couldn't find " + dll_path.string());
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return error(res, "Couldn't find module.");
}
// convert offset to RVA
offset = libutils::offset2rva(dll_path, offset);
if (offset == ~0) {
return error(res, "Couldn't convert offset to RVA.");
}
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(MODULEINFO))) {
return error(res, "Couldn't get module information.");
}
// check bounds
if (offset + data_bin_size >= (size_t) module_info.lpBaseOfDll + module_info.SizeOfImage) {
return error(res, "Data out of bounds.");
}
auto data_pos = reinterpret_cast<uint8_t *>(module_info.lpBaseOfDll) + offset;
// replace data
memutils::VProtectGuard guard(data_pos, data_bin_size);
memcpy(data_pos, data_bin.get(), data_bin_size);
}
/**
* read(dll_name: str, offset: uint, size: uint)
*/
void Memory::read(Request &req, Response &res) {
std::lock_guard<std::mutex> lock(MEMORY_LOCK);
// check params
if (req.params.Size() < 3) {
return error_params_insufficient(res);
}
if (!req.params[0].IsString()) {
return error_type(res, "dll_name", "str");
}
if (!req.params[1].IsUint()) {
return error_type(res, "offset", "uint");
}
if (!req.params[2].IsUint()) {
return error_type(res, "size", "uint");
}
// get params
auto dll_name = req.params[0].GetString();
auto dll_path = MODULE_PATH / dll_name;
intptr_t offset = req.params[1].GetUint();
auto size = req.params[2].GetUint();
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return error(res, "Couldn't find " + dll_path.string());
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return error(res, "Couldn't find module.");
}
// convert offset to RVA
offset = libutils::offset2rva(dll_path, offset);
if (offset == ~0) {
return error(res, "Couldn't convert offset to RVA.");
}
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(MODULEINFO))) {
return error(res, "Couldn't get module information.");
}
// check bounds
auto max = offset + size;
if ((size_t) max >= (size_t) module_info.lpBaseOfDll + module_info.SizeOfImage) {
return error(res, "Data out of bounds.");
}
// read memory to hex (without virtual protect)
std::string hex = bin2hex((uint8_t*) module_info.lpBaseOfDll + offset, size);
Value hex_val(hex.c_str(), res.doc()->GetAllocator());
res.add_data(hex_val);
}
/**
* signature(
* dll_name: str,
* signature: hex,
* replacement: hex,
* offset: uint,
* usage: uint)
*
* Both signature and replacement will ignore bytes specified as "??" in the hex string.
* The offset specifies the offset between the found signature and the position to write the replacement to.
* The resulting integer is the file offset where the replacement was written to.
*/
void Memory::signature(Request &req, Response &res) {
std::lock_guard<std::mutex> lock(MEMORY_LOCK);
// check params
if (req.params.Size() < 5) {
return error_params_insufficient(res);
}
if (!req.params[0].IsString()) {
return error_type(res, "dll_name", "string");
}
if (!req.params[1].IsString() || (req.params[1].GetStringLength() & 1)) {
return error_type(res, "signature", "hex string");
}
if (!req.params[2].IsString() || (req.params[2].GetStringLength() & 1)) {
return error_type(res, "replacement", "hex string");
}
if (!req.params[3].IsUint()) {
return error_type(res, "offset", "uint");
}
if (!req.params[4].IsUint()) {
return error_type(res, "usage", "uint");
}
// get params
auto dll_name = req.params[0].GetString();
auto dll_path = MODULE_PATH / dll_name;
auto signature = req.params[1].GetString();
auto replacement = req.params[2].GetString();
auto offset = req.params[3].GetUint();
auto usage = req.params[4].GetUint();
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return error(res, "Couldn't find " + dll_path.string());
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return error(res, "Couldn't find module.");
}
// execute
auto result = replace_pattern(
module,
signature,
replacement,
offset,
usage
);
// check result
if (!result) {
return error(res, std::string("Pattern not found in memory of ") + dll_name);
}
// convert to offset
auto rva = result - reinterpret_cast<intptr_t>(module);
result = libutils::rva2offset(dll_path, rva);
if (result == -1) {
return error(res, "Couldn't convert RVA to file offset.");
}
// add result
Value result_val(result);
res.add_data(result_val);
}
}
+19 -19
View File
@@ -1,19 +1,19 @@
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Memory : public Module {
public:
Memory();
private:
// function definitions
void write(Request &req, Response &res);
void read(Request &req, Response &res);
void signature(Request &req, Response &res);
};
}
#pragma once
#include "api/module.h"
#include "api/request.h"
namespace api::modules {
class Memory : public Module {
public:
Memory();
private:
// function definitions
void write(Request &req, Response &res);
void read(Request &req, Response &res);
void signature(Request &req, Response &res);
};
}