Skip to content

Instantly share code, notes, and snippets.

@trishume
Created January 27, 2016 23:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trishume/5fc7678f2007d25ab05c to your computer and use it in GitHub Desktop.
Save trishume/5fc7678f2007d25ab05c to your computer and use it in GitHub Desktop.
TheEyeTribe protocol reverse engineering
// Reversing notes
// Tristan Hume
// trying to figure out what packets to send to get the lights to turn on for a TheEyeTribe tracker
// Steps so far:
// debug the server so I can figure out how to log all UVC control requests sent using
// the mechanism in https://github.com/HBehrens/CamHolderApp/blob/master/CamHolderApp%2FUVCCameraControl.h
// I've managed to figure out where the IOUSBDevRequestDesc is in registers at one point
// Next step is to create a debugger script that logs it whenever that method is called.
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#pragma mark Named Structures
struct _IplImage {
int _field1;
int _field2;
int _field3;
int _field4;
int _field5;
char _field6[4];
char _field7[4];
int _field8;
int _field9;
int _field10;
int _field11;
int _field12;
struct _IplROI *_field13;
struct _IplImage *_field14;
void *_field15;
struct _IplTileInfo *_field16;
int _field17;
char *_field18;
int _field19;
int _field20[4];
int _field21[4];
char *_field22;
};
struct _IplROI;
struct _IplTileInfo;
struct mutex {
struct _opaque_pthread_mutex_t {
long long __sig;
char __opaque[56];
} __m_;
};
#pragma mark Typedef'd Structures
typedef struct {
unsigned char _field1;
unsigned char _field2;
unsigned short _field3;
unsigned short _field4;
unsigned short _field5;
void *_field6;
unsigned int _field7;
} CDStruct_a911f613;
typedef struct {
int _field1;
int _field2;
int _field3;
} CDStruct_77932685;
typedef struct {
int _field1;
int _field2;
} CDStruct_1ef3fb1f;
#pragma mark -
//
// File: /Applications/EyeTribe/EyeTribe
// UUID: 2CB42854-BB82-3598-B5D3-EDD073BC296F
//
// Arch: x86_64
// Source version: 0.0.0.0.0
// Minimum Mac OS X version: 10.10.0
// SDK version: 10.9.0
//
// Objective-C Garbage Collection: Unsupported
//
@protocol AVCaptureVideoDataOutputSampleBufferDelegate <NSObject>
@optional
- (void)captureOutput:(AVCaptureOutput *)arg1 didDropSampleBuffer:(struct opaqueCMSampleBuffer *)arg2 fromConnection:(AVCaptureConnection *)arg3;
- (void)captureOutput:(AVCaptureOutput *)arg1 didOutputSampleBuffer:(struct opaqueCMSampleBuffer *)arg2 fromConnection:(AVCaptureConnection *)arg3;
@end
@protocol NSObject
@property(readonly, copy) NSString *description;
@property(readonly) Class superclass;
@property(readonly) unsigned long long hash;
- (struct _NSZone *)zone;
- (unsigned long long)retainCount;
- (id)autorelease;
- (oneway void)release;
- (id)retain;
- (BOOL)respondsToSelector:(SEL)arg1;
- (BOOL)conformsToProtocol:(Protocol *)arg1;
- (BOOL)isMemberOfClass:(Class)arg1;
- (BOOL)isKindOfClass:(Class)arg1;
- (BOOL)isProxy;
- (id)performSelector:(SEL)arg1 withObject:(id)arg2 withObject:(id)arg3;
- (id)performSelector:(SEL)arg1 withObject:(id)arg2;
- (id)performSelector:(SEL)arg1;
- (id)self;
- (Class)class;
- (BOOL)isEqual:(id)arg1;
@optional
@property(readonly, copy) NSString *debugDescription;
@end
@interface CaptureDelegate : NSObject
{
int newFrame;
struct __CVBuffer *mCurrentImageBuffer;
char *imagedata;
struct _IplImage *image;
char *bgr_imagedata;
struct _IplImage *bgr_image;
unsigned long long currSize;
}
- (int)updateImage;
- (struct _IplImage *)getOutput;
- (void)captureOutput:(id)arg1 didDropVideoFrameWithSampleBuffer:(id)arg2 fromConnection:(id)arg3;
- (void)captureOutput:(id)arg1 didOutputVideoFrame:(struct __CVBuffer *)arg2 withSampleBuffer:(id)arg3 fromConnection:(id)arg4;
- (void)dealloc;
- (id)init;
@end
@interface AVFCaptureDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
{
_Bool newFrame;
long long ts;
struct __CVBuffer *mCurrentImageBuffer;
struct mutex lock;
}
- (id).cxx_construct;
- (void).cxx_destruct;
- // Error parsing type: B24@0:8^{FrameGrabber=^^?BBBQ{thread=^{_opaque_pthread_t}}Q{VideoFormat=^^?iiiC{gtSize2<int>=ii}}{gtRect2<int, int>={gtPoint2<int>=ii}{gtSize2<int>=ii}}qQQii{atomic<bool>=AB}{vector<cv::Mat, std::__1::allocator<cv::Mat> >=^{Mat}^{Mat}{__compressed_pair<cv::Mat *, std::__1::allocator<cv::Mat> >=^{Mat}}}{mutex={_opaque_pthread_mutex_t=q[56c]}}{function<void (void *, const void *, unsigned long, const std::__1::pair<gtl::gtRect2<int, int> *, gtl::gtSize2<int> *> &)>={type=[24C]}^{__base<void (void *, const void *, unsigned long, const std::__1::pair<gtl::gtRect2<int, int> *, gtl::gtSize2<int> *> &)>}}}16, name: grabFrame:
- (_Bool)hasNewFrame;
- (void)captureOutput:(id)arg1 didOutputSampleBuffer:(struct opaqueCMSampleBuffer *)arg2 fromConnection:(id)arg3;
- (void)dealloc;
- (id)init;
// Remaining properties
@property(readonly, copy) NSString *debugDescription;
@property(readonly, copy) NSString *description;
@property(readonly) unsigned long long hash;
@property(readonly) Class superclass;
@end
@interface UVCCameraControl : NSObject
{
long long dataBuffer;
struct IOUSBInterfaceStruct190 **interface;
}
- (BOOL)getUvcControl:(int)arg1 withValue:(char *)arg2;
- (BOOL)setUvcControl:(int)arg1 withValue:(char *)arg2;
- (BOOL)getControlRange:(int)arg1 withMin:(long long *)arg2 withMax:(long long *)arg3;
- (BOOL)getControl:(int)arg1 withValue:(long long *)arg2;
- (BOOL)setControl:(int)arg1 withValue:(long long)arg2;
- (BOOL)getValueForControl:(void *)arg1 forControl:(const CDStruct_77932685 *)arg2;
- (BOOL)setValue:(void *)arg1 forControl:(const CDStruct_77932685 *)arg2;
- (CDStruct_1ef3fb1f)getRangeForControl:(const CDStruct_77932685 *)arg1;
- (BOOL)getDataFor:(int)arg1 withValue:(void *)arg2 withLength:(int)arg3 fromSelector:(int)arg4 at:(int)arg5;
- (BOOL)setData:(void *)arg1 withLength:(int)arg2 forSelector:(int)arg3 at:(int)arg4; 0x000000010003f6e0
- (BOOL)sendControlRequest:(CDStruct_a911f613)arg1; 0x000000010003f650
- (void)dealloc;
- (struct IOUSBInterfaceStruct190 **)getControlInferaceWithDeviceInterface:(struct IOUSBDeviceStruct **)arg1;
- (id)initWithVendorID:(long long)arg1 productID:(long long)arg2;
- (id)initWithLocationID:(unsigned int)arg1;
@end
char -[UVCCameraControl sendControlRequest:](void * self, void * _cmd, struct ? arg2) {
rdi = self->interface;
if (rdi == 0x0) goto loc_10003f682;
loc_10003f66d:
rcx = (*(*rdi + 0x40))();
if (rcx == 0x0) goto loc_10003f694;
loc_10003f679:
rdi = @"CameraControl Error: Unable to open interface (%08x)\n";
goto loc_10003f6c4;
loc_10003f6c4:
rbx = 0x0;
NSLog(rdi);
goto loc_10003f6cf;
loc_10003f6cf:
rax = rbx & 0xff;
return rax;
loc_10003f694:
rdi = 0x1->interface;
r14 = (*(*rdi + 0xc0))(rdi, 0x0, arg_0);
rdi = 0x1->interface;
rcx = (*(*rdi + 0x48))(rdi);
rbx = 0x1;
if (r14 == 0x0) goto loc_10003f6cf;
loc_10003f6bd:
rdi = @"CameraControl Error: Control request failed: %08x";
goto loc_10003f6c4;
loc_10003f682:
rbx = 0x0;
NSLog(@"CameraControl Error: No interface to send request");
goto loc_10003f6cf;
}
000000010003f650 push rbp ; Objective C Implementation defined at 0x10061b190 (instance)
000000010003f651 mov rbp, rsp
000000010003f654 push r15
000000010003f656 push r14
000000010003f658 push rbx
000000010003f659 push rax
000000010003f65a mov rbx, rdi
000000010003f65d mov r15, qword [ds:objc_ivar_offset_UVCCameraControl_interface]
000000010003f664 mov rdi, qword [ds:rbx+r15]
000000010003f668 test rdi, rdi
000000010003f66b je 0x10003f682
000000010003f66d mov rax, qword [ds:rdi]
000000010003f670 call qword [ds:rax+0x40]
000000010003f673 mov ecx, eax
000000010003f675 test ecx, ecx
000000010003f677 je 0x10003f694
000000010003f679 lea rdi, qword [ds:cfstring_CameraControl_Error__Unable_to_open_interface___08x__] ; @"CameraControl Error: Unable to open interface (%08x)\\n"
000000010003f680 jmp 0x10003f6c4
000000010003f682 lea rdi, qword [ds:cfstring_CameraControl_Error__No_interface_to_send_request] ; @"CameraControl Error: No interface to send request", argument "format" for method imp___stubs__NSLog, XREF=-[UVCCameraControl sendControlRequest:]+27
000000010003f689 xor ebx, ebx
000000010003f68b xor eax, eax
000000010003f68d call imp___stubs__NSLog
000000010003f692 jmp 0x10003f6cf
000000010003f694 lea rdx, qword [ss:rbp+arg_0] ; XREF=-[UVCCameraControl sendControlRequest:]+39
000000010003f698 mov rdi, qword [ds:rbx+r15]
000000010003f69c mov rax, qword [ds:rdi]
000000010003f69f xor esi, esi
000000010003f6a1 call qword [ds:rax+0xc0]
000000010003f6a7 mov r14d, eax
000000010003f6aa mov rdi, qword [ds:rbx+r15]
000000010003f6ae mov rax, qword [ds:rdi]
000000010003f6b1 call qword [ds:rax+0x48]
000000010003f6b4 mov ecx, eax
000000010003f6b6 test r14d, r14d
000000010003f6b9 mov bl, 0x1
000000010003f6bb je 0x10003f6cf
000000010003f6bd lea rdi, qword [ds:cfstring_CameraControl_Error__Control_request_failed___08x] ; @"CameraControl Error: Control request failed: %08x"
000000010003f6c4 xor ebx, ebx ; XREF=-[UVCCameraControl sendControlRequest:]+48
000000010003f6c6 xor eax, eax
000000010003f6c8 mov esi, ecx
000000010003f6ca call imp___stubs__NSLog
000000010003f6cf movzx eax, bl ; XREF=-[UVCCameraControl sendControlRequest:]+66, -[UVCCameraControl sendControlRequest:]+107
000000010003f6d2 add rsp, 0x8
000000010003f6d6 pop rbx
000000010003f6d7 pop r14
000000010003f6d9 pop r15
000000010003f6db pop rbp
000000010003f6dc ret
; endp
000000010003f6dd nop dword [ds:rax]
* thread #8: tid = 0x888c69, 0x00007fff8d81b86c IOKit`IOConnectCallMethod + 63, stop reason = instruction step into
* frame #0: 0x00007fff8d81b86c IOKit`IOConnectCallMethod + 63
frame #1: 0x0000000100be6c4a IOUSBLib`IOUSBInterfaceClass::ControlRequest(unsigned char, IOUSBDevRequestTO*) + 288
frame #2: 0x0000000100be9007 IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest(void*, unsigned char, IOUSBDevRequest*) + 101
frame #3: 0x000000010003f6a7 EyeTribe`___lldb_unnamed_function315$$EyeTribe + 87
frame #4: 0x000000010003f7a9 EyeTribe`___lldb_unnamed_function317$$EyeTribe + 89
frame #5: 0x000000010003f88d EyeTribe`___lldb_unnamed_function320$$EyeTribe + 45
frame #6: 0x000000010003f927 EyeTribe`___lldb_unnamed_function322$$EyeTribe + 55
frame #7: 0x000000010003c1b8 EyeTribe`___lldb_unnamed_function275$$EyeTribe + 104
frame #8: 0x00000001000339ce EyeTribe`___lldb_unnamed_function165$$EyeTribe + 734
frame #9: 0x00000001000378c4 EyeTribe`___lldb_unnamed_function191$$EyeTribe + 132
frame #10: 0x000000010002425b EyeTribe`___lldb_unnamed_function122$$EyeTribe + 1115
frame #11: 0x0000000100028ebb EyeTribe`___lldb_unnamed_function124$$EyeTribe + 219
frame #12: 0x0000000100030bba EyeTribe`___lldb_unnamed_function147$$EyeTribe + 8474
frame #13: 0x000000010002e834 EyeTribe`___lldb_unnamed_function146$$EyeTribe + 196
frame #14: 0x000000010001695f EyeTribe`___lldb_unnamed_function81$$EyeTribe + 15
frame #15: 0x0000000100017d39 EyeTribe`___lldb_unnamed_function103$$EyeTribe + 57
frame #16: 0x0000000100017e21 EyeTribe`___lldb_unnamed_function104$$EyeTribe + 113
frame #17: 0x00007fff8808505a libsystem_pthread.dylib`_pthread_body + 131
frame #18: 0x00007fff88084fd7 libsystem_pthread.dylib`_pthread_start + 176
frame #19: 0x00007fff880823ed libsystem_pthread.dylib`thread_start + 13
(lldb) si
Process 10119 stopped
* thread #8: tid = 0x88fb9a, 0x0000000100ae2fae IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest(void*, unsigned char, IOUSBDevRequest*) + 12, stop reason = instruction step into
frame #0: 0x0000000100ae2fae IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest(void*, unsigned char, IOUSBDevRequest*) + 12
IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest:
-> 0x100ae2fae <+12>: movb (%rbx), %al
0x100ae2fb0 <+14>: movb %al, -0x28(%rbp)
0x100ae2fb3 <+17>: movb 0x1(%rbx), %al
0x100ae2fb6 <+20>: movb %al, -0x27(%rbp)
(lldb) dis
IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest:
0x100ae2fa2 <+0>: pushq %rbp
0x100ae2fa3 <+1>: movq %rsp, %rbp
0x100ae2fa6 <+4>: pushq %rbx
0x100ae2fa7 <+5>: subq $0x28, %rsp
0x100ae2fab <+9>: movq %rdx, %rbx
-> 0x100ae2fae <+12>: movb (%rbx), %al
0x100ae2fb0 <+14>: movb %al, -0x28(%rbp)
0x100ae2fb3 <+17>: movb 0x1(%rbx), %al
0x100ae2fb6 <+20>: movb %al, -0x27(%rbp)
0x100ae2fb9 <+23>: movw 0x2(%rbx), %ax
0x100ae2fbd <+27>: movw %ax, -0x26(%rbp)
0x100ae2fc1 <+31>: movw 0x4(%rbx), %ax
0x100ae2fc5 <+35>: movw %ax, -0x24(%rbp)
0x100ae2fc9 <+39>: movw 0x6(%rbx), %ax
0x100ae2fcd <+43>: movw %ax, -0x22(%rbp)
0x100ae2fd1 <+47>: movq 0x8(%rbx), %rax
0x100ae2fd5 <+51>: movq %rax, -0x20(%rbp)
0x100ae2fd9 <+55>: movl 0x10(%rbx), %eax
0x100ae2fdc <+58>: movl %eax, -0x18(%rbp)
0x100ae2fdf <+61>: xorl %eax, %eax
0x100ae2fe1 <+63>: testb %sil, %sil
0x100ae2fe4 <+66>: movl $0x0, -0x10(%rbp)
0x100ae2feb <+73>: movl $0x1388, %ecx
0x100ae2ff0 <+78>: cmovnel %eax, %ecx
0x100ae2ff3 <+81>: movl %ecx, -0x14(%rbp)
0x100ae2ff6 <+84>: movq 0x8(%rdi), %rdi
0x100ae2ffa <+88>: movq (%rdi), %rax
0x100ae2ffd <+91>: leaq -0x28(%rbp), %rdx
0x100ae3001 <+95>: callq *0xf8(%rax)
0x100ae3007 <+101>: movl -0x18(%rbp), %ecx
0x100ae300a <+104>: movl %ecx, 0x10(%rbx)
0x100ae300d <+107>: addq $0x28, %rsp
0x100ae3011 <+111>: popq %rbx
0x100ae3012 <+112>: popq %rbp
0x100ae3013 <+113>: retq
(lldb) register read
General Purpose Registers:
rax = 0x0000000100ae4be8 IOUSBInterfaceClass::sUSBInterfaceInterfaceV700
rbx = 0x0000000105683810
rcx = 0x0000000000000000
rdx = 0x0000000105683810
rdi = 0x0000000100d1c440
rsi = 0x0000000000000000
rbp = 0x00000001056837d0
rsp = 0x00000001056837a0
r8 = 0x0000000000003d03
r9 = 0x0000000000000000
r10 = 0x00000000000010bc
r11 = 0xfffffffefa97da1c
r12 = 0x0000000105683a40
r13 = 0x0000000105683a90
r14 = 0x0000000100d19880
r15 = 0x0000000000000010
rip = 0x0000000100ae2fae IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest(void*, unsigned char, IOUSBDevRequest*) + 12
rflags = 0x0000000000000206
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) e (char)$rbx
(char) $16 = '\x10'
(lldb) e (int)((char)$rbx)
(int) $17 = 16
(lldb) e (int)((char*)$rbx)[0]
(int) $18 = 161
(lldb) si
Process 10119 stopped
* thread #8: tid = 0x88fb9a, 0x0000000100ae2fb0 IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest(void*, unsigned char, IOUSBDevRequest*) + 14, stop reason = instruction step into
frame #0: 0x0000000100ae2fb0 IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest(void*, unsigned char, IOUSBDevRequest*) + 14
IOUSBLib`IOUSBInterfaceClass::interfaceControlRequest:
-> 0x100ae2fb0 <+14>: movb %al, -0x28(%rbp)
0x100ae2fb3 <+17>: movb 0x1(%rbx), %al
0x100ae2fb6 <+20>: movb %al, -0x27(%rbp)
0x100ae2fb9 <+23>: movw 0x2(%rbx), %ax
(lldb) e (int)((char*)$rbx)[0]
(int) $19 = 161
(lldb) e (char)$al
(char) $20 = '�'
(lldb) e (int)(char)$al
(int) $21 = 161
(lldb) e (int)((char*)$rbx)[1]
(int) $22 = 129
// which is 0x81 which is UVC_GET_CUR in https://github.com/HBehrens/CamHolderApp/blob/master/CamHolderApp%2FUVCCameraControl.h
// EUREKA! $rbx is a *IOUSBDevRequestDesc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment