MCPcopy Create free account
hub / github.com/MJx0/KittyMemoryEx / _callFunctionFrom

Method _callFunctionFrom

KittyMemoryEx/KittyTrace.cpp:375–661  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

373// https://github.com/topjohnwu/Magisk/blob/master/native/src/zygisk/ptrace.cpp
374
375kitty_rp_call_t KittyTraceMgr::_callFunctionFrom(uintptr_t callerAddress, uintptr_t functionAddress, int nargs, ...)
376{
377 if (!_attached || _pid <= 0 || functionAddress == 0)
378 return {KT_RP_CALL_FAILED, {0}};
379
380 user_regs_struct backup_regs, return_regs, tmp_regs;
381 memset(&backup_regs, 0, sizeof(backup_regs));
382 memset(&return_regs, 0, sizeof(return_regs));
383 memset(&tmp_regs, 0, sizeof(tmp_regs));
384
385 // backup current regs
386 if (!getRegs(&backup_regs))
387 {
388 KITTY_LOGE("callFunction(%p): Failed, couldn't get regs.", (void *)functionAddress);
389 return {KT_RP_CALL_REGS_FAILED, {0}};
390 }
391
392 memcpy(&tmp_regs, &backup_regs, sizeof(backup_regs));
393
394 KT_REGS_ALIGN_STACK(backup_regs);
395 KT_REGS_ALIGN_STACK(tmp_regs);
396 KT_REGS_ALIGN_STACK(return_regs);
397
398 KITTY_LOGD("callFunction(%p): Calling with %d args.", (void *)functionAddress, nargs);
399
400 std::vector<uintptr_t> vargs(nargs, 0);
401 if (nargs > 0)
402 {
403 va_list vl;
404 va_start(vl, nargs);
405 for (int i = 0; i < nargs; i++)
406 {
407 vargs[i] = va_arg(vl, uintptr_t);
408 }
409 va_end(vl);
410 }
411
412 // cleanup failure return
413 auto failure_return = [&](KT_RP_CALL_STATUS s = KT_RP_CALL_FAILED) -> kitty_rp_call_t {
414 KITTY_LOGE("callFunction(%p): Failed.", (void *)functionAddress);
415 if (_autoRestoreRegs)
416 setRegs(&backup_regs);
417 return {s, {0}};
418 };
419
420 auto validate_ret = [this](const user_regs_struct &regs, uintptr_t return_addr) -> bool {
421 uintptr_t pc = regs.KT_REG_PC;
422 if (pc != return_addr)
423 {
424#if defined(__arm__)
425 if (uintptr_t((intptr_t(pc) & ~1)) != uintptr_t((intptr_t(return_addr) & ~1)))
426#elif defined(__i386__) || defined(__x86_64__)
427 if (pc < return_addr || pc > (return_addr + 7))
428#endif
429 {
430 siginfo_t si = {};
431 getSignalInfo(&si);
432 return uintptr_t(si.si_addr) == return_addr;

Callers

nothing calls this directly

Calls 3

getAddressMapFunction · 0.85
toStringMethod · 0.80
isValidMethod · 0.45

Tested by

no test coverage detected