Calling iTunesStored's kbsync Remotely with A64Dbg ADCpp
About the author. I’m Colin Xiao — an independent reverse engineer, mostly working solo on contract jobs. I dig into compiled code of every kind, including but not limited to: Android and iOS apps, x86/x64/ARM native binaries, packers and obfuscators, DRM and license checks, network protocols and APIs, crypto and signature algorithms, malware, game binaries, and embedded/IoT firmware. I also handle large-scale data collection and vulnerability research. If you have any project in mind, I’d be glad to take it on — whatever it is, as long as it’s within my wheelhouse. Just reach out. You can reach me on X at @colinxiao_lab or on Telegram at https://t.me/ColinXiao666.
This research is published for educational and defensive purposes. The target sample is anonymized throughout.
Calling iTunesStored’s kbsync Remotely with A64Dbg ADCpp
A64Dbg’s ADCpp lets you script Objective-C against a live process and wire it into an adpy plugin for remote procedure calls. Here’s a real-world case: remotely invoking iTunesStored’s kbsync calculation.
Environment setup
Step 1 — install Textobot: https://gitee.com/geekneo/Textobot/blob/master/iOS/Textobot.deb
Step 2 — install the A64Dbg server: https://gitee.com/geekneo/A64Dbg/blob/master/a64dbg-server.deb
Step 3 — install the UVMDbg server: https://gitee.com/geekneo/A64Dbg/blob/master/a64dbg-server.uvm.deb
Reverse engineering
Analyzing itunesstored in LLDB mode, the kbsync calculation entry is reached through this code:
__text:00000001001C07AC ; void __cdecl -[KeybagSyncOperation run](KeybagSyncOperation *self, SEL)
__text:00000001001C07AC __KeybagSyncOperation_run_
__text:00000001001C07AC FC 6F BA A9 STP X28, X27, [SP,#-0x60]!
__text:00000001001C07B0 FA 67 01 A9 STP X26, X25, [SP,#0x10]
//...
__text:00000001001C0868 68 0E 00 B0 ADRP X8, #selRef_unsignedLongLongValue@PAGE
__text:00000001001C086C 01 E1 45 F9 LDR X1, [X8,#selRef_unsignedLongLongValue@PAGEOFF]
__text:00000001001C0870 E0 03 14 AA MOV X0, X20
__text:00000001001C0874 94 2A 03 94 BL _objc_msgSend
__text:00000001001C0878 61 01 80 52 MOV W1, #0xB
__text:00000001001C087C 08 9E F9 97 BL sub_10002809C
__text:00000001001C0880 F5 03 00 AA MOV X21, X0
sub_10002809C is the interface we want to call.
Writing the adpy plugin
See the code comments:
'''
This is really a very simple a64dbg python adp demo.
'''
# import basic adp definition like error/event code
from adpdef import *
# import adp api entries
from adp import *
import os
# send kbsync result to here
def kbsync_result_callback(buf):
print('kbsync result is : %s' % (buf))
# a64dbg debugengine event for python plugin
def adp_on_event(args):
event = args[adp_inkey_type]
# user clicked the plugin's main menu
if event == adp_event_main_menu:
# kbsync calc is valid on ios platform
if curPlatform() == adp_remote_unicornvm_ios:
runadc('%s/kbsync.mm' % (os.path.dirname(__file__)))
return success()
# ask for plugin's menu name
if event == adp_event_menuname:
return success('iTunesStoredKBSync')
# ask for plugins's version and descripton
if event == adp_event_adpinfo:
return success(('0.1.0', 'This is an itunesstored kbsync calc python plugin.'))
return failed(adp_err_unimpl)
#include <objc/runtime.h>
void adc_main() {
printf("Start to calc kbsync.\n");
auto KeybagSyncOperation = NSClassFromString(@"KeybagSyncOperation");
printf("Get KeybagSyncOperation class: %p.\n", KeybagSyncOperation);
auto method = class_getInstanceMethod(KeybagSyncOperation,
NSSelectorFromString(@"run"));
printf("Get run method: %p.\n", method);
auto imp = method_getImplementation(method);
printf("Get run implementation: %p.\n", imp);
const uint32_t *kbsync_caller = (uint32_t *)imp;
const uint8_t mov_w1_0xb[] = {
0x61, 0x01, 0x80, 0x52
};
while (*kbsync_caller++ != *(uint32_t *)&mov_w1_0xb[0]);
printf("Parsed kbsync caller: %p.\n", kbsync_caller);
// decode the bl instruction to get the real kbsyn callee
// 31 30 29 28 27 26 25 ... 0
// 1 0 0 1 0 1 - imm -
int blopcode = *(int *)kbsync_caller;
int blmask = 0xFC000000;
if (blopcode & (1 << 26)) {
// sign extend
blopcode |= blmask;
}
else {
blopcode &= ~blmask;
}
long kbsync_entry = (long)kbsync_caller + (blopcode << 2);
printf("Decoded kbsync entry: 0x%lx.\n", kbsync_entry);
// call the kbsync calc entry
NSData *kbsync = ((NSData *(*)(long, int))kbsync_entry)(1111, 0xB);
// send result to our python callback
if (kbsync) {
str2py("kbsync_result_callback", [kbsync base64EncodedStringWithOptions:0].UTF8String, 0);
}
else {
str2py("kbsync_result_callback", "error, you should download something in the AppStore to init kbsync.", 0);
}
printf("Finished calc kbsync.\n");
}
Running the plugin
Place both files in ~/A64Dbg/plugin, launch A64Dbg, and select Remote UnicornVM iOS mode:

Then attach to itunesstored:

Then run iTunesStoredKBSync from the Plugin menu:

The Log window shows:
Start to calc kbsync.
Get KeybagSyncOperation class: 0x10043dda0.
Get run method: 0x10041fdd8.
Get run implementation: 0x1002607ac.
Parsed kbsync caller: 0x10026087c.
Decoded kbsync entry: 0x1000c809c.
kbsync result is : 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
Finished calc kbsync.
Wrap-up
Scripted Objective-C plus an adpy plugin makes complex RPCs straightforward. Have fun.
Colin Xiao — I take on contract reverse-engineering work, and writeups like this are how I show what I can do. If you need help with anything in this space — including but not limited to the areas I cover above — I’m available. No project is too big or too small — if it’s reverse engineering and I can do it, I’ll take it. DM me on X (@colinxiao_lab) or Telegram (@ColinXiao666).
Get in touch