Created
January 27, 2016 23:26
-
-
Save trishume/5fc7678f2007d25ab05c to your computer and use it in GitHub Desktop.
TheEyeTribe protocol reverse engineering
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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