lpCriticalSection
对关键节对象的指针。先前必须已将该对象初始化与InitializeCriticalSection函数中。返回值
此函数不返回值[1]备注
删除关键节对象释放由该对象使用的所有系统资源。
关键节之后,对象已被删除,未引用的对象的任何功能,在关键节 (如EnterCriticalSection、TryEnterCriticalSection、 和LeaveCriticalSection) 上运行非InitializeCriticalSection和InitializeCriticalSectionAndSpinCount。如果您尝试这样做,可能会出现内存损坏和其他意外的错误。
如果它仍拥有删除关键节,则已删除的关键节的所有权在等待的线程的状态未定义。___________________________________
这是一个InlineAPIHook的场景,有多个线程
线程1,这是我Hook的函数(执行非常频繁)
MySysCall(...)
{
EnterCriticalSection()
...
LeaveCriticalSection()
}
线程2,这是卸载Hook,还原SysCall的线程
![DeleteCriticalSection() critical section](http://img.aihuau.com/images/31101031/31050034t010c0239f4fb02ca84.gif)
UnHook()
{
EnterCriticalSection()
//保证MySysCall函数执行到EnterCriticalSection处
Sleep(50);
...
//还原syscall的入口5个字节
//删除MySysCall中自己创建的资源
LeaveCriticalSection()
DeleteCriticalSection
}
请问我怎么保证我执行UnHook的时候MySysCall执行到EnterCriticalSection()时就跳出来呢?
-----------------------------------------------------------
UnHook的时候本来就是MySysCall执行不了呀,会等在EnterCriticalSection(),有什么问题?
UnHook的时候你
LeaveCriticalSection()
DeleteCriticalSection,立马就删除了,MySysCall线程在这LeaveCriticalSection与DeleteCriticalSection两句之间是抢不到cpu片的。
__________________________________________
是这样的,但是MySysCall在UnHook线程DeleteCriticalSection之后,进入EnterCriticalSection这里会出错,因为这个参数已经是NULL了,另外,即使这里不错的话,那么这个线程在之后会是什么样的流程呢?谢谢。
__________________________________
像这种多线程,用到临界区变量来做同步,最好都是先保证所有线程退出然后再释放临界区变量
___________________________________
我不释放是可以,但是执行完UnHook函数之后我的DLL会free掉,这时候MySysCall所在的代码区就成了未知地址了,EnterCriticalSection进去执行肯定错。所以我必须保证UnHook之后MySysCall就不应该在执行,跳回到系统自己的代码领域。不知道怎么操作,我快疯了!。
__________________________________
用事件结合的方式:
HANDLEhandle=NULL;
MySysCall(...)
{
if(handle!=NULL)
WaitForSingleObject(handle,...);
EnterCriticalSection()
...
LeaveCriticalSection()
}
UnHook()
{
handle=CreateEvent(...);
EnterCriticalSection()
//保证MySysCall函数执行到EnterCriticalSection处
Sleep(50);
m_bRunning=False;
...
//还原syscall的入口5个字节
//删除MySysCall中自己创建的资源
LeaveCriticalSection()
DeleteCriticalSection
}
__________________________________
是的,我已经这样做了。不过还是有点虚...
我是这样的:
HANDLEhCanDelCS=NULL;
HANDLEhCanFreeDll=NULL;
BOOLbUnHooking=FALSE;
MySysCall(...)
{
EnterCriticalSection()
if(bUnHooking)
{
SetEvent(hCanDelCS);
returncode=SysCall(...);
SetEvent(hCanFreeDLL);
returnreturncode;
}
...
LeaveCriticalSection()
}
线程2,这是卸载Hook,还原SysCall的线程
UnHook()
{
bUnHooking=TRUE;
EnterCriticalSection()
...
//还原syscall的入口5个字节
//删除MySysCall中自己创建的资源
if(hCanDelCS)
watforsingleobject(hCanDelCS,500);
LeaveCriticalSection()
DeleteCriticalSection
if(hCanFreeDll)
watforsingleobject(hCanDelCS,500);
sleep(50);
returntodllmain();//freedll
}
_______________________
mysyscall中会卡在EnterCriticalSection那里,等UnhookLeaveXx之后会继续执行mysyscall,这时候mysyscall代码已经失效了。
______________________________