sourcemod icon indicating copy to clipboard operation
sourcemod copied to clipboard

DETOUR_DECL_STATIC6 recvfrom crash on linux

Open xiluotop opened this issue 2 years ago • 1 comments

Help us help you

  • [x] I have checked that my issue doesn't exist yet.
  • [x] I have tried my absolute best to reduce the problem-space and have provided the absolute smallest test-case possible.
  • [x] I can always reproduce the issue with the provided description below.

Environment

  • Operating System version: Affected: Ubuntu 18.04.5 LTS/4.15.0-204-generic (x86_64) Test comparison: Microsoft Windows Server 2012 Standard

  • Game (with version if applicable): Left4Dead2 v2.2.2.6

  • Current SourceMod version: 1.11.0.6931

  • Current SourceMod snapshot: 1.12.0.6982

  • Current Metamod: Source snapshot: 1.12.0-dev+1167

  • [x] I have updated SourceMod to the latest version and it still happens.

  • [x] I have updated SourceMod to the latest snapshot and it still happens.

  • [x] I have updated SourceMM to the latest snapshot and it still happens.

Description

I used g_pVCR->Hook_recvfrom on windos to prevent dos query attacks, but the hook didn't work on linux. I tried using detours to hook recvfrom on linux, but it crashed at once. I did some output prompts and found that I was able to hook recvfrom the message I received, but when I called the original method, it crashed. I looked at the files for asm and detours and I don't understand how it works and how to fix the problem.So hopefully the bigwigs can offer some help or fix this problem.

Problematic Code (or Steps to Reproduce)

When the hook is started, you will receive information, but then a call to DETOUR_STATIC_CALL(Detour_RecvFrom) will crash.

typedef void* gpointer;
DETOUR_DECL_STATIC6(Detour_RecvFrom, int, int, socket, char *, buffer, int, length, int, flags, sockaddr *, address, socklen_t *, address_len)
{
      printf("receive:socket->%d,buffer->%s,length->%d,flags->%d,sockaddr->%p,socklen_t->%p\n",socket, buffer, length, flags, address, address_len);
      int ret = DETOUR_STATIC_CALL(Detour_RecvFrom)(socket, buffer, length, flags, address, address_len); // this call will crash
      ...
      return ret;
}

CDetour *g_RecvFromDetour = nullptr;
#if SH_SYS != SH_SYS_WIN32
      CDetourManager::Init(g_pSM->GetScriptingEngine(), nullptr);
      printf((gpointer)recvfrom->%p\n",(gpointer)recvfrom);
      g_RecvFromDetour = DETOUR_CREATE_STATIC_PTR(Detour_RecvFrom, (gpointer)recvfrom);
      g_RecvFromDetour->EnableDetour();
#else
   ...

I have Accelerator report IGKU-QC7Y-HZZU and the view raw:

IGKU-QC7Y-HZZU(stack).txt IGKU-QC7Y-HZZU(memory).txt IGKU-QC7Y-HZZU(raw).txt

Thank you again to those who contribute to the community. Your work deserves everyone's admiration.

xiluotop avatar Apr 18 '23 15:04 xiluotop

Old code and will not work, it takes a pointer to CSteamSocketMgr g_SteamSocketMgr from function NET_InitiateSteamConnection, but there is no such code in l4d2 and a pointer in this function. ~~Also, if you are hooking function CSteamSocketMgr::recvfrom, you must use the DETOUR_CREATE_MEMBER and DETOUR_DECL_MEMBER6 and DETOUR_MEMBER_CALL macros, because this function is inside the class.~~ Now I noticed that Linux uses the hook of another function recvfrom, which is inside function CSteamSocketMgr::recvfrom, the code looks for it using the global symbol recvfrom, and judging by the source code, the type of calling conventions there is not cdecl, it is specified as stdcall

A1mDev avatar Aug 03 '23 07:08 A1mDev