Skip to content

Commit

Permalink
better string extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed Oct 13, 2024
1 parent 9ad4dac commit 63aeac7
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 79 deletions.
125 changes: 64 additions & 61 deletions src/acts/tools/gsc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,25 +426,6 @@ int GSCOBJHandler::PatchCode(T8GSCOBJContext& ctx) {
}
}

uintptr_t str_location = reinterpret_cast<uintptr_t>(file) + GetStringsOffset();
int string_count = (int)GetStringsCount();
for (size_t i = 0; i < string_count; i++) {

const auto* str = reinterpret_cast<T8GSCString*>(str_location);
char* cstr = DecryptString(Ptr<char>(str->string));
if (gDumpStrings) {
gDumpStringsStore.insert(cstr);
}
uint32_t ref = ctx.AddStringValue(cstr);

const auto* strings = reinterpret_cast<const uint32_t*>(&str[1]);
for (size_t j = 0; j < str->num_address; j++) {
Ref<uint32_t>(strings[j]) = ref;
ctx.AddStringRef(strings[j], ref);
}
str_location += sizeof(*str) + sizeof(*strings) * str->num_address;
}

if (GetDevStringsOffset() && !(ctx.m_formatter && ctx.m_formatter->flags & tool::gsc::formatter::FFL_NOERROR_STR)) {
T8GSCString* val = Ptr<T8GSCString>(GetDevStringsOffset());
for (size_t i = 0; i < GetDevStringsCount(); i++) {
Expand Down Expand Up @@ -475,6 +456,25 @@ int GSCOBJHandler::PatchCode(T8GSCOBJContext& ctx) {
}
}

uintptr_t str_location = reinterpret_cast<uintptr_t>(file) + GetStringsOffset();
int string_count = (int)GetStringsCount();
for (size_t i = 0; i < string_count; i++) {

const auto* str = reinterpret_cast<T8GSCString*>(str_location);
char* cstr = DecryptString(Ptr<char>(str->string));
if (gDumpStrings) {
gDumpStringsStore.insert(cstr);
}
uint32_t ref = ctx.AddStringValue(cstr);

const auto* strings = reinterpret_cast<const uint32_t*>(&str[1]);
for (size_t j = 0; j < str->num_address; j++) {
Ref<uint32_t>(strings[j]) = ref;
ctx.AddStringRef(strings[j], ref);
}
str_location += sizeof(*str) + sizeof(*strings) * str->num_address;
}

auto imports_count = (int)GetImportsCount();
uintptr_t import_location = reinterpret_cast<uintptr_t>(file) + GetImportsOffset();
for (size_t i = 0; i < imports_count; i++) {
Expand Down Expand Up @@ -634,26 +634,6 @@ int GSCOBJHandler::PatchCode(T8GSCOBJContext& ctx) {
gvars_location += sizeof(*globalvar) + sizeof(*vars) * globalvar->num_address;
}

uintptr_t str_location = reinterpret_cast<uintptr_t>(file) + GetStringsOffset();
int string_count = (int)GetStringsCount();
for (size_t i = 0; i < string_count; i++) {

const auto* str = reinterpret_cast<T8GSCString*>(str_location);
char* cstr = DecryptString(Ptr<char>(str->string));
if (gDumpStrings) {
gDumpStringsStore.insert(cstr);
}
uint32_t ref = ctx.AddStringValue(cstr);

const auto* strings = reinterpret_cast<const uint32_t*>(&str[1]);
for (size_t j = 0; j < str->num_address; j++) {
// no align too....
Ref<uint32_t>(strings[j]) = ref;
ctx.AddStringRef(strings[j], ref);
}
str_location += sizeof(*str) + sizeof(*strings) * str->num_address;
}

if (GetDevStringsOffset() && !(ctx.m_formatter && ctx.m_formatter->flags & tool::gsc::formatter::FFL_NOERROR_STR)) {
T8GSCString* val = Ptr<T8GSCString>(GetDevStringsOffset());
for (size_t i = 0; i < GetDevStringsCount(); i++) {
Expand Down Expand Up @@ -684,6 +664,26 @@ int GSCOBJHandler::PatchCode(T8GSCOBJContext& ctx) {
}
}

uintptr_t str_location = reinterpret_cast<uintptr_t>(file) + GetStringsOffset();
int string_count = (int)GetStringsCount();
for (size_t i = 0; i < string_count; i++) {

const auto* str = reinterpret_cast<T8GSCString*>(str_location);
char* cstr = DecryptString(Ptr<char>(str->string));
if (gDumpStrings) {
gDumpStringsStore.insert(cstr);
}
uint32_t ref = ctx.AddStringValue(cstr);

const auto* strings = reinterpret_cast<const uint32_t*>(&str[1]);
for (size_t j = 0; j < str->num_address; j++) {
// no align too....
Ref<uint32_t>(strings[j]) = ref;
ctx.AddStringRef(strings[j], ref);
}
str_location += sizeof(*str) + sizeof(*strings) * str->num_address;
}

if (GetAnimTreeDoubleOffset()) {
uintptr_t animt_location = reinterpret_cast<uintptr_t>(file) + GetAnimTreeDoubleOffset();
auto anims_count = (int)GetAnimTreeDoubleCount();
Expand Down Expand Up @@ -1317,6 +1317,27 @@ int GscInfoHandleData(byte* data, size_t size, const char* path, GscDecompilerGl

// write the strings before the patch to avoid reading pre-decrypted strings
if (opt.m_strings) {
if (scriptfile->GetDevStringsOffset() && !(opt.m_formatter->flags & tool::gsc::formatter::FFL_NOERROR_STR)) {
T8GSCString* val = scriptfile->Ptr<T8GSCString>(scriptfile->GetDevStringsOffset());
for (size_t i = 0; i < scriptfile->GetDevStringsCount(); i++) {

const char* str = utils::va("<dev string:x%x>", val->string); // Ptr<char>(val->string); // no gdb

asmout << "Dev String: "
<< "addr:" << std::hex << val->string << ", "
<< "count:" << std::dec << (int)val->num_address << ", stype:"
<< (int)val->type << " -> \"" << str << "\"\n";
asmout << "loc: ";

uint32_t* loc = reinterpret_cast<uint32_t*>(val + 1);
for (size_t j = 0; j < val->num_address; j++) {
asmout << " 0x" << std::hex << loc[j];
}

asmout << "\n";
val = reinterpret_cast<T8GSCString*>(loc + val->num_address);
}
}
if (scriptfile->GetStringsOffset()) {
uintptr_t str_location = reinterpret_cast<uintptr_t>(scriptfile->Ptr(scriptfile->GetStringsOffset()));

Expand Down Expand Up @@ -1390,27 +1411,6 @@ int GscInfoHandleData(byte* data, size_t size, const char* path, GscDecompilerGl
str_location += sizeof(*str) + sizeof(*strings) * str->num_address;
}
}
if (scriptfile->GetDevStringsOffset() && !(opt.m_formatter->flags & tool::gsc::formatter::FFL_NOERROR_STR)) {
T8GSCString* val = scriptfile->Ptr<T8GSCString>(scriptfile->GetDevStringsOffset());
for (size_t i = 0; i < scriptfile->GetDevStringsCount(); i++) {

const char* str = utils::va("<dev string:x%x>", val->string); // Ptr<char>(val->string); // no gdb

asmout << "Dev String: "
<< "addr:" << std::hex << val->string << ", "
<< "count:" << std::dec << (int)val->num_address << ", stype:"
<< (int)val->type << " -> \"" << str << "\"\n";
asmout << "loc: ";

uint32_t* loc = reinterpret_cast<uint32_t*>(val + 1);
for (size_t j = 0; j < val->num_address; j++) {
asmout << " 0x" << std::hex << loc[j];
}

asmout << "\n";
val = reinterpret_cast<T8GSCString*>(loc + val->num_address);
}
}

if (scriptfile->GetStringsCount() || scriptfile->GetDevStringsCount()) {
asmout << "\n";
Expand Down Expand Up @@ -2375,7 +2375,10 @@ const char* tool::gsc::T8GSCOBJContext::GetStringValueOrError(uint32_t stringRef
if (v) {
return v;
}

return GetStringError(floc, errorValue);
}

const char* tool::gsc::T8GSCOBJContext::GetStringError(uint32_t floc, const char* errorValue) {
if (errorValue) {
m_unkstrings[errorValue].insert(floc);
}
Expand Down
6 changes: 6 additions & 0 deletions src/acts/tools/gsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,12 @@ namespace tool::gsc {
* @return string or error value
*/
const char* GetStringValueOrError(uint32_t stringRef, uint32_t floc, const char* errorValue);
/*
* Get a string for a string ref, return errorValue in case of error
* @param errorValue returned value in case of bad ref
* @return string or error value
*/
const char* GetStringError(uint32_t floc, const char* errorValue);
/*
* Add a global var
* @param value name
Expand Down
3 changes: 0 additions & 3 deletions src/acts/tools/gsc_opcode_nodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1376,9 +1376,6 @@ namespace tool::gsc::opcode {
if ((ctx.opt.m_formatter->flags & tool::gsc::formatter::FFL_NEWLINE_AFTER_BLOCK_START) && (ctx.opt.m_formatter->flags & tool::gsc::formatter::FFL_SWITCH_FORCE_BLOCKS)) {
ctx.WritePadding(out << "\n", true);
}
else {
out << " ";
}
cs.block->Dump(out, ctx);
}
}
Expand Down
36 changes: 21 additions & 15 deletions src/acts/tools/gsc_opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3708,7 +3708,13 @@ class OPCodeInfoGetString : public OPCodeInfo {

uint32_t ref = *(uint32_t*)base;

const char* str = objctx.GetStringValueOrError(ref, context.ScriptAbsoluteLocation(base), nullptr);
uint32_t floc = context.ScriptAbsoluteLocation(base);

const char* str = objctx.GetStringValueByLoc(floc);
if (!str) {
// build string
str = objctx.GetStringError(floc, nullptr);
}

base += 4;

Expand Down Expand Up @@ -4018,29 +4024,29 @@ class OPCodeInfoSwitch : public OPCodeInfo {
}
else {
out << "case ";
if (caseValue >= 0x100000000LL) {
// bo3 string decomp
uint32_t floc = (uint32_t)(caseLoc - context.m_gscReader.file);
const char* cv = objctx.GetStringValueByLoc(floc);
if (cv) {
PrintFormattedString(out << "\"", cv) << "\"";
if (node) {
node->m_cases.push_back({ new ASMContextNodeString(cv), caseRLoc });
}
}
else if (caseValue >= 0x100000000LL) {
// assume it's an hash after int32_t max value
out << "#\"" << hashutils::ExtractTmp("hash", caseValue) << "\"" << std::flush;
if (node) {
node->m_cases.push_back({ new ASMContextNodeHash(caseValue, false, "#"), caseRLoc });
}
}
else {
// bo3 string decomp
const char* cv = objctx.GetStringValueByLoc((uint32_t)(caseLoc - context.m_gscReader.file));
if (cv) {
PrintFormattedString(out << "\"", cv) << "\"";
if (node) {
node->m_cases.push_back({ new ASMContextNodeValue<const char*>(cv, TYPE_VALUE), caseRLoc });
}
}
else {
out << std::dec << caseValue;
if (node) {
node->m_cases.push_back({ new ASMContextNodeValue<int64_t>(caseValue, TYPE_VALUE), caseRLoc });
}
out << std::dec << caseValue;
if (node) {
node->m_cases.push_back({ new ASMContextNodeValue<int64_t>(caseValue, TYPE_VALUE), caseRLoc });
}
}
out << "(0x" << std::hex << floc << ")";
}

out << ": ." << std::hex << std::setfill('0') << std::setw(sizeof(int32_t) << 1)
Expand Down

0 comments on commit 63aeac7

Please sign in to comment.