Skip to content

Commit

Permalink
fix: NtRecallMsgHook for NT 4288
Browse files Browse the repository at this point in the history
  • Loading branch information
cinit committed Jul 16, 2023
1 parent c8a3a79 commit 6a92d5f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 20 deletions.
14 changes: 8 additions & 6 deletions app/src/main/cpp/ntkernel/NtRecallMsgHook.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -360,29 +360,31 @@ bool InitInitNtKernelRecallMsgHook() {
}
sIsHooked = true;
gLibkernelBaseAddress = reinterpret_cast<void*>(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<std::string> errorMsgList;
Expand Down
41 changes: 32 additions & 9 deletions app/src/main/cpp/utils/AobScanUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool SearchForAllAobScanTargets(std::vector<AobScanTarget*> targets,
std::span<const uint8_t> 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()) {
Expand All @@ -47,17 +47,40 @@ bool SearchForAllAobScanTargets(std::vector<AobScanTarget*> targets,
hasFailed = true;
continue;
}
uint64_t result = uint64_t(int64_t(rawResultSet[0]) + offsetForResult);
std::vector<uint64_t> resultCandidates;
for (auto offsetForResult: offsetsForResult) {
resultCandidates.emplace_back(uint64_t(int64_t(rawResultSet[0]) + offsetForResult));
}
std::vector<uint64_t> 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;
}
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/cpp/utils/AobScanUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ class AobScanTarget {
std::vector<uint8_t> sequence;
int step = 0;
bool execMemOnly = false;
int64_t offsetForResult = 0;
std::vector<int64_t> offsetsForResult;
std::optional<Validator> resultValidator;

std::vector<uint64_t> results;

AobScanTarget() = default;

AobScanTarget(std::string name, std::vector<uint8_t> sequence, int step, bool execMemOnly, int64_t offsetForResult,
AobScanTarget(std::string name, std::vector<uint8_t> sequence, int step, bool execMemOnly, int64_t offsetsForResult,
std::optional<Validator> 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);
Expand All @@ -63,8 +63,8 @@ class AobScanTarget {
return *this;
}

inline AobScanTarget& WithOffsetForResult(int64_t newOffsetForResult) {
this->offsetForResult = newOffsetForResult;
inline AobScanTarget& WithOffsetsForResult(std::vector<int64_t> newOffsetsForResult) {
this->offsetsForResult = std::move(newOffsetsForResult);
return *this;
}

Expand Down

0 comments on commit 6a92d5f

Please sign in to comment.