some improvements

+ Improved blackbox's backtracer
+ Improved json config read/writer
This commit is contained in:
project-bo4 2023-09-23 16:17:57 -07:00
parent 866527b7e8
commit 55553a4099
4 changed files with 149 additions and 44 deletions

View File

@ -153,12 +153,12 @@ namespace blackbox
#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 "";
const auto* ctx = exceptioninfo->ContextRecord;
const auto* ctx = exception_info->ContextRecord;
std::string registers_scroll{};
registers_scroll.append("registers:\r\n{\r\n");
@ -191,29 +191,36 @@ namespace blackbox
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");
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]);
size_t rva = reinterpret_cast<uint64_t>(stack[i]) - reinterpret_cast<uint64_t>(prnt.get_ptr());
const auto from = utils::nt::library::get_by_address(backtrace_stack[i]);
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)
{
const auto main_module = utils::nt::library{};
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{};
const auto line = [&info](const std::string& text)
@ -239,7 +246,7 @@ namespace blackbox
}
line("\r\n");
line(get_callstack_summary(18));
line(get_callstack_summary(rip_address));
line(get_memory_registers(exceptioninfo));
line("\r\nTimestamp: "s + get_timestamp());

View File

@ -18,7 +18,7 @@ namespace platform
if (!userid)
{
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;

View File

@ -70,6 +70,41 @@ namespace utils::json_config
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)
{
rapidjson::Document& doc = get_json_document();
@ -104,7 +139,42 @@ namespace utils::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::Value& section = get_json_section(szSection);
@ -123,12 +193,7 @@ namespace utils::json_config
return section[szKey].GetUint();
}
int ReadInteger(const char* szSection, const char* szKey, int iDefaultValue)
{
return static_cast<int>(ReadUnsignedInteger(szSection, szKey, static_cast<unsigned int>(iDefaultValue)));
}
void WriteUnsignedInteger(const char* szSection, const char* szKey, unsigned int iValue)
void WriteUnsignedInteger(const char* szSection, const char* szKey, uint32_t iValue)
{
rapidjson::Document& doc = get_json_document();
rapidjson::Value& section = get_json_section(szSection);
@ -143,40 +208,69 @@ namespace utils::json_config
write_json_config();
}
void WriteInteger(const char* szSection, const char* szKey, int iValue)
{
ReadUnsignedInteger(szSection, szKey, static_cast<unsigned int>(iValue));
}
bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue)
int64_t ReadInteger64(const char* szSection, const char* szKey, int64_t iDefaultValue)
{
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());
section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator());
}
else if (!section[szKey].IsBool()) {
section[szKey].SetBool(bolDefaultValue);
else if (!section[szKey].IsInt64()) {
section[szKey].SetInt64(iDefaultValue);
}
else {
return section[szKey].GetBool();
return section[szKey].GetInt64();
}
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::Value& section = get_json_section(szSection);
if (!section.HasMember(szKey)) {
section.AddMember(rapidjson::StringRef(szKey), bolValue, doc.GetAllocator());
section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator());
}
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();

View File

@ -3,15 +3,19 @@
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);
void WriteString(const char* szSection, const char* szKey, const std::string& strValue);
unsigned int ReadUnsignedInteger(const char* szSection, const char* szKey, unsigned int iDefaultValue);
void WriteUnsignedInteger(const char* szSection, const char* szKey, unsigned int iValue);
int32_t ReadInteger(const char* szSection, const char* szKey, int32_t iDefaultValue);
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);
void WriteInteger(const char* szSection, const char* szKey, int iValue);
bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue);
void WriteBoolean(const char* szSection, const char* szKey, bool bolValue);
int64_t ReadInteger64(const char* szSection, const char* szKey, int64_t iDefaultValue);
void WriteInteger64(const char* szSection, const char* szKey, int64_t iValue);
uint64_t ReadUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iDefaultValue);
void WriteUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iValue);
}