PageRenderTime 3068ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/Resources/NetHook2/NetHook2/sigscan.cpp

https://bitbucket.org/VoiDeD/steamre/
C++ | 124 lines | 78 code | 35 blank | 11 comment | 21 complexity | 0a51ca5695690fff05da10fab08bffd6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. #include "sigscan.h"
  2. /* There is no ANSI ustrncpy */
  3. unsigned char* ustrncpy(unsigned char *dest, const unsigned char *src, int len) {
  4. while(len--)
  5. dest[len] = src[len];
  6. return dest;
  7. }
  8. /* //////////////////////////////////////
  9. CSigScan Class
  10. ////////////////////////////////////// */
  11. unsigned char* CSigScan::base_addr;
  12. size_t CSigScan::base_len;
  13. void *(*CSigScan::sigscan_dllfunc)(const char *pName, int *pReturnCode);
  14. /* Initialize the Signature Object */
  15. int CSigScan::Init(unsigned char *sig, char *mask, size_t len) {
  16. is_set = 0;
  17. sig_len = len;
  18. if ( sig_str )
  19. delete[] sig_str;
  20. sig_str = new unsigned char[sig_len];
  21. ustrncpy(sig_str, sig, sig_len);
  22. if ( sig_mask )
  23. delete[] sig_mask;
  24. sig_mask = new char[sig_len/*+1*/];
  25. strncpy(sig_mask, mask, sig_len);
  26. //sig_mask[sig_len+1] = 0;
  27. if(!base_addr)
  28. return 2; // GetDllMemInfo() Failed
  29. if((sig_addr = FindSignature()) == NULL)
  30. return 1; // FindSignature() Failed
  31. is_set = 1;
  32. // SigScan Successful!
  33. return 0;
  34. }
  35. /* Destructor frees sig-string allocated memory */
  36. CSigScan::~CSigScan(void) {
  37. delete[] sig_str;
  38. delete[] sig_mask;
  39. }
  40. /* Get base address of the server module (base_addr) and get its ending offset (base_len) */
  41. bool CSigScan::GetDllMemInfo(void) {
  42. void *pAddr = (void*)sigscan_dllfunc;
  43. base_addr = 0;
  44. base_len = 0;
  45. #ifdef WIN32
  46. MEMORY_BASIC_INFORMATION mem;
  47. if(!pAddr)
  48. return false; // GetDllMemInfo failed!pAddr
  49. if(!VirtualQuery(pAddr, &mem, sizeof(mem)))
  50. return false;
  51. base_addr = (unsigned char*)mem.AllocationBase;
  52. IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)mem.AllocationBase;
  53. IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS*)((unsigned long)dos+(unsigned long)dos->e_lfanew);
  54. if(pe->Signature != IMAGE_NT_SIGNATURE) {
  55. base_addr = 0;
  56. return false; // GetDllMemInfo failedpe points to a bad location
  57. }
  58. base_len = (size_t)pe->OptionalHeader.SizeOfImage;
  59. #else
  60. Dl_info info;
  61. struct stat buf;
  62. if(!dladdr(pAddr, &info))
  63. return false;
  64. if(!info.dli_fbase || !info.dli_fname)
  65. return false;
  66. if(stat(info.dli_fname, &buf) != 0)
  67. return false;
  68. base_addr = (unsigned char*)info.dli_fbase;
  69. base_len = buf.st_size;
  70. #endif
  71. return true;
  72. }
  73. /* Scan for the signature in memory then return the starting position's address */
  74. void* CSigScan::FindSignature(void) {
  75. unsigned char *pBasePtr = base_addr;
  76. unsigned char *pEndPtr = base_addr+base_len;
  77. size_t i;
  78. while(pBasePtr < pEndPtr) {
  79. for(i = 0;i < sig_len;i++) {
  80. if((sig_mask[i] != '?') && (sig_str[i] != pBasePtr[i]))
  81. break;
  82. }
  83. // If 'i' reached the end, we know we have a match!
  84. if(i == sig_len)
  85. return (void*)pBasePtr;
  86. pBasePtr++;
  87. }
  88. return NULL;
  89. }