向指定线程插入异常

    技术2022-05-18  15

    一:输入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

     


    最新回复(0)