Task可以注册Hook,RTP也可以,只需在VIP中包含组件INCLUDE_RTP_HOOKS。每种Hook可以注册的数量为RTP_HOOK_TBL_SIZ
先看第一对Hook
代码语言:javascript复制typedef STATUS (*RTP_PRE_CREATE_HOOK)
(
const char *rtpFileName, /* Null-terminated path to executable */
const char *argv[], /* pointer to NULL terminated argv array */
const char *envp[], /* pointer to NULL terminated envp array */
int priority, /* priority of initial task */
size_t uStackSize, /* User space stack size for intial task */
int options, /* the options passed to RTP */
int taskOptions /* Task options for RTP's initial task */
);
STATUS rtpPreCreateHookAdd
(
RTP_PRE_CREATE_HOOK hook,
BOOL addToHead
);
STATUS rtpPreCreateHookDelete
(
RTP_PRE_CREATE_HOOK hook
);
rtpPreCreateHookAdd() 添加的Hook是在创建RTP之前调用。如果Hook的返回值不是OK,后续的RTP就不会被创建了。这种Hook可以用于RTP创建之前的验证。
参数<addToHead>用于指定同类Hook的调用顺序。如果使用FALSE,则将Hook加入列表尾部。如果使用TRUE,则加到列表头部,那么它就会被优先调用。
写个简单的RTP例子,例如main()直接返回,将编译的vxe文件复制两份
注册以下Hook
代码语言:javascript复制#include <private/rtpLibP.h>
#if 0
/* options */
#define RTP_GLOBAL_SYMBOLS 0x01 /* register global symbols for RTP */
#define RTP_LOCAL_SYMBOLS 0x02 /* idem for local symbols */
#define RTP_ALL_SYMBOLS (RTP_GLOBAL_SYMBOLS | RTP_LOCAL_SYMBOLS)
#define RTP_DEBUG 0x10 /* set RTP in debug mode when created */
#define RTP_BUFFER_VAL_OFF 0x20 /* disable buffer validation for all system calls issued from the RTP */
#define RTP_LOADED_WAIT 0x40 /* Wait until the RTP is loaded */
#define RTP_CPU_AFFINITY_NONE 0x80 /* Remove any CPU affinity (SMP) */
#endif
#if 0
/* taskOptions */
#define VX_PRIVATE_ENV 0x00000080 /* private environment variables */
#define VX_NO_STACK_FILL 0x00000100 /* avoid stack fill of 0xee */
#define VX_TASK_NOACTIVATE 0x00002000 /* taskOpen() does not taskActivate() */
#define VX_NO_STACK_PROTECT 0x00004000 /* no over/underflow stack protection,*/
#define VX_COPROC1_TASK 0x01000000
#define VX_COPROC2_TASK 0x02000000
/* i86 */
#define VX_FP_TASK VX_COPROC1_TASK
#endif
static STATUS rtpPreHook
(
const char *rtpFileName,
const char *argv[],
const char *envp[],
int priority,
size_t uStackSize,
int options,
int taskOptions
)
{
int i;
if(strcmp("test.vxe", rtpFileName))
{
printf("%s should be loaded latern", rtpFileName);
return ERROR;
}
if(argv != NULL)
{
i = -1;
while(argv[ i] != NULL)
{
printf("argv[%d] = %sn", i, argv[i]);
}
}
if(envp != NULL)
{
i = -1;
while(envp[ i] != NULL)
{
printf("envp[%d]: %sn", i, envp[i]);
}
}
printf("priority of main is %dn", priority);
printf("stack size of main is %#xn", uStackSize);
printf("options of RTP is %#xn", options);
printf("options of main is %#xn", taskOptions);
return OK;
}
void testRtpHook()
{
rtpPreCreateHookAdd(rtpPreHook, FALSE);
}
看看执行效果
第二对Hook
代码语言:javascript复制typedef STATUS (*RTP_POST_CREATE_HOOK)
(
const RTP_ID rtpId
);
STATUS rtpPostCreateHookAdd
(
RTP_POST_CREATE_HOOK hook,
BOOL addToHead
);
STATUS rtpPostCreateHookDelete
(
RTP_POST_CREATE_HOOK hook
);
rtpPostCreateHookAdd()添加的Hook是在RTP及其主任务已创建但未执行时调用。例如RTP A正在创建RTP B,这种Hook是在RTP A的上下文里执行。Hook创建的对象,属于RTP A。如果要改变对象的隶属关系,可以调用objOwnerSet():
objOwnerSet(createdObjId, rtpId)
这种Hook也是在rtpSpawn()里调用。如果返回值不是OK,已创建的RTP及其主任务都会被删除,然后rtpSpawn()返回ERROR。这种Hook可用于附加的资源分配。
参考上文的例子
代码语言:javascript复制
#include <private/rtpLibP.h>
static STATUS rtpPostHook
(
const RTP_ID rtpId
)
{
int i;
WIND_TCB *pTcb;
if(strcmp("test.vxe", rtpId->pPathName))
{
printf("%s should be loaded latern", rtpId->pPathName);
return ERROR;
}
if(rtpId->pArgv != NULL)
{
i = -1;
while(rtpId->pArgv[ i] != NULL)
{
printf("argv[%d] = %sn", i, rtpId->pArgv[i]);
}
}
if(rtpId->pEnv != NULL)
{
i = -1;
while(rtpId->pEnv[ i] != NULL)
{
printf("envp[%d]: %sn", i, rtpId->pEnv[i]);
}
}
pTcb = taskTcb(rtpId->initTaskId);
printf("priority of main is %dn", pTcb->priority);
printf("stack size of main is %#xn", pTcb->pStackBase-pTcb->pStackEnd);
printf("options of RTP is %#xn", rtpId->options);
printf("options of main is %#xn", pTcb->options);
return OK;
}
void testRtpHook()
{
rtpPostCreateHookAdd(rtpPostHook, FALSE);
}
第三对Hook
代码语言:javascript复制typedef void (*RTP_INIT_COMPLETE_HOOK)
(
const RTP_ID rtpId
);
STATUS rtpInitCompleteHookAdd
(
RTP_INIT_COMPLETE_HOOK hook,
BOOL addToHead
);
STATUS rtpInitCompleteHookDelete
(
RTP_INIT_COMPLETE_HOOK hook
);
rtpInitCompleteHookAdd()添加的Hook是在创建的RTP完全初始化之后调用 (其主任务执行之前)。这种Hook可用于通知Debugger或其它想访问新建RTP内存空间的工具。因此,它不应该再创建任何对象或执行对RTP有影响的操作。
最后一对
代码语言:javascript复制typedef void (*RTP_DELETE_HOOK)
(
const RTP_ID rtpId
const int exitCode
);
STATUS rtpDeleteHookAdd
(
RTP_DELETE_HOOK hook,
BOOL addToHead
);
STATUS rtpDeleteHookDelete
(
RTP_DELETE_HOOK hook
);
rtpDeleteHookAdd()添加的Hook在rtpDelete()删除RTP时调用。而且,这个时候,RTP内部的Task都已经被删除了
有个地方儿要注意:多个Hook之间可能有依赖关系。例如,某个Delete Hook使用的机制可能被其它Hook删除。因此,Hook的调用顺序就很重要。通常,Create Hook按照添加顺序来调用,Delete Hook的调用顺序则相反。即,Create Hook在注册时,参数 <addToHead> 使用FALSE;Delete Hook的,则使用TRUE。
这正是
RTP,多Hook, 可调试,可监测;
自己动手才解惑,多多练习更灵活