PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/gm_cvar3/gm_cvar3/sigscan.cpp

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