void LabelCacheLoad(JSON Root) { EXCLUSIVE_ACQUIRE(LockLabels); // Inline lambda to parse each JSON entry auto AddLabels = [](const JSON Object, bool Manual) { size_t i; JSON value; json_array_foreach(Object, i, value) { LABELSINFO labelInfo; memset(&labelInfo, 0, sizeof(LABELSINFO)); // Module const char* mod = json_string_value(json_object_get(value, "module")); if(mod && strlen(mod) < MAX_MODULE_SIZE) strcpy_s(labelInfo.mod, mod); else labelInfo.mod[0] = '\0'; // Address/Manual labelInfo.addr = (uint)json_hex_value(json_object_get(value, "address")); labelInfo.manual = Manual; // Text string const char* text = json_string_value(json_object_get(value, "text")); if(text) strcpy_s(labelInfo.text, text); else { // Skip empty strings continue; } // Go through the string replacing '&' with spaces for(char* ptr = labelInfo.text; ptr[0] != '\0'; ptr++) { if(ptr[0] == '&') ptr[0] = ' '; } // Finally insert the data const uint key = ModHashFromName(labelInfo.mod) + labelInfo.addr; labels.insert(std::make_pair(key, labelInfo)); } };
void CommentCacheLoad(JSON Root) { EXCLUSIVE_ACQUIRE(LockComments); // Inline lambda to parse each JSON entry auto AddComments = [](const JSON Object, bool Manual) { size_t i; JSON value; json_array_foreach(Object, i, value) { COMMENTSINFO commentInfo; memset(&commentInfo, 0, sizeof(COMMENTSINFO)); // Module const char* mod = json_string_value(json_object_get(value, "module")); if(mod && strlen(mod) < MAX_MODULE_SIZE) strcpy_s(commentInfo.mod, mod); else commentInfo.mod[0] = '\0'; // Address/Manual commentInfo.addr = (uint)json_hex_value(json_object_get(value, "address")); commentInfo.manual = Manual; // String value const char* text = json_string_value(json_object_get(value, "text")); if(text) strcpy_s(commentInfo.text, text); else { // Skip blank comments continue; } const uint key = ModHashFromName(commentInfo.mod) + commentInfo.addr; comments.insert(std::make_pair(key, commentInfo)); } };
void FunctionCacheLoad(JSON Root) { EXCLUSIVE_ACQUIRE(LockFunctions); // Delete existing entries functions.clear(); // Inline lambda to enumerate all JSON array indices auto InsertFunctions = [](const JSON Object, bool Manual) { size_t i; JSON value; json_array_foreach(Object, i, value) { FUNCTIONSINFO functionInfo; memset(&functionInfo, 0, sizeof(FUNCTIONSINFO)); // Copy module name const char* mod = json_string_value(json_object_get(value, "module")); if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE) strcpy_s(functionInfo.mod, mod); // Function address functionInfo.start = (uint)json_hex_value(json_object_get(value, "start")); functionInfo.end = (uint)json_hex_value(json_object_get(value, "end")); functionInfo.manual = Manual; // Sanity check if(functionInfo.end < functionInfo.start) continue; const uint key = ModHashFromName(functionInfo.mod); functions.insert(std::make_pair(ModuleRange(key, Range(functionInfo.start, functionInfo.end)), functionInfo)); } };
void LoopCacheLoad(JSON Root) { EXCLUSIVE_ACQUIRE(LockLoops); // Inline lambda to parse each JSON entry auto AddLoops = [](const JSON Object, bool Manual) { size_t i; JSON value; json_array_foreach(Object, i, value) { LOOPSINFO loopInfo; memset(&loopInfo, 0, sizeof(LOOPSINFO)); // Module name const char* mod = json_string_value(json_object_get(value, "module")); if(mod && strlen(mod) < MAX_MODULE_SIZE) strcpy_s(loopInfo.mod, mod); // All other variables loopInfo.start = (duint)json_hex_value(json_object_get(value, "start")); loopInfo.end = (duint)json_hex_value(json_object_get(value, "end")); loopInfo.depth = (int)json_integer_value(json_object_get(value, "depth")); loopInfo.parent = (duint)json_hex_value(json_object_get(value, "parent")); loopInfo.manual = Manual; // Sanity check: Make sure the loop starts before it ends if(loopInfo.end < loopInfo.start) continue; // Insert into global list loops.insert(std::make_pair(DepthModuleRange(loopInfo.depth, ModuleRange(ModHashFromName(loopInfo.mod), Range(loopInfo.start, loopInfo.end))), loopInfo)); } };
ModuleRange makeKey(const ARGUMENTSINFO & value) const override { return ModuleRange(ModHashFromName(value.mod), Range(value.start, value.end)); }
bool ModLoad(uint Base, uint Size, const char* FullPath) { // // Handle a new module being loaded // // TODO: Do loaded modules always require a path? if(!Base || !Size || !FullPath) return false; MODINFO info; // Copy the module path in the struct strcpy_s(info.path, FullPath); // Break the module path into a directory and file name char dir[MAX_PATH] = ""; char file[MAX_MODULE_SIZE] = ""; strcpy_s(dir, FullPath); _strlwr(dir); char* fileStart = strrchr(dir, '\\'); if(fileStart) { strcpy_s(file, fileStart + 1); *fileStart = '\0'; } //calculate module hash from full file name info.hash = ModHashFromName(file); // Copy the extension into the module struct { char* extensionPos = strrchr(file, '.'); if(extensionPos) { strcpy_s(info.extension, extensionPos); extensionPos[0] = '\0'; } } // Copy the name to the module struct strcpy_s(info.name, file); // Module base address/size info.base = Base; info.size = Size; // Process module sections info.sections.clear(); WString wszFullPath = StringUtils::Utf8ToUtf16(FullPath); if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &info.Handle, &info.FileMapSize, &info.MapHandle, &info.FileMapVA)) { // Get the entry point info.entry = GetPE32DataFromMappedFile(info.FileMapVA, 0, UE_OEP) + info.base; // Enumerate all PE sections int sectionCount = (int)GetPE32DataFromMappedFile(info.FileMapVA, 0, UE_SECTIONNUMBER); for(int i = 0; i < sectionCount; i++) { MODSECTIONINFO curSection; curSection.addr = GetPE32DataFromMappedFile(info.FileMapVA, i, UE_SECTIONVIRTUALOFFSET) + info.base; curSection.size = GetPE32DataFromMappedFile(info.FileMapVA, i, UE_SECTIONVIRTUALSIZE); const char* sectionName = (const char*)GetPE32DataFromMappedFile(info.FileMapVA, i, UE_SECTIONNAME); // Escape section name when needed strcpy_s(curSection.name, StringUtils::Escape(sectionName).c_str()); // Add entry to the vector info.sections.push_back(curSection); } } // Add module to list EXCLUSIVE_ACQUIRE(LockModules); modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), info)); EXCLUSIVE_RELEASE(); SymUpdateModuleList(); return true; }