The main thread has called environment checks and prevented the game from crashing

      Let me tell you two situations first, maybe these situations have been encountered by you.


  Case 1, reverse the software, debug the game and find a certain CALL, we write a DLL, write the call into the DLL, and then inject the DLL into the software, call the CALL, and the game directly crashes and reports an error.


  Or directly use the code injector to write inline assembly and directly inject the code to cause a crash. (Sometimes there is no problem with the code injector, because it is the way that the process is anchored is better than the way that the non-main thread calls in the DLL)


  Case 2, write a DLL with a single function or a series of functions, and test the later functions Correct, the code is correct, but it always crashes for no reason when running for a long time.


  In fact, both cases are caused by non-main thread calling functions.


  In the first case, detect the calling environment, and the non-main thread call will cause a crash. Of course, the premise is that your function is written correctly, and incorrectly will also cause a crash.


  The second case is that it runs for a long time, resulting in data access conflicts, and the resulting crash. Similarly, if the main thread queue is used to call, it can be completely avoided.


  So let's take a look at the code implementation of the main thread call.


  There are two functions that can implement the main thread to call


  SetWindowLong and SetWindowsHookEx The


  basic way is similar


 


  DWORD Call_Hook main thread()


  {


  HWND hGame=Call_Get window handle();


  DWORD ndThreadId=GetWindowThreadProcessId(hGame,NULL);if(ndThreadId!= 0)


  {


  g_Hook return=SetWindowsHookEx(WH_CALLWNDPROC,Call_main thread callback function,NULL,ndThreadId);}   return


  1;


  } The   function


  name is replaced by Chinese is equivalent to a function called by the main thread.   And the code also lists several examples of function CALL calls   LRESULT CALLBACK Call_ main thread callback function (int nCode, WPARAM wParam, LPARAM lparam){   CWPSTRUCT *lpArg=(CWPSTRUCT*)lparam;//structure hwnd message wParam lParamif ( nCode==HC_ACTION)//Message of our own process   {   if (lpArg->hwnd==Call_Get window handle()&&lpArg->message==g_My message ID)//Our own message {   switch (lpArg->wParam )   {   T packet parameter * packet;   T pathfinding parameter *pathfinding;   T coordinate folder parameter * coordinate folder parameter;   T coordinate folder coordinate folder;   T walking parameter *walking;   case ID_send plaintext packet:















































  Call_output debugging information ("YYC3D main thread calls plaintext packet\r\n");packet=(Tpacket parameters*)lpArg->lParam;


  Call_cleartext packet (packet->nd packet length, packet->p) ;


  return 1;


  break;


  case ID_pathfinding:


  Call_output debugging information ("YYC3D main thread calls pathfinding\r\n");pathfinding=(Tpathfinding parameters*)lpArg->lParam;


  Call_finding path(pathfinding->nfX,pathfinding->nfY);


  return 1;


  break;


  case ID_button:


  Call_output debugging information("YYC3D main thread call button Call\r\n");Call_button(( DWORD)lpArg->lParam);


  return 1;


  break;


  case ID_control click:


  Call_output debugging information("YYC3D main thread call control click Call\r\n");Call_control click((DWORD)lpArg- >lParam);


  return 1;


  break;


  case ID_control selection:


  Call_output debugging information("YYC3D main thread call control selection Call\r\n");Call_control selection((DWORD)lpArg-> lParam);


  return 1;


  break;


  case ID_calculated coordinate folder:


  Call_output debugging information ("YYC3D main thread calls calculation coordinate folder\r\n"); coordinate folder parameter=(T coordinate folder parameter*)lpArg->lParam;


  coordinate folder=Call _Calculate the coordinate folder (the coordinate folder parameter->nfX, the coordinate folder parameter->nfY);return 1;


  break;


  case ID_walking:


  Call_output debugging information("YYC3D main thread calls walking Call\r\n"); walk=(Twalk parameter*)lpArg->lParam;


  Call_walk(walk->nfX,walk->nfY);


  return 1;


  break;


  }


  }


  }


  return CallNextHookEx(g_Hook return,nCode,wParam,lparam);}


  Then when you need to call any function, you


  can directly send a message


  , so that the code will not crash for a long time due to data access conflict.


  For example


  void Msg_walk(FLOAT X,FLOAT Y)


  { Twalk


  parameter walk;


  walk.nfX=X;


  walk.nfY=Y;


  ::SendMessageA(Call_GetWindowHandle(),g_MyMessageID,ID_walk,(LPARAM)&walk);


Original: http://mp.weixin.qq.com/s/2sWnc24S3QP2mQ11hm-lA

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325933062&siteId=291194637