碰到个混淆
c-stalker
// typedef void (* GumEventSinkCallback) (const GumEvent * event, GumCpuContext * cpu_context, gpointer user_data);
static void event_sink(const GumEvent* event, GumCpuContext const* cpu_context, gpointer user_data) {
// g_print("called event_sink %d \n", event->type);
// GUM_NOTHING = 0,
// GUM_CALL = 1 << 0,
// GUM_RET = 1 << 1,
// GUM_EXEC = 1 << 2,
// GUM_BLOCK = 1 << 3,
// GUM_COMPILE = 1 << 4,
switch (event->type) {
case GUM_NOTHING:
g_print("called event_sink GUM_NOTHING \n");
break;
case GUM_CALL:
g_print("called event_sink GUM_CALL \n");
break;
case GUM_RET:
g_print("called event_sink GUM_RET \n");
break;
case GUM_EXEC:
g_print("called event_sink GUM_EXEC \n");
case GUM_BLOCK:
g_print("called event_sink GUM_BLOCK \n");
break;
case GUM_COMPILE:
g_print("called event_sink GUM_COMPILE\n");
break;
default:
break;
}
}
static void
on_enter_sub (GumInvocationContext * ic,
gpointer user_data)
{
GumStalkerTransformer* transformer = gum_stalker_transformer_make_from_callback( print_insn, NULL, NULL);
g_print("ic->backend->get_thread_id(ic) : %lu \n",ic->backend->get_thread_id(ic));
g_print("gum_process_get_current_thread_id : %lu \n",gum_process_get_current_thread_id());
GumEventSink *sink = gum_event_sink_make_from_callback( GUM_CALL | GUM_RET, (GumEventSinkCallback)event_sink, NULL, NULL);
gum_stalker_follow(stalker, ic->backend->get_thread_id(ic), transformer, sink);
}
static void
on_leave_sub (GumInvocationContext * ic,
gpointer user_data)
{
// int result = GPOINTER_TO_INT (gum_invocation_context_get_return_value (ic));
gum_stalker_unfollow(stalker,ic->backend->get_thread_id(ic));
g_print (" on_leave_sub ");
// g_print("flag : %d \n", user_data );
}
void print_insn(GumStalkerIterator* iterator, GumStalkerOutput* output, gpointer user_data) {
const cs_insn* instr;
while (gum_stalker_iterator_next(iterator, &instr)) {
g_print("Inst Addr 0x%llx\t: \t %s \t %s\n", instr->address, instr->mnemonic, instr->op_str);
gum_stalker_iterator_keep(iterator);
}
}
js-stalker
function teststalker() {
let baseAddr = 0x7FA30;
try {
var targetAddress = get_func_addr('TargetModule', baseAddr);
if (targetAddress) {
Interceptor.attach(targetAddress, {
onEnter: function(args) {
console.log('Hooked function at { ' + baseAddr.toString(16) + '}: ');
console.log("threadId " + this.threadId);
Stalker.follow(this.threadId, {
events: {
call: true, // CALL instructions: yes please
ret: true, // RET instructions
exec: false, // all instructions: not recommended as it's
block: false, // block executed: coarse execution trace
compile: false // bl
},
transform : (iterator) =>{
let instruction = iterator.next();
const startAddress = instruction.address;
const isAppCode = startAddress.compare(targetAddress) >= 0;
do {
if (isAppCode ) {
console.log(instruction);
console.log(instruction.mnemonic + " " + instruction.opStr) ;
// console.log();
}
iterator.keep();
} while ((instruction = iterator.next()) !== null);
},
});
console.log(' ' + ' called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n') + '\n');
},
onLeave: function(retval) {
Stalker.unfollow();
// retval.replace(this.returnValue);
console.log('Hooked function at + ' + baseAddr + ' + ' + 'retval' + retval.toString());
}
});
} else {
console.warn('Address not found: ' + baseAddr);
}
} catch (e) {
console.error('Error hooking address: ' + baseAddr, e);
}
}
lldb-trace
Chomper
Version:1.0 StartHTML:0000000105 EndHTML:-9223372036854775704 StartFragment:-9223372036854775704 EndFragment:-9223372036854775704
import logging
import os
import uuid
from chomper import Chomper
from chomper.const import ARCH_ARM64, OS_IOS
from chomper.objc import ObjC
from chomper.utils import pyobj2nsobj
base_path = os.path.abspath(os.path.dirname(__file__))
log_format = "%(asctime)s - %(name)s - %(levelname)s: %(message)s"
logging.basicConfig(
format=log_format,
level=logging.INFO,
)
logger = logging.getLogger(__name__)
def hook_skip(uc, address, size, user_data):
pass
def hook_retval(retval):
def decorator(uc, address, size, user_data):
return retval
return decorator
def hook_ns_bundle(emu):
executable_path = f"/var/containers/Bundle/Application/{uuid.uuid4()}/com.ceair.b2m/target"
bundle_info = {
"CFBundleShortVersionString": "9.4.7",
"CFBundleExecutable": executable_path,
}
emu.add_interceptor("-[NSBundle initWithPath:]", hook_skip)
emu.add_interceptor("-[NSBundle bundleIdentifier]", hook_retval(pyobj2nsobj(emu, "com.ceair.b2m")))
emu.add_interceptor("-[NSBundle executablePath]", hook_retval(pyobj2nsobj(emu, executable_path)))
emu.add_interceptor("-[NSBundle infoDictionary]", hook_retval(pyobj2nsobj(emu, bundle_info)))
def main():
emu = Chomper(
arch=ARCH_ARM64,
os_type=OS_IOS,
logger=logger,
rootfs_path=os.path.join(base_path, "ios/rootfs"),
enable_ui_kit=True,
)
objc = ObjC(emu)
hook_ns_bundle(emu)
# Skip a file operation
emu.add_interceptor("_fopen", hook_retval(0))
libszstone = emu.load_module(
os.path.join(base_path, "ios/apps/com.www.yuzhouheike/target"),
exec_init_array=True,
trace_inst=True,
trace_symbol_calls=True
)
with objc.autorelease_pool():
result_size = emu.call_address(libszstone.base + 0x57188C)
logger.info("PRMShieldEventManage: %d",result_size)
if __name__ == "__main__":
main()