mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-29 23:32:23 +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 <switch.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "creport_code_info.hpp"
|
#include "creport_code_info.hpp"
|
||||||
|
|
||||||
|
@ -19,7 +20,11 @@ void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mi.perm == Perm_Rx) {
|
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++;
|
this->code_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,3 +65,51 @@ bool CodeList::TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address) {
|
||||||
}
|
}
|
||||||
return false;
|
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 {
|
struct CodeInfo {
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
u8 id[0x20];
|
u8 build_id[0x20];
|
||||||
u64 start_address;
|
u64 start_address;
|
||||||
u64 end_address;
|
u64 end_address;
|
||||||
};
|
};
|
||||||
|
@ -21,4 +21,6 @@ class CodeList {
|
||||||
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
|
void ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr);
|
||||||
private:
|
private:
|
||||||
bool TryFindCodeRegion(Handle debug_handle, u64 guess, u64 *address);
|
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