taiHEN
1.0
CFW framework for PS Vita
|
Patches functions. More...
Data Structures | |
struct | _tai_hook_user |
Internal structure. More... | |
Macros | |
#define | TAI_CONTINUE(type, hook, ...) |
Calls the next function in the chain. More... | |
Typedefs | |
typedef uintptr_t | tai_hook_ref_t |
Hook information. More... | |
Kernel Hooks | |
SceUID | taiHookFunctionAbs (SceUID pid, tai_hook_ref_t *p_hook, void *dest_func, const void *hook_func) |
Add a hook given an absolute address. More... | |
SceUID | taiHookFunctionExportForKernel (SceUID pid, tai_hook_ref_t *p_hook, const char *module, uint32_t library_nid, uint32_t func_nid, const void *hook_func) |
Add a hook to a module function export. More... | |
SceUID | taiHookFunctionImportForKernel (SceUID pid, tai_hook_ref_t *p_hook, const char *module, uint32_t import_library_nid, uint32_t import_func_nid, const void *hook_func) |
Add a hook to a module function import. More... | |
SceUID | taiHookFunctionOffsetForKernel (SceUID pid, tai_hook_ref_t *p_hook, SceUID modid, int segidx, uint32_t offset, int thumb, const void *hook_func) |
Add a hook to a module manually with an offset. More... | |
int | taiGetModuleInfoForKernel (SceUID pid, const char *module, tai_module_info_t *info) |
Gets information on a currently loaded module. More... | |
int | taiHookReleaseForKernel (SceUID tai_uid, tai_hook_ref_t hook) |
Release a hook. More... | |
User Hooks | |
SceUID | taiHookFunctionExportForUser (tai_hook_ref_t *p_hook, tai_hook_args_t *args) |
Add a hook to a module function export for the calling process. More... | |
SceUID | taiHookFunctionImportForUser (tai_hook_ref_t *p_hook, tai_hook_args_t *args) |
Add a hook to a module function import for the calling process. More... | |
SceUID | taiHookFunctionOffsetForUser (tai_hook_ref_t *p_hook, tai_offset_args_t *args) |
Add a hook to a module manually with an offset for the calling process. More... | |
int | taiGetModuleInfo (const char *module, tai_module_info_t *info) |
Gets information on a currently loaded module. More... | |
int | taiHookRelease (SceUID tai_uid, tai_hook_ref_t hook) |
Release a hook for the calling process. More... | |
HELPER SceUID | taiHookFunctionExport (tai_hook_ref_t *p_hook, const char *module, uint32_t library_nid, uint32_t func_nid, const void *hook_func) |
Helper function for taiHookFunctionExportForUser. More... | |
HELPER SceUID | taiHookFunctionImport (tai_hook_ref_t *p_hook, const char *module, uint32_t import_library_nid, uint32_t import_func_nid, const void *hook_func) |
Helper function for taiHookFunctionImportForUser. More... | |
HELPER SceUID | taiHookFunctionOffset (tai_hook_ref_t *p_hook, SceUID modid, int segidx, uint32_t offset, int thumb, const void *hook_func) |
Helper function for taiHookFunctionOffsetForUser. More... | |
Patches functions.
A function hook allows a plugin to run code before and after a any function call. As an example, say we wish to hook sceIoOpenForDriver
If we wish to log the path of any kernel file opens, we can write this
Note that it is the user's responsibility to ensure that the function prototype matches. What if we want to log the return values too?
For a more complicated example, we can redirect a file open as follows
Note that we use the TAI_CONTINUE
macro in order to continue the chain. You should always do this because it ensures all hooks get their share of the pie. Consider this bad example
This prevents any other hooks from running. This would break, for example, our logging hook above. Instead you should do
Another common use case is the ability to call the original function. The recommended way of doing this is to make the original function call
Note that calling the original sceIoOpenForDriver
will recurse back to recurse_open_hook
so it is very important to avoid an infinite recursion. In this case, we check that the parameter is not the same, but more complex checks may be needed for other function.
#define TAI_CONTINUE | ( | type, | |
hook, | |||
... | |||
) |
Calls the next function in the chain.
type | Return type |
hook | The hook continuing the call |
typedef uintptr_t tai_hook_ref_t |
int taiGetModuleInfo | ( | const char * | module, |
tai_module_info_t * | info | ||
) |
Gets information on a currently loaded module.
You can use the macro TAI_MAIN_MODULE
for module
to specify the main module. This is usually the module that is loaded first and is usually the eboot.bin. This will only work if there is only one module loaded in the main memory space. Not all processes have this property! Make sure you check the return value.
[in] | module | The name of the module or TAI_MAIN_MODULE . |
[out] | info | The information to fill |
info->size
is too small or large or module
is invalidTAI_MAIN_MODULE
is specified and there are multiple main modules Definition at line 209 of file taihen-user.c.
int taiGetModuleInfoForKernel | ( | SceUID | pid, |
const char * | module, | ||
tai_module_info_t * | info | ||
) |
Gets information on a currently loaded module.
You should use this before calling taiHookFunctionOffsetForKernel
in order to check that the module you wish to hook is currently loaded and that the module NID matches. The module NID changes in each version of the module.
[in] | pid | The pid of the caller (kernel should set to KERNEL_PID) |
[in] | module | The name of the module |
[out] | info | The information to fill |
module
is TAI_MAIN_MODULE
and pid
is kernel SceUID taiHookFunctionAbs | ( | SceUID | pid, |
tai_hook_ref_t * | p_hook, | ||
void * | dest_func, | ||
const void * | hook_func | ||
) |
Add a hook given an absolute address.
If target is the kernel, use KERNEL_PID as pid
.
[in] | pid | The pid of the target |
[out] | p_hook | A reference that can be used by the hook function |
dest_func | The function to patch (must be in the target address space) | |
[in] | hook_func | The hook function (must be in the target address space) |
pid
is kernel and address is in shared memory region HELPER SceUID taiHookFunctionExport | ( | tai_hook_ref_t * | p_hook, |
const char * | module, | ||
uint32_t | library_nid, | ||
uint32_t | func_nid, | ||
const void * | hook_func | ||
) |
Helper function for taiHookFunctionExportForUser.
You can use the macro TAI_MAIN_MODULE
for module
to specify the main module. This is usually the module that is loaded first and is usually the eboot.bin. This will only work if there is only one module loaded in the main memory space. Not all processes have this property! Make sure you check the return value.
[out] | p_hook | A reference that can be used by the hook function |
[in] | module | Name of the target module or TAI_MAIN_MODULE . |
[in] | library_nid | Optional. NID of the target library. |
[in] | func_nid | The function NID. If library_nid is TAI_ANY_LIBRARY , then the first export with the NID will be hooked. |
[in] | hook_func | The hook function |
SceUID taiHookFunctionExportForKernel | ( | SceUID | pid, |
tai_hook_ref_t * | p_hook, | ||
const char * | module, | ||
uint32_t | library_nid, | ||
uint32_t | func_nid, | ||
const void * | hook_func | ||
) |
Add a hook to a module function export.
If target is the kernel, use KERNEL_PID as pid
. Since a module can have two libraries that export the same NID, you can optionally pass in the library NID of the one to hook. Otherwise, use TAI_ANY_LIBRARY
and the first one found will be used.
[in] | pid | The pid of the target |
[out] | p_hook | A reference that can be used by the hook function |
[in] | module | Name of the target module. |
[in] | library_nid | Optional. NID of the target library. |
[in] | func_nid | The function NID. If library_nid is TAI_ANY_LIBRARY , then the first export with the NID will be hooked. |
[in] | hook_func | The hook function (must be in the target address space) |
pid
is kernel and address is in shared memory regionmodule
is TAI_MAIN_MODULE
and pid
is kernel SceUID taiHookFunctionExportForUser | ( | tai_hook_ref_t * | p_hook, |
tai_hook_args_t * | args | ||
) |
Add a hook to a module function export for the calling process.
[out] | p_hook | A reference that can be used by the hook function |
[in] | args | Call arguments |
TAI_MAIN_MODULE
is specified and there are multiple main modules Definition at line 44 of file taihen-user.c.
HELPER SceUID taiHookFunctionImport | ( | tai_hook_ref_t * | p_hook, |
const char * | module, | ||
uint32_t | import_library_nid, | ||
uint32_t | import_func_nid, | ||
const void * | hook_func | ||
) |
Helper function for taiHookFunctionImportForUser.
You can use the macro TAI_MAIN_MODULE
for module
to specify the main module. This is usually the module that is loaded first and is usually the eboot.bin. This will only work if there is only one module loaded in the main memory space. Not all processes have this property! Make sure you check the return value.
[out] | p_hook | A reference that can be used by the hook function |
[in] | module | Name of the target module or TAI_MAIN_MODULE . |
[in] | import_library_nid | The imported library from the target module |
[in] | import_func_nid | The function NID of the import |
[in] | hook_func | The hook function |
SceUID taiHookFunctionImportForKernel | ( | SceUID | pid, |
tai_hook_ref_t * | p_hook, | ||
const char * | module, | ||
uint32_t | import_library_nid, | ||
uint32_t | import_func_nid, | ||
const void * | hook_func | ||
) |
Add a hook to a module function import.
If target is the kernel, use KERNEL_PID as pid
. This will let you hook calls from one module to another without having to hook all calls to that module.
[in] | pid | The pid of the target |
[out] | p_hook | A reference that can be used by the hook function |
[in] | module | Name of the target module. |
[in] | import_library_nid | The imported library from the target module |
[in] | import_func_nid | The function NID of the import |
[in] | hook_func | The hook function (must be in the target address space) |
pid
is kernel and address is in shared memory regionsceKernelLoadStartModule
, sceSysmoduleLoadModule
or whatever the application uses to start the imported module and add this hook after the module is loaded. Be sure to also hook module unloading to remove the hook BEFORE the imported module is unloaded!module
is TAI_MAIN_MODULE
and pid
is kernel SceUID taiHookFunctionImportForUser | ( | tai_hook_ref_t * | p_hook, |
tai_hook_args_t * | args | ||
) |
Add a hook to a module function import for the calling process.
[out] | p_hook | A reference that can be used by the hook function |
[in] | args | Call arguments |
sceKernelLoadStartModule
, sceSysmoduleLoadModule
or whatever the application uses to start the imported module and add this hook after the module is loaded. Be sure to also hook module unloading to remove the hook BEFORE the imported module is unloaded!TAI_MAIN_MODULE
is specified and there are multiple main modules Definition at line 105 of file taihen-user.c.
HELPER SceUID taiHookFunctionOffset | ( | tai_hook_ref_t * | p_hook, |
SceUID | modid, | ||
int | segidx, | ||
uint32_t | offset, | ||
int | thumb, | ||
const void * | hook_func | ||
) |
Helper function for taiHookFunctionOffsetForUser.
[out] | p_hook | A reference that can be used by the hook function |
[in] | modid | The module UID from taiGetModuleInfo |
[in] | segidx | The ELF segment index containing the function to patch |
[in] | offset | The offset from the start of the segment |
[in] | thumb | Set to 1 if this is a Thumb function |
[in] | hook_func | The hook function (must be in the target address space) |
SceUID taiHookFunctionOffsetForKernel | ( | SceUID | pid, |
tai_hook_ref_t * | p_hook, | ||
SceUID | modid, | ||
int | segidx, | ||
uint32_t | offset, | ||
int | thumb, | ||
const void * | hook_func | ||
) |
Add a hook to a module manually with an offset.
If target is the kernel, use KERNEL_PID as pid
. The caller is responsible for checking that the module is of the correct version!
[in] | pid | The pid of the target |
[out] | p_hook | A reference that can be used by the hook function |
[in] | modid | The module UID from taiGetModuleInfoForKernel |
[in] | segidx | The ELF segment index containing the function to patch |
[in] | offset | The offset from the start of the segment |
[in] | thumb | Set to 1 if this is a Thumb function |
[in] | hook_func | The hook function (must be in the target address space) |
pid
is kernel and address is in shared memory region SceUID taiHookFunctionOffsetForUser | ( | tai_hook_ref_t * | p_hook, |
tai_offset_args_t * | args | ||
) |
Add a hook to a module manually with an offset for the calling process.
[out] | p_hook | A reference that can be used by the hook function |
[in] | args | Call arguments |
Definition at line 155 of file taihen-user.c.
int taiHookRelease | ( | SceUID | tai_uid, |
tai_hook_ref_t | hook | ||
) |
Release a hook for the calling process.
[in] | tai_uid | The tai patch reference to free |
[in] | hook | The hook to free |
Definition at line 246 of file taihen-user.c.
int taiHookReleaseForKernel | ( | SceUID | tai_uid, |
tai_hook_ref_t | hook | ||
) |