mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 13:52:21 +00:00
creport: Implement reading name/build id from .rodata
This commit is contained in:
parent
f189610af8
commit
92bc396972
2 changed files with 57 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
|||
#include <switch.h>
|
||||
#include <cstring>
|
||||
|
||||
#include "creport_code_info.hpp"
|
||||
|
||||
|
@ -19,7 +20,11 @@ void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
|
|||
}
|
||||
|
||||
if (mi.perm == Perm_Rx) {
|
||||
/* TODO: Parse CodeInfo. */
|
||||
/* Parse CodeInfo. */
|
||||
this->code_infos[this->code_count].start_address = mi.addr;
|
||||
this->code_infos[this->code_count].end_address = mi.addr + mi.size;
|
||||
GetCodeInfoName(debug_handle, mi.addr + mi.size, this->code_infos[this->code_count].name);
|
||||
GetCodeInfoBuildId(debug_handle, mi.addr + mi.size, this->code_infos[this->code_count].build_id);
|
||||
this->code_count++;
|
||||
}
|
||||
|
||||
|
@ -59,4 +64,52 @@ bool CodeList::TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address) {
|
|||
guess -= 4;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CodeList::GetCodeInfoName(u64 debug_handle, u64 rodata_addr, char *name) {
|
||||
char name_in_proc[0x200];
|
||||
|
||||
/* Clear name. */
|
||||
memset(name, 0, 0x20);
|
||||
|
||||
/* Read name out of .rodata. */
|
||||
if (R_FAILED(svcReadDebugProcessMemory(name_in_proc, debug_handle, rodata_addr + 8, sizeof(name_in_proc)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start after last slash in path. */
|
||||
int ofs = strnlen(name_in_proc, sizeof(name_in_proc));
|
||||
while (ofs >= 0 && name_in_proc[ofs] != '/' && name_in_proc[ofs] != '\\') {
|
||||
ofs--;
|
||||
}
|
||||
|
||||
strncpy(name, name_in_proc + ofs + 1, 0x20);
|
||||
name[0x1F] = '\x00';
|
||||
}
|
||||
|
||||
void CodeList::GetCodeInfoBuildId(u64 debug_handle, u64 rodata_addr, u8 *build_id) {
|
||||
MemoryInfo mi;
|
||||
u32 pi;
|
||||
|
||||
/* Clear build id. */
|
||||
memset(build_id, 0, 0x20);
|
||||
|
||||
/* Verify .rodata is read-only. */
|
||||
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, rodata_addr)) || mi.perm != Perm_R) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We want to read the last two pages of .rodata. */
|
||||
u8 last_pages[0x2000];
|
||||
size_t last_pages_size = mi.size >= 0x2000 ? 0x2000 : 0x1000;
|
||||
if (R_FAILED(svcReadDebugProcessMemory(last_pages, debug_handle, mi.addr + mi.size - last_pages_size, last_pages_size))) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find GNU\x00 to locate start of Build ID. */
|
||||
for (int ofs = last_pages_size - 0x24; ofs >= 0; ofs--) {
|
||||
if (memcmp(last_pages + ofs, "GNU\x00", 4) == 0) {
|
||||
memcpy(build_id, last_pages + ofs + 4, 0x20);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
struct CodeInfo {
|
||||
char name[0x20];
|
||||
u8 id[0x20];
|
||||
u8 build_id[0x20];
|
||||
u64 start_address;
|
||||
u64 end_address;
|
||||
};
|
||||
|
@ -21,4 +21,6 @@ class CodeList {
|
|||
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
|
||||
private:
|
||||
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);
|
||||
void GetCodeInfoName(u64 debug_handle, u64 ro_address, char *name);
|
||||
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue