MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Класс type_info"
Answer 1003779
По моим тестам, в Visual C++ результат вывода
type_info.hash_code()
не меняется при внесении изменений в код функций класса (он меняется только при изменении его имени). Так что идея уже сомнительная.Хэш самого тела функции можно получить, скажем, как-то так:
#include <stdio.h> #include <stdint.h> #include <tchar.h> #include <Windows.h> #include <DbgHelp.h> #pragma comment(lib, "Dbghelp.lib") struct Function { const char* name; uint64_t addr; unsigned int size; bool success; }; BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID context) { Function* pfstruct = (Function*)context; if (strcmp(pSymInfo->Name, pfstruct->name) == 0) { pfstruct->addr = pSymInfo->Address; pfstruct->size = SymbolSize; pfstruct->success = true; return FALSE; //закончить поиск } return TRUE; //продолжить поиск } bool GetFuncBounds(const char* fname, uint64_t& addr, unsigned int& size) { bool ret; Function fstruct; fstruct.name = fname; fstruct.size = 0; fstruct.success = false; HANDLE hProcess = GetCurrentProcess(); //текущий процесс char Mask[] = "*!*"; BOOL status; status = SymInitialize(hProcess, NULL, TRUE); //загрузка символов if (status == FALSE) { printf("SymInitialize failed. Error code: 0x%x\n", (UINT)GetLastError()); return false; } //поиск символов if (SymEnumSymbols(hProcess, 0, Mask, &EnumSymProc, (void*)&fstruct)) { if (fstruct.success != false) { //возвращаем адрес и размер функции addr = fstruct.addr; size = fstruct.size; ret = true; } else { printf("Symbol [%s] not found\n", fname); ret = false; } } else { printf("SymEnumSymbols failed. Error code: 0x%x\n", (UINT)GetLastError()); ret = false; } SymCleanup(hProcess); return ret; } uint32_t GetMemHash(uint64_t addr, int size) { uint32_t hash = 1234; uint32_t k = 9870; for (int i=0; i < size; i+=sizeof(uint32_t)) { uint32_t* p = (uint32_t*)((char*)addr + i); hash = hash * k + (*p); } hash += size; return hash; } //********************************** void Func() { printf("Hello, World!\n"); } int _tmain(int argc, _TCHAR* argv[]) { uint64_t addr = 0; unsigned int size = 0; UINT hash; if (GetFuncBounds("Func", addr, size)) { hash = GetMemHash(addr, size); printf("Hash: 0x%x\n", (UINT)hash); } else { printf("Cannot calculate hash!\n"); } getchar(); return 0; }
Но я не думаю, что это поможет решить задачу. Значение этого хэша в большинстве случаев будет меняться даже при простой пересборке проекта без изменений, так как компилятор каждый раз генерирует новые адреса объектов, что приводит к различиям в машинном коде.
Как же решить задачу? Если вам нужно отслеживать изменения в исходном коде, то и зайти логичнее со стороны исходного кода. Сделайте, чтобы тело всех функций, изменения в которых надо отслеживать, было вынесено в отдельный файл, подключаемый через include. Напишите программу, которая будет считать хэши от содержимого этих файлов, и записывать результат в XML-файл. Прикрутите ее к вашим инструментам сборки (например, в Visual Studio - Custom build step), и распространяйте получаемый XML-файл с хэшами функций вместе с программой, тогда вы всегда можете определить, какая функция изменилась. Для проверки, что XML-файл действительно соответствует текущему бинарнику, можно включить в него и хэш от бинарника.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.