一:输入1.HANDLE hThread 线程句柄2. void (*ThrowFun)() 异常函数指针二:将指定线程挂起来将线程挂起来来。暂停线程的目的是使线程停下来,方便向线程的栈空间插入代码。也方面调试代码。SuspendThread(hThread)三:获取线程的当前状态通过GetThreadContext获取线程的寄存器的值。主要是要获取线程栈空间的ESP指针。以便向线程栈空间插入返回地址,模拟成当前线程调用ThrowFun。四:让线程执行输入的函数指针 首先,向栈空间插入线程的当前地址。以便模拟成从该地址调用了ThrowFun con.Esp -= 4; *(int*)(con.Esp) = con.Eip; 然后,将线程的EIP指针直接设置为ThrowFun的入口。这样线程就会转到ThrowFun函数执行。五:唤醒线程因为线程在我们的SuspendThread(hThread)调用前可能已经被多次的挂起了。为了让线程被真正的被唤醒,需要多次调用ResumeThread直到线程被真正的唤醒。for(unsigned i = 0; i <= count; ++i) { ResumeThread(hThread); }六:如果线程调用了Sleep函数 但是,如果该线程已经处在Sleep调用中,除非Sleep的时间到了。否则线程不能够被唤醒的。为了避免线程Sleep很长时间,导致插入的异常代码不能被立即执行。我们可以将对Sleep的长时间调用,修改为多次对Sleep的短时间调用void my_sleep(unsigned Milliseconds){ unsigned time_out = Milliseconds; while(time_out > 0) { Sleep(80); if(time_out > 100) { time_out -= 100; } else { time_out = 0; } }}这样,线程不会一直处于Sleep状态,当被插入异常代码后就可以很快执行到。
七:如果线程调用了EnterCriticalSection函数int my_EnterCriticalSection ( CRITICAL_SECTION& m_csunsigned time1, bool IsThrowException){ unsigned time = time1; while(time > 0) { typedef BOOL (WINAPI *TryEnterCriticalSectionType)(__inout LPCRITICAL_SECTION lpCriticalSection); static TryEnterCriticalSectionType TryEnterCriticalSection= (TryEnterCriticalSectionType)::GetProcAddress(::LoadLibraryA("Kernel32.dll"), "TryEnterCriticalSection"); if(0 != TryEnterCriticalSection(&m_cs)) { return 0; } if(time > 100) { Sleep(80); time -= 100; } else { Sleep(time); time = 0; } } if(IsThrowException) { Throw(TException_LockTimeOver()); } return -1;}八:如果线程调用了WaitForSingleObject函数
int my_WaitForSingleObject (HANDLE m_lock,unsigned timeout, bool IsThrowException){ unsigned time = timeout; while(time > 0) { int len = 80; if(time < 100) { len = time - 20; }
DWORD result = ::WaitForSingleObject(m_lock, len); if(WAIT_TIMEOUT == result) { time -= (len + 20); continue; } if(WAIT_OBJECT_0 == result) { return 0; } Throw(TException()); } if(IsThrowException) { Throw(TException_LockTimeOver()); }
return -1;}九:如果线程调用socket的recv函数void recv(SOCKET m_socket,int len1){ int size = len1; char buf[1024]; while(size > 0) { int len = size; if(len < sizeof(buf)-1) { len = sizeof(buf) -1; } fd_set lst; FD_ZERO(&lst); FD_SET(m_socket, &lst); timeval over_time; over_time.tv_sec = 0; over_time.tv_usec = 100; int select_result = ::select( 1, &lst, 0, 0, &over_time ); if(select_result > 0) { size -= ::recv(m_socket, buf, len, 0); } }}十:如果线程调用socket的send函数十一:如果线程调用socket的accept函数
http://download.csdn.net/source/3120625