ApplesauceOS
Read Markdown ↗Download .md

C functions and native memory

To call Objective-C classes and methods, start with Objective-C from JavaScript. This guide covers known C functions and memory buffers. Incorrect addresses or signatures can crash the target process.

C calls in the local automation context. RemoteC.forApp(bundleId) selects a running app with its helper enabled; it does not launch it. const app = RemoteC.forApp("com.apple.Preferences") gives you the same methods as C. Keep buffers and function handles in their original client/session.

C signatures

js
const length = C.bind("strlen", {returns: "size_t", args: ["cstring"]});
console.log(length("Hello"));
length.release();

Supported names: void (return only), bool, int8, uint8, int16, uint16, int32, uint32, int64, uint64, long, ulong, size_t, float, double, pointer, cstring, object, class, selector, and CGRect, CGPoint, CGSize, NSRange, UIEdgeInsets, CGAffineTransform, CGVector, UIOffset. long and size_t are 64-bit. Up to 32 fixed arguments are supported.

Signatures require returns and args. For bind() and call(), optional library loads an absolute dylib/framework executable path. bindAddress() rejects library; omit it. ownership:"retained" applies only to object results whose native ownership is +1; the default is borrowed. captureErrno:true returns {value, errno} captured around that call.

Variadic calls, callbacks, arbitrary custom structures and unions are unsupported. Objective-C non-null blocks and arbitrary pointer arguments are not supported by ObjC; use a known C signature where appropriate. Symbol resolution cannot infer the correct declaration.

Structures use plain JavaScript objects with these fields:

TypeFields
CGRectx, y, width, height
CGPoint / CGSizex, y / width, height
NSRangelocation, length
UIEdgeInsetstop, left, bottom, right
CGAffineTransforma, b, c, d, tx, ty
CGVector / UIOffsetdx, dy / horizontal, vertical

Calls are synchronous and run on the target main thread. Avoid blocking native functions. A remote timeout does not undo an action already executing; reconnect after a process restart and reacquire handles.

Managed buffers

js
const buffer = C.alloc(4);
try {
  buffer.writeBytes([65, 66, 67, 0]);
  console.log(buffer.readBytes());
} finally {
  buffer.release();
}

Managed allocations are limited to 16 MiB each and 64 MiB per session. Reads/writes allow at most 65536 bytes per operation. Use release(), not free/realloc. Releasing an external pointer handle does not free external memory. Closing either a C or ObjC client invalidates their shared references.

bindAddress() requires a verified absolute runtime function address in the selected process. Addresses change with ASLR and app restarts. Executable memory and alignment checks do not establish that an address is a valid function entry or that your signature is correct.