Files
reverse-engineering-anything/tests/conformance/native/calls.m
T
Kaoru0822andClaude Opus 5.5 9837203234 feat(native): observe function and Objective-C method calls under LLDB
Add observe_native_calls (CLI: observe-native-calls <path> <input-json>). It
launches the active Mach-O as an owned process under `lldb --batch`, stops at
caller-selected functions or Objective-C methods, records each entry and
auto-continues:

- thread, image, symbol, load and file address;
- raw integer argument registers and optional caller frames;
- for methods, the selector read from _cmd and the receiver's dynamic class,
  from LLDB's runtime reader without running target code.

No expression is evaluated and no existing process is attached. The run ends
on exit, max_events or duration_ms; REA then kills the process and confirms
that it is gone. The result also carries exit status, bounded stdout/stderr,
breakpoint resolution with partial coverage for unresolved requests, and
limitations. A target LLDB may not debug fails with a debugger-attach-denied
reason and remediation.

verify:native-calls checks the tool through the CLI and stdio MCP against a
compiled fixture, compares breakpoint addresses with nm, exercises every
outcome, and checks hardened-runtime targets with and without get-task-allow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:22:55 +00:00

34 lines
995 B
Objective-C

#import <Foundation/Foundation.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// Observed by verify:native-calls; `--wait` keeps the process running.
@interface ReaCallGreeter : NSObject
- (NSString *)greet:(NSString *)name times:(long)count;
@end
@implementation ReaCallGreeter
- (NSString *)greet:(NSString *)name times:(long)count {
return [NSString stringWithFormat:@"%@ x%ld", name, count];
}
@end
__attribute__((noinline)) int rea_call_add(int left, int right) {
return left + right;
}
int main(int argc, char **argv) {
@autoreleasepool {
if (argc > 1 && strcmp(argv[1], "--wait") == 0)
for (;;) sleep(1);
ReaCallGreeter *greeter = [ReaCallGreeter new];
for (long index = 0; index < 3; index++)
printf("%s %d\n", [[greeter greet:@"world" times:index] UTF8String],
rea_call_add((int)index, 40));
const char *marker = getenv("REA_CALLS_MARKER");
if (marker != NULL)
printf("marker %s\n", marker);
}
return 0;
}