memscan.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "memscan.h"
  2. uintptr_t FindPattern(uintptr_t start, uintptr_t end, const char* pattern, size_t length) {
  3. uintptr_t ptr = start;
  4. while (ptr < end - length) {
  5. bool f = true;
  6. const char* cur = reinterpret_cast<char*>(ptr);
  7. for (register size_t i = 0; i < length; i++) {
  8. if (pattern[i] != '\x2A' && pattern[i] != cur[i]) {
  9. f = false;
  10. break;
  11. }
  12. }
  13. if (f) {
  14. return ptr;
  15. }
  16. ptr++;
  17. }
  18. return 0;
  19. }
  20. #if _WINDOWS
  21. CWinLibInfo::CWinLibInfo(void* pInBase) {
  22. MEMORY_BASIC_INFORMATION info;
  23. if (!VirtualQuery(pInBase, &info, sizeof(MEMORY_BASIC_INFORMATION))) {
  24. this->m_bValid = false;
  25. return;
  26. }
  27. uintptr_t base = reinterpret_cast<uintptr_t>(info.AllocationBase);
  28. IMAGE_DOS_HEADER *dos = reinterpret_cast<IMAGE_DOS_HEADER *>(base);
  29. IMAGE_NT_HEADERS *pe = reinterpret_cast<IMAGE_NT_HEADERS *>(base + dos->e_lfanew);
  30. IMAGE_OPTIONAL_HEADER *opt = &pe->OptionalHeader;
  31. size_t size = opt->SizeOfImage;
  32. this->m_StartRange = reinterpret_cast<uintptr_t>(info.AllocationBase);
  33. this->m_EndRange = this->m_StartRange + size;
  34. this->m_bValid = true;
  35. }
  36. bool CWinLibInfo::LocateSymbol(const char* name, void** result) {
  37. return false;
  38. }
  39. bool CWinLibInfo::LocatePattern(const char* bytes, size_t length, void** result) {
  40. if (!this->m_bValid) {
  41. return false;
  42. }
  43. uintptr_t pResult = FindPattern(this->m_StartRange, this->m_EndRange, bytes, length);
  44. if (pResult) {
  45. *result = reinterpret_cast<void*>(pResult);
  46. return true;
  47. }
  48. return false;
  49. }
  50. #elif _LINUX
  51. CLinuxLibInfo::CLinuxLibInfo(void* pInBase) {
  52. if (!dladdr(pInBase, &this->m_info)) {
  53. this->m_bValid = false;
  54. return;
  55. }
  56. elf_version(EV_CURRENT);
  57. this->m_fd = open(m_info.dli_fname, O_RDONLY);
  58. this->m_Elf = elf_begin(this->m_fd, ELF_C_READ, NULL);
  59. this->m_bValid = true;
  60. }
  61. bool CLinuxLibInfo::LocatePattern(const char* bytes, size_t length, void** result) {
  62. return false;
  63. }
  64. bool CLinuxLibInfo::LocateSymbol(const char* name, void** result) {
  65. if (!this->m_bValid) {
  66. return false;
  67. }
  68. Elf_Scn *scn = NULL;
  69. GElf_Shdr shdr;
  70. while ((scn = elf_nextscn(this->m_Elf, scn)) != NULL) {
  71. gelf_getshdr(scn, &shdr);
  72. if (shdr.sh_type == SHT_SYMTAB) {
  73. break;
  74. }
  75. }
  76. Elf_Data *data = elf_getdata(scn, NULL);
  77. size_t count = shdr.sh_size / shdr.sh_entsize;
  78. // iterate symbols
  79. for (size_t i = 0; i < count; ++i) {
  80. GElf_Sym sym;
  81. gelf_getsym(data, i, &sym);
  82. const char *symname = elf_strptr(this->m_Elf, shdr.sh_link, sym.st_name);
  83. if (symname && !strcmp(symname, name)) {
  84. *result = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(m_info.dli_fbase) + sym.st_value);
  85. return true;
  86. }
  87. }
  88. return false;
  89. }
  90. CLinuxLibInfo::~CLinuxLibInfo() {
  91. elf_end(this->m_Elf);
  92. close(this->m_fd);
  93. }
  94. #endif