yifanlu / taiHEN

CFW framework for PS Vita
MIT License
307 stars 46 forks source link

Add start module handler #70

Open TheOfficialFloW opened 7 years ago

TheOfficialFloW commented 7 years ago

Provide kernel and user export for registering handlers that capture the moment a module is started. Here is an example of how this can be done: https://github.com/TheOfficialFloW/taiHEN/commit/f86436385e4c071a9c06b490823f981b58184a63 (This however does not capture kernel module loads yet)

TheOfficialFloW commented 7 years ago

It might be a good idea to capture both start and stop of a module, so that we can easily hook/release specific patches.

yifanlu commented 7 years ago

Realistically I won't have the time to implement (& test) this feature.

TheOfficialFloW commented 7 years ago

If you describe how you imagine the implementation of this feature, I can do it.

yifanlu commented 7 years ago

I'm not sure what you want though. A callback before and after module_stop/module_stop?

TheOfficialFloW commented 7 years ago

Exactly

yifanlu commented 7 years ago

Isn't it possible to just hook the module_start export before calling start module?

TheOfficialFloW commented 7 years ago

The idea is that we invoke our callback at module_start/stop of every module. If you just hook the module_start export, you'd need to to it after the module is loaded but not yet started, so this won't be any different than manually hook load/start... The reason we need this is because there are at least 6 different methods to load modules and if you want to hook many weak imports you'd need to hook all these functions which is a waste...

If you still can't imagine what I'm meaning, there exists the same API for PSP CFW: sctrlHENSetStartModuleHandler

yifanlu commented 7 years ago

I see. Can we generalize it and not worry about module_start/stop? So we currently have hooks and injections. How about we add a third category called "events" and we can have int taiEventsAddHandlerForKernel(int pid, tai_event_t event, tai_event_callback_t handler); which returns a uid and taiEventsRemoveHandlerForKernel(int uid);

Then we have

typedef enum _tai_event {
  TAI_EVENT_MODULE_LOAD,
  TAI_EVENT_MODULE_START,
  TAI_EVENT_MODULE_STOP,
  TAI_EVENT_MODULE_UNLOAD,
  TAI_EVENT_MAX
} tai_event_t;

typedef struct _tai_event_module_start {
  tai_event_t event;
  SceUID modid;
  // other useful params
  SceSize args; // from module_start
  void *argp; // from module_start
} tai_event_module_start_t;

typedef struct _tai_event_module_stop {
  tai_event_t event;
  SceUID modid;
  // other useful params
  SceSize args; // from module_stop
  void *argp; // from module_stop
} tai_event_module_stop_t;

// and so on...

typedef union _tai_event_args {
  tai_event_t event;
  tai_event_module_load_t module_load_event;
  tai_event_module_start_t module_start_event;
  tai_event_module_stop_t module_stop_event;
  tai_event_module_unload_t module_unload_event;
} tai_event_args_t;

typedef void (*tai_event_callback_t)(tai_event_args_t *args);

Implementation wise, I think we can have a hashmap of PID to event handler mappings. Each value will point to a static array of size TAI_EVENT_MAX where each array element is a linked list of handlers.

To trigger an event, we just look up the PID in O(1), and then index in the array in O(1) and then call each O(N) handlers.

You can use the same callback function to handle multiple events.