_am: add search for OS main menu function
This commit is contained in:
parent
0f23fec85d
commit
12e6cd45a4
110
shell/a.cpp
110
shell/a.cpp
|
@ -142,6 +142,103 @@ void _ads(Session &session)
|
|||
ad_disassemble_all(space, addresses, true);
|
||||
}
|
||||
|
||||
//---
|
||||
// am
|
||||
//---
|
||||
|
||||
static void _am_cg_main_menu_function(VirtualSpace &vspace)
|
||||
{
|
||||
OS *os = vspace.os_analysis();
|
||||
if(!os) {
|
||||
FxOS_log(ERR, "no OS analysis");
|
||||
return;
|
||||
}
|
||||
|
||||
if(os->syscall_count() < 0x1e58) {
|
||||
FxOS_log(ERR, "less than 0x1e58 syscalls");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t sc_addr = os->syscall(0x1e58);
|
||||
fmt::print("syscall %%1e58 found at 0x{:08x}\n", sc_addr);
|
||||
|
||||
/* Check up to 150 instructions to find the call to the internal function
|
||||
SaveAndOpenMainMenu(). This call is in a widget of the shape
|
||||
|
||||
mov.l GetkeyToMainFunctionReturnFlag, rX
|
||||
mov #3, rY
|
||||
bsr SaveAndOpenMainMenu
|
||||
mov.b rY, @rX
|
||||
bra <start of widget>
|
||||
nop */
|
||||
for(int i = 0; i < 150; i++) {
|
||||
uint16_t i0 = vspace.read_u16(sc_addr + 2 * (i + 0));
|
||||
uint16_t i1 = vspace.read_u16(sc_addr + 2 * (i + 1));
|
||||
uint16_t i2 = vspace.read_u16(sc_addr + 2 * (i + 2));
|
||||
uint16_t i3 = vspace.read_u16(sc_addr + 2 * (i + 3));
|
||||
uint16_t i4 = vspace.read_u16(sc_addr + 2 * (i + 4));
|
||||
uint16_t i5 = vspace.read_u16(sc_addr + 2 * (i + 5));
|
||||
|
||||
/* Match: mov.l @(disp, pc), rX */
|
||||
if((i0 & 0xf000) != 0xd000)
|
||||
continue;
|
||||
int rX = (i0 >> 8) & 0x0f;
|
||||
|
||||
/* Match: mov #3, rY */
|
||||
if((i1 & 0xf0ff) != 0xe003)
|
||||
continue;
|
||||
int rY = (i1 >> 8) & 0x0f;
|
||||
|
||||
/* Match: bsr @(disp, pc) */
|
||||
if((i2 & 0xf000) != 0xb000)
|
||||
continue;
|
||||
int disp = (i2 & 0x0fff);
|
||||
|
||||
/* Match: mov.b rX, @rY */
|
||||
if((i3 != 0x2000 + (rX << 8) + (rY << 4)))
|
||||
continue;
|
||||
|
||||
/* Match: bra @(_, pc) */
|
||||
if((i4 & 0xf000) != 0xa000)
|
||||
continue;
|
||||
|
||||
/* Match: nop */
|
||||
if(i5 != 0x0009)
|
||||
continue;
|
||||
|
||||
/* Return the target of the bsr instruction */
|
||||
uint32_t fun_addr = sc_addr + 2*(i+2) + 4 + disp * 2;
|
||||
|
||||
fmt::print("found widget at 0x{:08x}\n", sc_addr + 2 * i);
|
||||
fmt::print("rX = r{}, rY = r{}, disp = {}\n", rX, rY, disp);
|
||||
fmt::print("main menu function address: 0x{:08x}\n", fun_addr);
|
||||
}
|
||||
}
|
||||
|
||||
static std::string parse_am(Session &session, Parser &parser)
|
||||
{
|
||||
if(!session.current_space)
|
||||
return "";
|
||||
|
||||
std::string name = parser.symbol();
|
||||
parser.end();
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void _am(Session &session, std::string name)
|
||||
{
|
||||
if(!session.current_space) {
|
||||
FxOS_log(ERR, "am: no virtual space");
|
||||
return;
|
||||
}
|
||||
|
||||
if(name == "cg_main_menu_function")
|
||||
_am_cg_main_menu_function(*session.current_space);
|
||||
else
|
||||
FxOS_log(ERR, "am: unknown misc. command '%s'", name);
|
||||
}
|
||||
|
||||
//---
|
||||
// Command definitions
|
||||
//---
|
||||
|
@ -174,3 +271,16 @@ Disassembles all syscalls entries using ad, which stores the results in the
|
|||
current virtual space's main disassembly. Unlike ad, this commands continues
|
||||
even if some syscalls fail to disassemble.
|
||||
)");
|
||||
|
||||
static ShellCommand _am_cmd(
|
||||
"am",
|
||||
[](Session &s, Parser &p) {
|
||||
auto name = parse_am(s, p);
|
||||
_am(s, name);
|
||||
},
|
||||
[](Session &s, Parser &p) { parse_am(s, p); },
|
||||
"Analysis: Misc functions", R"(
|
||||
am <name>
|
||||
|
||||
Runs miscellaneous analysis functions; commonly used for prototyping.
|
||||
)");
|
||||
|
|
Loading…
Reference in New Issue