From 6a92d5f52eb3192e93dd844506b9a04b347a4840 Mon Sep 17 00:00:00 2001 From: ACh Sulfate Date: Sun, 16 Jul 2023 17:47:38 +0800 Subject: [PATCH] fix: NtRecallMsgHook for NT 4288 --- app/src/main/cpp/ntkernel/NtRecallMsgHook.cc | 14 ++++--- app/src/main/cpp/utils/AobScanUtils.cc | 41 +++++++++++++++----- app/src/main/cpp/utils/AobScanUtils.h | 10 ++--- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc b/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc index f63b57b332..664625e066 100644 --- a/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc +++ b/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc @@ -203,7 +203,7 @@ void NotifyRecallMsgEventForGroup(const std::string& peerUid, const std::string& void (* sOriginHandleGroupRecallSysMsgCallback)(void*, void*, void*) = nullptr; -void HandleGroupRecallSysMsgCallback([[maybe_unused]] void* x0, void* x1, [[maybe_unused]] void* x2) { +void HandleGroupRecallSysMsgCallback([[maybe_unused]] void* x0, void* x1, [[maybe_unused]] void* x2, [[maybe_unused]] int x3) { // LOGD("HandleGroupRecallSysMsgCallback start p1={:p}, p2={:p}, p3={:p}", x0, x1, x2); // we can still do it... hitherto p3 == null... we need to decode the message manually... uintptr_t base = (uintptr_t) gLibkernelBaseAddress; @@ -293,7 +293,7 @@ void HandleGroupRecallSysMsgCallback([[maybe_unused]] void* x0, void* x1, [[mayb void (* sOriginHandleC2cRecallSysMsgCallback)(void*, void*, void*) = nullptr; -void HandleC2cRecallSysMsgCallback([[maybe_unused]] void* p1, [[maybe_unused]] void* p2, void* p3) { +void HandleC2cRecallSysMsgCallback([[maybe_unused]] void* p1, [[maybe_unused]] void* p2, void* p3, [[maybe_unused]] int x3) { if (p3 == nullptr || *(void**) p3 == nullptr) { LOGE("HandleC2cGroupSysMsgCallback BUG !!! *p3 = null, this should not happen!!!"); return; @@ -360,29 +360,31 @@ bool InitInitNtKernelRecallMsgHook() { } sIsHooked = true; gLibkernelBaseAddress = reinterpret_cast(baseAddress); - + // RecallC2cSysMsg 09 8d 40 f8 f5 03 00 aa 21 00 80 52 f3 03 02 aa 29 8d 40 f9 auto targetRecallC2cSysMsg = AobScanTarget() .WithName("RecallC2cSysMsg") .WithSequence({0x09, 0x8d, 0x40, 0xf8, 0xf5, 0x03, 0x00, 0xaa, 0x21, 0x00, 0x80, 0x52, 0xf3, 0x03, 0x02, 0xaa, 0x29, 0x8d, 0x40, 0xf9}) .WithStep(4) .WithExecMemOnly(true) - .WithOffsetForResult(-4 * 8) + .WithOffsetsForResult({-4 * 8, -0x24}) .WithResultValidator(CommonAobScanValidator::kArm64StpX29X30SpImm); + // RecallGroupSysMsg 28 00 40 f9 61 00 80 52 09 8d 40 f8 29 8d 40 f9 auto targetRecallGroupSysMsg = AobScanTarget() .WithName("RecallGroupSysMsg") .WithSequence({0x28, 0x00, 0x40, 0xf9, 0x61, 0x00, 0x80, 0x52, 0x09, 0x8d, 0x40, 0xf8, 0x29, 0x8d, 0x40, 0xf9}) .WithStep(4) .WithExecMemOnly(true) - .WithOffsetForResult(-4 * 6) + .WithOffsetsForResult({-4 * 6, -0x24}) .WithResultValidator(CommonAobScanValidator::kArm64StpX29X30SpImm); + // GetDecoder 3f 8d 01 f8 f4 03 00 aa 1f 10 00 f9 auto targetGetDecoder = AobScanTarget() .WithName("GetDecoder") .WithSequence({0x3f, 0x8d, 0x01, 0xf8, 0xf4, 0x03, 0x00, 0xaa, 0x1f, 0x10, 0x00, 0xf9}) .WithStep(4) .WithExecMemOnly(true) - .WithOffsetForResult(-0x78) + .WithOffsetsForResult({-0x78}) .WithResultValidator(CommonAobScanValidator::kArm64StpX29X30SpImm); std::vector errorMsgList; diff --git a/app/src/main/cpp/utils/AobScanUtils.cc b/app/src/main/cpp/utils/AobScanUtils.cc index 50dcc621d2..f832fb9054 100644 --- a/app/src/main/cpp/utils/AobScanUtils.cc +++ b/app/src/main/cpp/utils/AobScanUtils.cc @@ -30,7 +30,7 @@ bool SearchForAllAobScanTargets(std::vector targets, std::span sequence = target->sequence; int step = target->step; bool execMemOnly = target->execMemOnly; - int64_t offsetForResult = target->offsetForResult; + auto offsetsForResult = target->offsetsForResult; auto validator = target->resultValidator; auto rawResultSet = FindByteSequenceImpl(imageBase, isLoadedImage, sequence, execMemOnly, step); if (rawResultSet.empty()) { @@ -47,17 +47,40 @@ bool SearchForAllAobScanTargets(std::vector targets, hasFailed = true; continue; } - uint64_t result = uint64_t(int64_t(rawResultSet[0]) + offsetForResult); + std::vector resultCandidates; + for (auto offsetForResult: offsetsForResult) { + resultCandidates.emplace_back(uint64_t(int64_t(rawResultSet[0]) + offsetForResult)); + } + std::vector results; + // run validator for each result candidate if (validator.has_value()) { - // TODO: 2023-07-14 if the image is a mmaped file, the offset in file is not provided, currently we just set it to 0 - if (!validator.value()(imageBase, isLoadedImage, result, 0)) { - errors.emplace_back(fmt::format("AobScanUtils: validator failed for target '{}' with sequence {} for result 0x{:x}", - name, bytes2hex(sequence), result)); - hasFailed = true; - continue; + for (auto resultCandidate: resultCandidates) { + // TODO: 2023-07-14 if the image is a mmaped file, the offset in file is not provided, currently we just set it to 0 + if (!validator.value()(imageBase, isLoadedImage, resultCandidate, 0)) { + continue; + } + results.emplace_back(resultCandidate); + } + } else { + results = std::move(resultCandidates); + } + if (results.empty()) { + errors.emplace_back(fmt::format("AobScanUtils: validator failed for all targets '{}' with sequence {} for result 0x{:x}+offset", + name, bytes2hex(sequence), rawResultSet[0])); + hasFailed = true; + continue; + } else if (results.size() > 1) { + std::string msg = fmt::format("AobScanUtils: validator passed too many for {} targets '{}' with sequence {} for results 0x{:x}+offset, result: ", + results.size(), name, bytes2hex(sequence), rawResultSet[0]); + for (auto result: results) { + msg += fmt::format("0x{:x}, ", result); } + errors.emplace_back(std::move(msg)); + hasFailed = true; + continue; + } else { + target->results.emplace_back(results[0]); } - target->results.emplace_back(result); } return !hasFailed; } diff --git a/app/src/main/cpp/utils/AobScanUtils.h b/app/src/main/cpp/utils/AobScanUtils.h index bb063c2934..3034aa7116 100644 --- a/app/src/main/cpp/utils/AobScanUtils.h +++ b/app/src/main/cpp/utils/AobScanUtils.h @@ -31,17 +31,17 @@ class AobScanTarget { std::vector sequence; int step = 0; bool execMemOnly = false; - int64_t offsetForResult = 0; + std::vector offsetsForResult; std::optional resultValidator; std::vector results; AobScanTarget() = default; - AobScanTarget(std::string name, std::vector sequence, int step, bool execMemOnly, int64_t offsetForResult, + AobScanTarget(std::string name, std::vector sequence, int step, bool execMemOnly, int64_t offsetsForResult, std::optional resultValidator) : name(std::move(name)), sequence(std::move(sequence)), step(step), execMemOnly(execMemOnly), - offsetForResult(offsetForResult), resultValidator(std::move(resultValidator)) {} + offsetsForResult(std::move(offsetsForResult)), resultValidator(std::move(resultValidator)) {} inline AobScanTarget& WithName(std::string newName) { this->name = std::move(newName); @@ -63,8 +63,8 @@ class AobScanTarget { return *this; } - inline AobScanTarget& WithOffsetForResult(int64_t newOffsetForResult) { - this->offsetForResult = newOffsetForResult; + inline AobScanTarget& WithOffsetsForResult(std::vector newOffsetsForResult) { + this->offsetsForResult = std::move(newOffsetsForResult); return *this; }