diff --git a/include/subcommand_record.h b/include/subcommand_record.h index dfdc2581660061ad033e04f95b104625e0b03930..8c1ad7cd16d9312829b4a5a71a8dfca50d0aeedc 100644 --- a/include/subcommand_record.h +++ b/include/subcommand_record.h @@ -284,6 +284,14 @@ private: std::vector excludeProcessNameArgs_ = {}; std::set excludePids_ = {}; std::set excludeTids_ = {}; + const std::unordered_set kSensitiveServices = { + "hguard.elf", + "crypto.elf", + "auditmgr.elf", + "devmgr.elf" + }; + std::unordered_set sensitivePids_; + std::unordered_map sensitiveOffsets_; void CollectExcludeThread(); void SetExcludeHiperf(); bool IsThreadExcluded(const pid_t pid, const pid_t tid); @@ -384,6 +392,8 @@ private: void UpdateDevHostMaps(PerfEventRecord& record); void UpdateDevHostCallChains(PerfEventRecord& record); void UpdateDevHostMapsAndIPs(PerfEventRecord& record); + void UpdateSensitiveMaps(PerfEventRecord& record); + void UpdateSensitiveCallChains(PerfEventRecord& record); // file format like as 0,1-3,4-6,7,8 uint32_t GetCountFromFile(const std::string &fileName); diff --git a/include/symbols_file.h b/include/symbols_file.h index 04079977fd896eb07baa60517293cb8a9229eab0..1dd073833e367080bb13581129d5ac743f57ae75 100644 --- a/include/symbols_file.h +++ b/include/symbols_file.h @@ -208,6 +208,7 @@ public: std::vector matchedSymbols_ {}; std::map symbolsMap_; static uint32_t offsetNum_; + static std::unordered_map sensitiveOffsets_; virtual DfxSymbol GetSymbolWithPcAndMap(const uint64_t pc, std::shared_ptr map) { return DfxSymbol(); @@ -219,6 +220,11 @@ public: map_ = map; } + static void SetSensitiveOffsets(const std::unordered_map& offsets) + { + sensitiveOffsets_ = offsets; + } + protected: bool symbolsLoaded_ = false; bool symbolsLoadResult_ = false; diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index e0ed4e2a31342ed482b6e83845494f198ab6bbdf..51623d9cbe49fc16477b6aedfd68a3f0351fd8fd 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -1618,6 +1618,7 @@ HiperfError SubCommandRecord::OnSubCommand(std::vector& args) if (!isRoot_) { offset_ = GetOffsetNum(); SymbolsFile::offsetNum_ = offset_; + SymbolsFile::SetSensitiveOffsets(sensitiveOffsets_); HIPERF_HILOGI(MODULE_DEFAULT, "[OnSubCommand] get offset success"); } @@ -1840,6 +1841,10 @@ bool SubCommandRecord::ProcessRecord(PerfEventRecord& record) prcessRecordTimes_ += duration_cast(steady_clock::now() - startTime); #endif UpdateDevHostMapsAndIPs(record); + if (!isRoot_) { + UpdateSensitiveMaps(record); + UpdateSensitiveCallChains(record); + } return SaveRecord(record); #endif } @@ -2218,6 +2223,12 @@ void SubCommandRecord::CollectSymbol(PerfRecordSample *sample) sample->data_.ips[i] -= offset_; } } + if (!isRoot_ && sensitivePids_.count(serverPid)) { + uint32_t offset = sensitiveOffsets_[serverPid]; + if (sample->data_.ips[i] > offset) { + sample->data_.ips[i] -= offset; + } + } if (virtualRuntime_.IsKernelThread(serverPid)) { kernelThreadSymbolsHits_[serverPid].insert(sample->data_.ips[i]); } else if (context == PERF_CONTEXT_KERNEL) { @@ -2386,7 +2397,15 @@ void SubCommandRecord::SetHM() if (cmdline == "/bin/" + DEVHOST_FILE_NAME) { virtualRuntime_.SetDevhostPid(pid); devhostPid_ = static_cast(pid); - break; + } + + for (const auto& service : kSensitiveServices) { + if (cmdline.find(service) != std::string::npos) { + sensitivePids_.insert(static_cast(pid)); + sensitiveOffsets_[static_cast(pid)] = GetOffsetNum(); // 复用现有偏移量生成函数 + HIPERF_HILOGI(MODULE_DEFAULT, "Detected sensitive PID: %d (service: %s)", pid, service.c_str()); + break; // 匹配到一个服务即可跳出 + } } } } @@ -2543,6 +2562,46 @@ void SubCommandRecord::UpdateDevHostCallChains(PerfEventRecord& record) } } } + +void SubCommandRecord::UpdateSensitiveMaps(PerfEventRecord& record) +{ + if (record.GetType() == PERF_RECORD_MMAP) { + auto mmapRecord = static_cast(&record); + uint32_t pid = mmapRecord->data_.pid; + if (sensitivePids_.count(pid)) { // 匹配敏感服务PID + mmapRecord->data_.addr += sensitiveOffsets_[pid]; + } + } else if (record.GetType() == PERF_RECORD_MMAP2) { + auto mmap2Record = static_cast(&record); + uint32_t pid = mmap2Record->data_.pid; + if (sensitivePids_.count(pid)) { + mmap2Record->data_.addr += sensitiveOffsets_[pid]; + } + } +} + +void SubCommandRecord::UpdateSensitiveCallChains(PerfEventRecord& record) { + if (record.GetType() == PERF_RECORD_SAMPLE) { + auto sample = static_cast(&record); + uint32_t serverPid = sample->GetServerPidof(0); + + // 混淆当前IP + if (sensitivePids_.count(serverPid)) { + sample->data_.ip += sensitiveOffsets_[serverPid]; + } + + // 混淆调用栈所有IP + for (size_t i = 0; i < sample->data_.nr; i++) { + if (sample->data_.ips[i] >= PERF_CONTEXT_MAX || sample->data_.ips[i] < 2) { + continue; + } + serverPid = sample->GetServerPidof(i); + if (sensitivePids_.count(serverPid)) { + sample->data_.ips[i] += sensitiveOffsets_[serverPid]; + } + } + } +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/src/symbols_file.cpp b/src/symbols_file.cpp index e0dc295f6ea9ab4e0112a6743c120990f4e29263..26085cb76a030b7898b4079cd70cfe0ed2de8cfc 100644 --- a/src/symbols_file.cpp +++ b/src/symbols_file.cpp @@ -51,7 +51,7 @@ namespace HiPerf { bool SymbolsFile::onRecording_ = true; bool SymbolsFile::needParseJsFunc_ = false; uint32_t SymbolsFile::offsetNum_ = 0; - +std::unordered_map SymbolsFile::sensitiveOffsets_; const std::string SymbolsFile::GetBuildId() const { return buildId_; diff --git a/src/virtual_runtime.cpp b/src/virtual_runtime.cpp index e5e1718cf1cd3a16f2bc61133d84790bf34a07b3..965cdb041c4422f0fc3fd11db978201b0373af51 100644 --- a/src/virtual_runtime.cpp +++ b/src/virtual_runtime.cpp @@ -1022,6 +1022,8 @@ const DfxSymbol VirtualRuntime::GetKernelThreadSymbol(const uint64_t ip, const V auto map = thread.GetMaps()[mapIndex]; CHECK_TRUE(map != nullptr, vaddrSymbol, 0, ""); + uint32_t pid = thread.pid_; + uint32_t sensitiveOffset = 0; HLOGM("found addr 0x%" PRIx64 " in kthread map 0x%" PRIx64 " - 0x%" PRIx64 " from %s", ip, map->begin, map->end, map->name.c_str()); // found symbols by file name @@ -1031,6 +1033,12 @@ const DfxSymbol VirtualRuntime::GetKernelThreadSymbol(const uint64_t ip, const V vaddrSymbol.module_ = map->name; vaddrSymbol.fileVaddr_ = symbolsFile->GetVaddrInSymbols(ip, map->begin, map->offset); + if (SymbolsFile::sensitiveOffsets_.count(pid)) { + sensitiveOffset = SymbolsFile::sensitiveOffsets_[pid]; + if (vaddrSymbol.fileVaddr_ > sensitiveOffset) { + vaddrSymbol.fileVaddr_ -= sensitiveOffset; + } + } perf_callchain_context context = PERF_CONTEXT_MAX; if (GetSymbolCache(vaddrSymbol.fileVaddr_, vaddrSymbol, context)) { return vaddrSymbol; @@ -1044,6 +1052,8 @@ const DfxSymbol VirtualRuntime::GetKernelThreadSymbol(const uint64_t ip, const V DfxSymbol foundSymbols; if (thread.pid_ == devhostPid_ && recordCallBack_ != nullptr) { foundSymbols = symbolsFile->GetSymbolWithPcAndMap(vaddrSymbol.fileVaddr_, map); + } else if (SymbolsFile::sensitiveOffsets_.count(pid)) { + foundSymbols = symbolsFile->GetSymbolWithPcAndMap(vaddrSymbol.fileVaddr_, map); } else { foundSymbols = symbolsFile->GetSymbolWithVaddr(vaddrSymbol.fileVaddr_); } @@ -1054,6 +1064,10 @@ const DfxSymbol VirtualRuntime::GetKernelThreadSymbol(const uint64_t ip, const V ip, vaddrSymbol.fileVaddr_, map->name.c_str()); return vaddrSymbol; } + if (sensitiveOffset > 0) { + foundSymbols.funcVaddr_ += sensitiveOffset; + foundSymbols.fileVaddr_ += sensitiveOffset; + } return foundSymbols; } }