some improvements
+ Improved blackbox's backtracer + Improved json config read/writer
This commit is contained in:
parent
866527b7e8
commit
55553a4099
@ -153,12 +153,12 @@ namespace blackbox
|
|||||||
#undef EXCEPTION_CASE
|
#undef EXCEPTION_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_memory_registers(const LPEXCEPTION_POINTERS exceptioninfo)
|
std::string get_memory_registers(const LPEXCEPTION_POINTERS exception_info)
|
||||||
{
|
{
|
||||||
if (IsBadReadPtr(exceptioninfo, sizeof(EXCEPTION_POINTERS)))
|
if (IsBadReadPtr(exception_info, sizeof(EXCEPTION_POINTERS)))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
const auto* ctx = exceptioninfo->ContextRecord;
|
const auto* ctx = exception_info->ContextRecord;
|
||||||
|
|
||||||
std::string registers_scroll{};
|
std::string registers_scroll{};
|
||||||
registers_scroll.append("registers:\r\n{\r\n");
|
registers_scroll.append("registers:\r\n{\r\n");
|
||||||
@ -191,29 +191,36 @@ namespace blackbox
|
|||||||
return registers_scroll;
|
return registers_scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_callstack_summary(int trace_max_depth = 18)
|
std::string get_callstack_summary(void* exception_addr, int trace_depth = 32)
|
||||||
{
|
{
|
||||||
std::string callstack_scroll("callstack:\r\n{\r\n");
|
std::string callstack_scroll("callstack:\r\n{\r\n");
|
||||||
void* stack[32]; if (trace_max_depth > 32) trace_max_depth = 32;
|
|
||||||
uint16_t count = RtlCaptureStackBackTrace(1, trace_max_depth, stack, NULL);
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < count; i++)
|
void* backtrace_stack[32]; int backtrace_stack_size = ARRAYSIZE(backtrace_stack);
|
||||||
|
if (trace_depth > backtrace_stack_size) trace_depth = backtrace_stack_size;
|
||||||
|
|
||||||
|
size_t count = RtlCaptureStackBackTrace(0, trace_depth, backtrace_stack, NULL);
|
||||||
|
|
||||||
|
auto itr = std::find(backtrace_stack, backtrace_stack + backtrace_stack_size, exception_addr);
|
||||||
|
auto exception_start_index = std::distance(backtrace_stack, itr);
|
||||||
|
|
||||||
|
for (size_t i = exception_start_index; i < count; i++)
|
||||||
{
|
{
|
||||||
const auto prnt = utils::nt::library::get_by_address(stack[i]);
|
const auto from = utils::nt::library::get_by_address(backtrace_stack[i]);
|
||||||
size_t rva = reinterpret_cast<uint64_t>(stack[i]) - reinterpret_cast<uint64_t>(prnt.get_ptr());
|
size_t rva = reinterpret_cast<uint64_t>(backtrace_stack[i]) - reinterpret_cast<uint64_t>(from.get_ptr());
|
||||||
|
|
||||||
callstack_scroll.append(std::format("\t{}: {:012X}\r\n", prnt.get_name(), rva));
|
if (from.get_name() == "BlackOps4.exe"s) rva += 0x140000000;
|
||||||
|
|
||||||
|
callstack_scroll.append(std::format("\t{}: {:012X}\r\n", from.get_name(), rva));
|
||||||
}
|
}
|
||||||
callstack_scroll.append("}");
|
|
||||||
|
|
||||||
return callstack_scroll;
|
return callstack_scroll.append("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo)
|
std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo)
|
||||||
{
|
{
|
||||||
const auto main_module = utils::nt::library{};
|
|
||||||
const auto& build_info = game::version_string;
|
const auto& build_info = game::version_string;
|
||||||
const auto thread_id = ::GetCurrentThreadId(); // TODO: Find Thread's Name
|
const auto main_module = utils::nt::library{};
|
||||||
|
const auto rip_address = exceptioninfo->ExceptionRecord->ExceptionAddress;
|
||||||
|
|
||||||
std::string info{};
|
std::string info{};
|
||||||
const auto line = [&info](const std::string& text)
|
const auto line = [&info](const std::string& text)
|
||||||
@ -239,7 +246,7 @@ namespace blackbox
|
|||||||
}
|
}
|
||||||
|
|
||||||
line("\r\n");
|
line("\r\n");
|
||||||
line(get_callstack_summary(18));
|
line(get_callstack_summary(rip_address));
|
||||||
line(get_memory_registers(exceptioninfo));
|
line(get_memory_registers(exceptioninfo));
|
||||||
|
|
||||||
line("\r\nTimestamp: "s + get_timestamp());
|
line("\r\nTimestamp: "s + get_timestamp());
|
||||||
|
@ -18,7 +18,7 @@ namespace platform
|
|||||||
if (!userid)
|
if (!userid)
|
||||||
{
|
{
|
||||||
uint32_t default_xuid = utils::cryptography::xxh32::compute(utils::identity::get_sys_username());
|
uint32_t default_xuid = utils::cryptography::xxh32::compute(utils::identity::get_sys_username());
|
||||||
userid = utils::json_config::ReadUnsignedInteger("identity", "xuid", default_xuid);
|
userid = utils::json_config::ReadUnsignedInteger64("identity", "xuid", default_xuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return userid;
|
return userid;
|
||||||
|
@ -70,6 +70,41 @@ namespace utils::json_config
|
|||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue)
|
||||||
|
{
|
||||||
|
rapidjson::Document& doc = get_json_document();
|
||||||
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
|
if (!section.HasMember(szKey)) {
|
||||||
|
section.AddMember(rapidjson::StringRef(szKey), bolDefaultValue, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
else if (!section[szKey].IsBool()) {
|
||||||
|
section[szKey].SetBool(bolDefaultValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return section[szKey].GetBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
write_json_config();
|
||||||
|
return section[szKey].GetBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteBoolean(const char* szSection, const char* szKey, bool bolValue)
|
||||||
|
{
|
||||||
|
rapidjson::Document& doc = get_json_document();
|
||||||
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
|
if (!section.HasMember(szKey)) {
|
||||||
|
section.AddMember(rapidjson::StringRef(szKey), bolValue, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
section[szKey].SetBool(bolValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_json_config();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string ReadString(const char* szSection, const char* szKey, const std::string& strDefaultValue)
|
std::string ReadString(const char* szSection, const char* szKey, const std::string& strDefaultValue)
|
||||||
{
|
{
|
||||||
rapidjson::Document& doc = get_json_document();
|
rapidjson::Document& doc = get_json_document();
|
||||||
@ -104,7 +139,42 @@ namespace utils::json_config
|
|||||||
write_json_config();
|
write_json_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ReadUnsignedInteger(const char* szSection, const char* szKey, unsigned int iDefaultValue)
|
|
||||||
|
int32_t ReadInteger(const char* szSection, const char* szKey, int32_t iDefaultValue)
|
||||||
|
{
|
||||||
|
rapidjson::Document& doc = get_json_document();
|
||||||
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
|
if (!section.HasMember(szKey)) {
|
||||||
|
section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
else if (!section[szKey].IsInt()) {
|
||||||
|
section[szKey].SetInt(iDefaultValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return section[szKey].GetInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
write_json_config();
|
||||||
|
return section[szKey].GetInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteInteger(const char* szSection, const char* szKey, int32_t iValue)
|
||||||
|
{
|
||||||
|
rapidjson::Document& doc = get_json_document();
|
||||||
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
|
if (!section.HasMember(szKey)) {
|
||||||
|
section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
section[szKey].SetInt(iValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_json_config();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ReadUnsignedInteger(const char* szSection, const char* szKey, uint32_t iDefaultValue)
|
||||||
{
|
{
|
||||||
rapidjson::Document& doc = get_json_document();
|
rapidjson::Document& doc = get_json_document();
|
||||||
rapidjson::Value& section = get_json_section(szSection);
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
@ -123,12 +193,7 @@ namespace utils::json_config
|
|||||||
return section[szKey].GetUint();
|
return section[szKey].GetUint();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadInteger(const char* szSection, const char* szKey, int iDefaultValue)
|
void WriteUnsignedInteger(const char* szSection, const char* szKey, uint32_t iValue)
|
||||||
{
|
|
||||||
return static_cast<int>(ReadUnsignedInteger(szSection, szKey, static_cast<unsigned int>(iDefaultValue)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteUnsignedInteger(const char* szSection, const char* szKey, unsigned int iValue)
|
|
||||||
{
|
{
|
||||||
rapidjson::Document& doc = get_json_document();
|
rapidjson::Document& doc = get_json_document();
|
||||||
rapidjson::Value& section = get_json_section(szSection);
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
@ -143,40 +208,69 @@ namespace utils::json_config
|
|||||||
write_json_config();
|
write_json_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteInteger(const char* szSection, const char* szKey, int iValue)
|
int64_t ReadInteger64(const char* szSection, const char* szKey, int64_t iDefaultValue)
|
||||||
{
|
|
||||||
ReadUnsignedInteger(szSection, szKey, static_cast<unsigned int>(iValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue)
|
|
||||||
{
|
{
|
||||||
rapidjson::Document& doc = get_json_document();
|
rapidjson::Document& doc = get_json_document();
|
||||||
rapidjson::Value& section = get_json_section(szSection);
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
if (!section.HasMember(szKey)) {
|
if (!section.HasMember(szKey)) {
|
||||||
section.AddMember(rapidjson::StringRef(szKey), bolDefaultValue, doc.GetAllocator());
|
section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator());
|
||||||
}
|
}
|
||||||
else if (!section[szKey].IsBool()) {
|
else if (!section[szKey].IsInt64()) {
|
||||||
section[szKey].SetBool(bolDefaultValue);
|
section[szKey].SetInt64(iDefaultValue);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return section[szKey].GetBool();
|
return section[szKey].GetInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
write_json_config();
|
write_json_config();
|
||||||
return section[szKey].GetBool();
|
return section[szKey].GetInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteBoolean(const char* szSection, const char* szKey, bool bolValue)
|
void WriteInteger64(const char* szSection, const char* szKey, int64_t iValue)
|
||||||
{
|
{
|
||||||
rapidjson::Document& doc = get_json_document();
|
rapidjson::Document& doc = get_json_document();
|
||||||
rapidjson::Value& section = get_json_section(szSection);
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
if (!section.HasMember(szKey)) {
|
if (!section.HasMember(szKey)) {
|
||||||
section.AddMember(rapidjson::StringRef(szKey), bolValue, doc.GetAllocator());
|
section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
section[szKey].SetBool(bolValue);
|
section[szKey].SetInt64(iValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_json_config();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ReadUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iDefaultValue)
|
||||||
|
{
|
||||||
|
rapidjson::Document& doc = get_json_document();
|
||||||
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
|
if (!section.HasMember(szKey)) {
|
||||||
|
section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
else if (!section[szKey].IsUint64()) {
|
||||||
|
section[szKey].SetUint64(iDefaultValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return section[szKey].GetUint64();
|
||||||
|
}
|
||||||
|
|
||||||
|
write_json_config();
|
||||||
|
return section[szKey].GetUint64();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iValue)
|
||||||
|
{
|
||||||
|
rapidjson::Document& doc = get_json_document();
|
||||||
|
rapidjson::Value& section = get_json_section(szSection);
|
||||||
|
|
||||||
|
if (!section.HasMember(szKey)) {
|
||||||
|
section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
section[szKey].SetUint64(iValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_json_config();
|
write_json_config();
|
||||||
|
@ -3,15 +3,19 @@
|
|||||||
|
|
||||||
namespace utils::json_config
|
namespace utils::json_config
|
||||||
{
|
{
|
||||||
|
bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue);
|
||||||
|
void WriteBoolean(const char* szSection, const char* szKey, bool bolValue);
|
||||||
|
|
||||||
std::string ReadString(const char* szSection, const char* szKey, const std::string& strDefaultValue);
|
std::string ReadString(const char* szSection, const char* szKey, const std::string& strDefaultValue);
|
||||||
void WriteString(const char* szSection, const char* szKey, const std::string& strValue);
|
void WriteString(const char* szSection, const char* szKey, const std::string& strValue);
|
||||||
|
|
||||||
unsigned int ReadUnsignedInteger(const char* szSection, const char* szKey, unsigned int iDefaultValue);
|
int32_t ReadInteger(const char* szSection, const char* szKey, int32_t iDefaultValue);
|
||||||
void WriteUnsignedInteger(const char* szSection, const char* szKey, unsigned int iValue);
|
void WriteInteger(const char* szSection, const char* szKey, int32_t iValue);
|
||||||
|
uint32_t ReadUnsignedInteger(const char* szSection, const char* szKey, uint32_t iDefaultValue);
|
||||||
|
void WriteUnsignedInteger(const char* szSection, const char* szKey, uint32_t iValue);
|
||||||
|
|
||||||
int ReadInteger(const char* szSection, const char* szKey, int iDefaultValue);
|
int64_t ReadInteger64(const char* szSection, const char* szKey, int64_t iDefaultValue);
|
||||||
void WriteInteger(const char* szSection, const char* szKey, int iValue);
|
void WriteInteger64(const char* szSection, const char* szKey, int64_t iValue);
|
||||||
|
uint64_t ReadUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iDefaultValue);
|
||||||
bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue);
|
void WriteUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iValue);
|
||||||
void WriteBoolean(const char* szSection, const char* szKey, bool bolValue);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user