tp-spy.c
/**
* Attempt to intercept all TryPostEvent calls
*
* Usage:
*
* 1) Make sure the cache hack is working.
* For example, add this in boot-hack.c:
* // Make sure that our self-modifying code clears the cache
* clean_d_cache();
* flush_caches();
* + cache_lock();
*
*
* 2) call "tp_intercept" from "don't click me"
*
**/
#include "dryos.h"
#include "bmp.h"
#include "cache_hacks.h"
//~ #define BUF_SIZE (1024*1024)
//~ static char* buf = 0;
//~ static int len = 0;
extern thunk TryPostEvent;
extern thunk TryPostEvent_end;
extern thunk TryPostStageEvent;
extern thunk TryPostStageEvent_end;
#define reloc_start ((uintptr_t)&TryPostEvent)
#define reloc_end ((uintptr_t)&TryPostEvent_end)
#define reloc_len (reloc_end - reloc_start)
#define reloc_start2 ((uintptr_t)&TryPostStageEvent)
#define reloc_end2 ((uintptr_t)&TryPostStageEvent_end)
#define reloc_len2 (reloc_end2 - reloc_start2)
static uintptr_t reloc_buf = 0;
static uintptr_t reloc_buf2 = 0;
static int (*new_TryPostEvent)(int taskclass, int obj, int event, int arg1, int arg2) = 0;
static int (*new_TryPostStageEvent)(int taskclass, int obj, int event, int arg1, int arg2) = 0;
static char callstack[100];
char* get_call_stack()
{
uintptr_t sp = 0;
asm __volatile__ (
"mov %0, %%sp"
: "=&r"(sp)
);
callstack[0] = 0;
for (int i = 0; i < 100; i++)
{
if ((MEM(sp+i*4) & 0xFF000000) == 0xFF000000)
{
STR_APPEND(callstack, "%x ", MEM(sp+i*4));
}
}
return callstack;
}
int my_TryPostEvent(int taskclass, int obj, int event, int arg3, int arg4)
{
DryosDebugMsg(0,0,"[%d] *** TryPostEvent(%x, %x %s, %x, %x [%x %x %x %x], %x)\n call stack: %s", get_ms_clock_value(), taskclass, obj, MEM(obj), event, arg3, MEM(arg3), MEM(arg3+4), MEM(arg3+8), MEM(arg3+12), arg4, get_call_stack());
if (streq(MEM(obj), "PropMgr"))
{
if (event == 3)
{
DryosDebugMsg(0,0," prop_deliver(&0x%x, 0x%x, 0x%x)", MEM(MEM(arg3)), MEM(arg3+4), arg4);
}
else if (event == 7)
{
DryosDebugMsg(0,0," prop_request_change(0x%x, &0x%x, 0x%x)", MEM(arg3), MEM(MEM(arg3+4)), arg4);
}
}
return new_TryPostEvent(taskclass, obj, event, arg3, arg4);
}
int my_TryPostStageEvent(int taskclass, int obj, int event, int arg3, int arg4)
{
DryosDebugMsg(0,0,"[%d] *** TryPostStageEvent(%x, %x %s, %x, %x [%x %x %x %x], %x)", get_ms_clock_value(), taskclass, obj, MEM(obj), event, arg3, MEM(arg3), MEM(arg3+4), MEM(arg3+8), MEM(arg3+12), arg4 );
return new_TryPostStageEvent(taskclass, obj, event, arg3, arg4);
}
// call this from "don't click me"
void tp_intercept()
{
//~ if (!buf) // first call, intercept debug messages
{
//~ buf = alloc_dma_memory(BUF_SIZE);
if (!reloc_buf) reloc_buf = (uintptr_t) AllocateMemory(reloc_len + 64);
if (!reloc_buf2) reloc_buf2 = (uintptr_t) AllocateMemory(reloc_len2 + 64);
new_TryPostEvent = reloc(
0, // we have physical memory
0, // with no virtual offset
reloc_start,
reloc_end,
reloc_buf
);
new_TryPostStageEvent = reloc(
0, // we have physical memory
0, // with no virtual offset
reloc_start2,
reloc_end2,
reloc_buf2
);
cache_fake((uint32_t)&TryPostEvent, B_INSTR((uint32_t)&TryPostEvent, my_TryPostEvent), TYPE_ICACHE);
cache_fake((uint32_t)&TryPostStageEvent, B_INSTR((uint32_t)&TryPostStageEvent, my_TryPostStageEvent), TYPE_ICACHE);
//~ NotifyBox(2000, "Now logging... ALL TryPostEvent's :)", len);
}
//~ else // subsequent call, save log to file
//~ {
//~ dump_seg(buf, len, CARD_DRIVE"tp.log");
//~ NotifyBox(2000, "Saved %d bytes.", len);
//~ }
//~ beep();
}