1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-11-06 04:01:44 +00:00

creport: fix various issues, improve support (closes #187)

-Fixes a NULL deref in thread info parsing
-Heuristically uses [<buildid>] instead of rodata contents if NSO has no
name segment
-Adds full thread/code region dump for all firmwares, instead of just
5.x.
This commit is contained in:
Michael Scire 2018-08-11 18:46:41 -07:00
parent 761ab4fcfe
commit 6c8a1a39e1
3 changed files with 44 additions and 13 deletions

View file

@ -36,8 +36,14 @@ void CodeList::ReadCodeRegionsFromProcess(Handle debug_handle, u64 pc, u64 lr) {
/* Parse CodeInfo. */ /* Parse CodeInfo. */
this->code_infos[this->code_count].start_address = mi.addr; this->code_infos[this->code_count].start_address = mi.addr;
this->code_infos[this->code_count].end_address = mi.addr + mi.size; 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); GetCodeInfoName(debug_handle, mi.addr, 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); GetCodeInfoBuildId(debug_handle, mi.addr + mi.size, this->code_infos[this->code_count].build_id);
if (this->code_infos[this->code_count].name[0] == '\x00') {
snprintf(this->code_infos[this->code_count].name, 0x1F, "[%02x%02x%02x%02x]", this->code_infos[this->code_count].build_id[0],
this->code_infos[this->code_count].build_id[1],
this->code_infos[this->code_count].build_id[2],
this->code_infos[this->code_count].build_id[3]);
}
this->code_count++; this->code_count++;
} }
@ -79,12 +85,38 @@ 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) { void CodeList::GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 rodata_addr, char *name) {
char name_in_proc[0x200]; char name_in_proc[0x200];
/* Clear name. */ /* Clear name. */
memset(name, 0, 0x20); memset(name, 0, 0x20);
/* Check whether this NSO *has* a name... */
{
u64 rodata_start[0x20/sizeof(u64)];
MemoryInfo mi;
u32 pi;
u64 rw_address;
/* Verify .rodata is read-only. */
if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, rodata_addr)) || mi.perm != Perm_R) {
return;
}
/* rwdata is after rodata. */
rw_address = mi.addr + mi.size;
/* Read start of .rodata. */
if (R_FAILED(svcReadDebugProcessMemory(rodata_start, debug_handle, rodata_addr, sizeof(rodata_start)))) {
return;
}
/* Check if name section is present. */
if (rodata_start[0] == (rw_address - rx_address)) {
return;
}
}
/* Read name out of .rodata. */ /* Read name out of .rodata. */
if (R_FAILED(svcReadDebugProcessMemory(name_in_proc, debug_handle, rodata_addr + 8, sizeof(name_in_proc)))) { if (R_FAILED(svcReadDebugProcessMemory(name_in_proc, debug_handle, rodata_addr + 8, sizeof(name_in_proc)))) {
return; return;

View file

@ -25,6 +25,6 @@ class CodeList {
void SaveToFile(FILE *f_report); void SaveToFile(FILE *f_report);
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 GetCodeInfoName(u64 debug_handle, u64 rx_address, u64 ro_address, char *name);
void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id); void GetCodeInfoBuildId(u64 debug_handle, u64 ro_address, u8 *build_id);
}; };

View file

@ -11,10 +11,9 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
this->has_extra_info = has_extra_info; this->has_extra_info = has_extra_info;
if (OpenProcess(pid)) { if (OpenProcess(pid)) {
ProcessExceptions(); ProcessExceptions();
if (kernelAbove500()) { this->code_list.ReadCodeRegionsFromProcess(this->debug_handle, this->crashed_thread_info.GetPC(), this->crashed_thread_info.GetLR());
this->code_list.ReadCodeRegionsFromProcess(this->debug_handle, this->crashed_thread_info.GetPC(), this->crashed_thread_info.GetLR()); this->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit());
this->thread_list.ReadThreadsFromProcess(this->debug_handle, Is64Bit()); this->crashed_thread_info.SetCodeList(&this->code_list);
}
this->thread_list.SetCodeList(&this->code_list); this->thread_list.SetCodeList(&this->code_list);
if (IsApplication()) { if (IsApplication()) {
@ -287,11 +286,11 @@ void CrashReport::SaveToFile(FILE *f_report) {
fprintf(f_report, " Size: 0x%016lx\n", this->dying_message_size); fprintf(f_report, " Size: 0x%016lx\n", this->dying_message_size);
CrashReport::Memdump(f_report, " Dying Message: ", this->dying_message, this->dying_message_size); CrashReport::Memdump(f_report, " Dying Message: ", this->dying_message, this->dying_message_size);
} }
fprintf(f_report, "Code Region Info:\n");
this->code_list.SaveToFile(f_report);
fprintf(f_report, "\nThread Report:\n");
this->thread_list.SaveToFile(f_report);
} }
fprintf(f_report, "Code Region Info:\n");
this->code_list.SaveToFile(f_report);
fprintf(f_report, "\nThread Report:\n");
this->thread_list.SaveToFile(f_report);
} }
/* Lifted from hactool. */ /* Lifted from hactool. */