PageRenderTime 71ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/utils/sourcelua/sigscan.cpp

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