├── Screenshot.png
├── src
├── images
│ ├── App Icon.icns
│ ├── Prefs Output Icon.tif
│ ├── Prefs General Icon.tif
│ └── Main Window Background.tif
├── English.lproj
│ ├── Help
│ │ ├── art
│ │ │ ├── otxArt.png
│ │ │ ├── iconhelptoc.png
│ │ │ └── iconhelpcenter.png
│ │ ├── images
│ │ │ ├── pdf.gif
│ │ │ ├── up.gif
│ │ │ ├── dash.gif
│ │ │ ├── next.gif
│ │ │ ├── bullet.gif
│ │ │ ├── download.gif
│ │ │ ├── previous.gif
│ │ │ ├── sm_dash.gif
│ │ │ ├── MainWindow.jpg
│ │ │ ├── hideframes.gif
│ │ │ ├── showframes.gif
│ │ │ ├── sm_bullet.gif
│ │ │ ├── graydiamond.gif
│ │ │ ├── larg_bullet.gif
│ │ │ ├── sm_triangle.gif
│ │ │ └── sm_opentriangle.gif
│ │ ├── Contents
│ │ │ ├── chapter_2_section_5.html
│ │ │ ├── chapter_2_section_3.html
│ │ │ ├── chapter_2_section_11.html
│ │ │ ├── chapter_2_section_12.html
│ │ │ ├── chapter_2_section_4.html
│ │ │ ├── chapter_2_section_6.html
│ │ │ ├── chapter_2_section_7.html
│ │ │ ├── chapter_2_section_10.html
│ │ │ ├── chapter_2_section_2.html
│ │ │ ├── chapter_2_section_8.html
│ │ │ ├── index.html
│ │ │ ├── index_last.html
│ │ │ ├── toc_closed.html
│ │ │ ├── chapter_2_section_1.html
│ │ │ └── toc.html
│ │ ├── Overview
│ │ │ ├── index.html
│ │ │ ├── chapter_1_section_2.html
│ │ │ ├── index_last.html
│ │ │ ├── toc_closed.html
│ │ │ ├── chapter_1_section_1.html
│ │ │ └── toc.html
│ │ └── index.html
│ └── MainMenu.nib
│ │ └── keyedobjects.nib
├── source
│ ├── Processors
│ │ ├── ExeProcessor.h
│ │ ├── ExeProcessor.m
│ │ ├── PPC64Processor.h
│ │ ├── X8664Processor.h
│ │ ├── X86Processor.h
│ │ ├── PPCProcessor.h
│ │ ├── Exe64Processor.h
│ │ └── Exe32Processor.h
│ ├── SmoothViewAnimation.h
│ ├── Categories
│ │ ├── SysUtils.h
│ │ ├── Searchers64.h
│ │ ├── Searchers.h
│ │ ├── ListUtils.h
│ │ ├── List64Utils.h
│ │ ├── ArchSpecifics.h
│ │ ├── Arch64Specifics.h
│ │ ├── Objc64Accessors.h
│ │ ├── ObjcAccessors.h
│ │ ├── Object64Loader.h
│ │ ├── ObjectLoader.h
│ │ ├── Searchers64.m
│ │ ├── ArchSpecifics.m
│ │ ├── Arch64Specifics.m
│ │ ├── SysUtils.m
│ │ ├── ListUtils.m
│ │ ├── List64Utils.m
│ │ ├── Searchers.m
│ │ ├── Objc64Accessors.m
│ │ └── ObjcAccessors.m
│ ├── Protocols
│ │ ├── ErrorReporter.h
│ │ ├── ProgressReporter.h
│ │ └── Deobfuscator.h
│ ├── UserDefaultKeys.h
│ ├── SharedDefs.h
│ ├── CLIController.h
│ ├── SystemIncludes.h
│ ├── SmoothViewAnimation.m
│ ├── DropBox.h
│ ├── StolenDefs.h
│ ├── DropBox.m
│ ├── ObjcTypes.m
│ ├── AppController.h
│ ├── ObjcTypes.h
│ └── SyscallStrings.h
├── Version.plist
├── otx_Prefix.pch
├── main.m
└── Info.plist
├── .gitignore
└── README.md
/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/Screenshot.png
--------------------------------------------------------------------------------
/src/images/App Icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/images/App Icon.icns
--------------------------------------------------------------------------------
/src/images/Prefs Output Icon.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/images/Prefs Output Icon.tif
--------------------------------------------------------------------------------
/src/images/Prefs General Icon.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/images/Prefs General Icon.tif
--------------------------------------------------------------------------------
/src/English.lproj/Help/art/otxArt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/art/otxArt.png
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/pdf.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/pdf.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/up.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/up.gif
--------------------------------------------------------------------------------
/src/images/Main Window Background.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/images/Main Window Background.tif
--------------------------------------------------------------------------------
/src/source/Processors/ExeProcessor.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/source/Processors/ExeProcessor.h
--------------------------------------------------------------------------------
/src/source/Processors/ExeProcessor.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/source/Processors/ExeProcessor.m
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/dash.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/dash.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/next.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/next.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/art/iconhelptoc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/art/iconhelptoc.png
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/bullet.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/bullet.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/download.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/download.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/previous.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/previous.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/sm_dash.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/sm_dash.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/MainWindow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/MainWindow.jpg
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/hideframes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/hideframes.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/showframes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/showframes.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/sm_bullet.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/sm_bullet.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/art/iconhelpcenter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/art/iconhelpcenter.png
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/graydiamond.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/graydiamond.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/larg_bullet.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/larg_bullet.gif
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/sm_triangle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/sm_triangle.gif
--------------------------------------------------------------------------------
/src/English.lproj/MainMenu.nib/keyedobjects.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/MainMenu.nib/keyedobjects.nib
--------------------------------------------------------------------------------
/src/English.lproj/Help/images/sm_opentriangle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/x43x61x69/otx/HEAD/src/English.lproj/Help/images/sm_opentriangle.gif
--------------------------------------------------------------------------------
/src/source/SmoothViewAnimation.h:
--------------------------------------------------------------------------------
1 | /*
2 | SmoothViewAnimation.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | @interface SmoothViewAnimation : NSViewAnimation
10 | {
11 | @private
12 | NSWindow* iWindow;
13 | }
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/src/source/Categories/SysUtils.h:
--------------------------------------------------------------------------------
1 | /*
2 | SysUtils.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | @interface NSObject(SysUtils)
10 |
11 | - (BOOL)checkOtool: (NSString*)filePath;
12 | - (NSString*)pathForTool: (NSString*)toolName;
13 |
14 | @end
--------------------------------------------------------------------------------
/src/source/Protocols/ErrorReporter.h:
--------------------------------------------------------------------------------
1 | /*
2 | ErrorReporter.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | @protocol ErrorReporter
10 |
11 | - (void)reportError: (NSString*)inMessageText
12 | suggestion: (NSString*)inInformativeText;
13 |
14 | @end
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | *.xcworkspace
13 | !default.xcworkspace
14 | xcuserdata
15 | profile
16 | *.moved-aside
17 | DerivedData
18 | .idea/
19 |
--------------------------------------------------------------------------------
/src/Version.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildVersion
6 | 17
7 | ProjectName
8 | NibPBTemplates
9 | SourceVersion
10 | 1150000
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/source/Protocols/ProgressReporter.h:
--------------------------------------------------------------------------------
1 | /*
2 | ProgressReporter.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | #define PRValueKey @"PRValueKey" // NSNumber* (double)
10 | #define PRIndeterminateKey @"PRIndeterminateKey" // NSNumber* (BOOL)
11 | #define PRNewLineKey @"PRNewLineKey" // NSNumber* (BOOL)
12 | #define PRCompleteKey @"PRCompleteKey" // NSNumber* (BOOL)
13 | #define PRDescriptionKey @"PRDescriptionKey" // NSString*
14 |
15 | @protocol ProgressReporter
16 |
17 | - (void)reportProgress: (NSDictionary*)inState;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/src/source/Categories/Searchers64.h:
--------------------------------------------------------------------------------
1 | /*
2 | Searchers64.h
3 |
4 | A category on Exe64Processor that contains the various binary search
5 | methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Exe64Processor.h"
13 |
14 | @interface Exe64Processor(Searchers64)
15 |
16 | - (char*)findSymbolByAddress: (uint64_t)inAddress;
17 | - (BOOL)findClassMethod: (Method64Info**)outMI
18 | byAddress: (UInt64)inAddress;
19 | - (BOOL)findIvar: (objc2_64_ivar_t**)outIvar
20 | inClass: (objc2_64_class_t*)inClass
21 | withOffset: (UInt64)inOffset;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/src/otx_Prefix.pch:
--------------------------------------------------------------------------------
1 | /*
2 | otx_Prefix.pch
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #ifdef __OBJC__
8 | #import
9 | extern BOOL gCancel;
10 | #endif
11 |
12 | #ifndef NSAppKitVersionNumber10_4
13 | #define NSAppKitVersionNumber10_4 824
14 | #endif
15 |
16 | #ifndef NSAppKitVersionNumber10_6
17 | #define NSAppKitVersionNumber10_6 1038
18 | #endif
19 |
20 | #define OS_IS_PRE_TIGER NSAppKitVersionNumber < NSAppKitVersionNumber10_4
21 | #define OS_IS_POST_TIGER floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4
22 | #define OS_IS_TIGER (!OS_IS_PRE_TIGER) && (!OS_IS_POST_TIGER)
23 | #define OS_IS_PRE_SNOW NSAppKitVersionNumber < NSAppKitVersionNumber10_6
24 |
--------------------------------------------------------------------------------
/src/source/Categories/Searchers.h:
--------------------------------------------------------------------------------
1 | /*
2 | Searchers.h
3 |
4 | A category on Exe32Processor that contains the various binary search
5 | methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Exe32Processor.h"
13 |
14 | @interface Exe32Processor(Searchers)
15 |
16 | - (char*)findSymbolByAddress: (uint32_t)inAddress;
17 | - (BOOL)findClassMethod: (MethodInfo**)outMI
18 | byAddress: (uint32_t)inAddress;
19 | - (BOOL)findCatMethod: (MethodInfo**)outMI
20 | byAddress: (uint32_t)inAddress;
21 | - (BOOL)findIvar: (objc1_32_ivar*)outIvar
22 | inClass: (objc1_32_class*)inClass
23 | withOffset: (uint32_t)inOffset;
24 | - (BOOL)findIvar: (objc2_32_ivar_t**)outIvar
25 | inClass2: (objc2_32_class_t*)inClass
26 | withOffset: (uint32_t)inOffset;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/src/source/Categories/ListUtils.h:
--------------------------------------------------------------------------------
1 | /*
2 | ListUtils.h
3 |
4 | A category on Exe32Processor that contains the linked list
5 | manipulation methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Exe32Processor.h"
13 |
14 | @interface Exe32Processor(ListUtils)
15 |
16 | - (void)insertLine: (Line*)inLine
17 | before: (Line*)nextLine
18 | inList: (Line**)listHead;
19 | - (void)insertLine: (Line*)inLine
20 | after: (Line*)prevLine
21 | inList: (Line**)listHead;
22 | - (void)replaceLine: (Line*)inLine
23 | withLine: (Line*)newLine
24 | inList: (Line**)listHead;
25 | - (BOOL)printLinesFromList: (Line*)listHead;
26 | - (void)deleteLinesFromList: (Line*)listHead;
27 | - (void)deleteLinesBefore: (Line*)inLine
28 | fromList: (Line**)listHead;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/src/source/Categories/List64Utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | List64Utils.h
3 |
4 | A category on Exe64Processor that contains the linked list
5 | manipulation methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Exe64Processor.h"
13 |
14 | @interface Exe64Processor(List64Utils)
15 |
16 | - (void)insertLine: (Line64*)inLine
17 | before: (Line64*)nextLine
18 | inList: (Line64**)listHead;
19 | - (void)insertLine: (Line64*)inLine
20 | after: (Line64*)prevLine
21 | inList: (Line64**)listHead;
22 | - (void)replaceLine: (Line64*)inLine
23 | withLine: (Line64*)newLine
24 | inList: (Line64**)listHead;
25 | - (BOOL)printLinesFromList: (Line64*)listHead;
26 | - (void)deleteLinesFromList: (Line64*)listHead;
27 | - (void)deleteLinesBefore: (Line64*)inLine
28 | fromList: (Line64**)listHead;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/src/source/Protocols/Deobfuscator.h:
--------------------------------------------------------------------------------
1 | /*
2 | Deobfuscator.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | /* NopList
10 |
11 | 'list' is a 'count'-sized array of addresses at which an obfuscated
12 | sequence of nops was found.
13 | */
14 | typedef struct NopList
15 | {
16 | unsigned char** list;
17 | uint32_t count;
18 | }
19 | NopList;
20 |
21 | // ============================================================================
22 |
23 | @protocol Deobfuscator
24 |
25 | - (BOOL)verifyNops: (unsigned char***)outList
26 | numFound: (uint32_t*)outFound;
27 | - (unsigned char**)searchForNopsIn: (unsigned char*)inHaystack
28 | ofLength: (uint32_t)inHaystackLength
29 | numFound: (uint32_t*)outFound;
30 | - (NSURL*)fixNops: (NopList*)inList
31 | toPath: (NSString*)inOutputFilePath;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/src/source/Processors/PPC64Processor.h:
--------------------------------------------------------------------------------
1 | /*
2 | PPC64Processor.h
3 |
4 | A subclass of Exe64Processor that handles PPC64-specific issues.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe64Processor.h"
12 |
13 | #define MB64(x) ((((x) >> 6) & 0x1f) | (x) & 0x20) // bits 5 - 10, split
14 | #define SH(x) ((((x) >> 12) & 0x0f) | ((x) >> 7) & 0x10) // bits 11 - 15, split
15 | #define DS(x) (SInt64)(BD((x))) // bits 2 - 15
16 |
17 | // ============================================================================
18 |
19 | @interface PPC64Processor : Exe64Processor
20 | {
21 | GP64RegisterInfo iRegInfos[32];
22 | GP64RegisterInfo iLR;
23 | GP64RegisterInfo iCTR;
24 |
25 | Var64Info* iLocalSelves; // 'self' copied to local variables
26 | uint32_t iNumLocalSelves;
27 | Var64Info* iLocalVars;
28 | uint32_t iNumLocalVars;
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/src/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | main.m
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | #ifdef OTX_CLI
10 | #import "CLIController.h"
11 | #else
12 | #import
13 | #endif
14 |
15 | BOOL gCancel = NO;
16 |
17 | int main(
18 | int argc,
19 | char* argv[])
20 | {
21 | if (OS_IS_PRE_TIGER)
22 | {
23 | fprintf(stderr, "otx requires Mac OS X 10.4 or higher.\n");
24 | return -1;
25 | }
26 |
27 | int result = 1;
28 |
29 | #ifdef OTX_CLI
30 | @autoreleasepool {
31 | CLIController* controller =
32 | [[[CLIController alloc] initWithArgs: argv count: argc] autorelease];
33 |
34 | if (controller)
35 | {
36 | [controller processFile];
37 | result = noErr;
38 | }
39 | else
40 | result = -1;
41 | }
42 | #else
43 | result = NSApplicationMain(argc, (const char**)argv);
44 | #endif
45 |
46 | return result;
47 | }
48 |
--------------------------------------------------------------------------------
/src/source/Categories/ArchSpecifics.h:
--------------------------------------------------------------------------------
1 | /*
2 | ArchSpecifics.h
3 |
4 | A category on Exe32Processor that contains most of the
5 | architecture-specific methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Exe32Processor.h"
13 |
14 | @interface Exe32Processor(ArchSpecifics)
15 |
16 | - (void)gatherFuncInfos;
17 | - (void)postProcessCodeLine: (Line**)ioLine;
18 | - (BOOL)lineIsFunction: (Line*)inLine;
19 | - (BOOL)codeIsBlockJump: (UInt8*)inCode;
20 | - (void)codeFromLine: (Line*)inLine;
21 | - (void)checkThunk: (Line*)inLine;
22 | - (BOOL)getThunkInfo: (ThunkInfo*)outInfo
23 | forLine: (Line*)inLine;
24 |
25 | - (void)commentForLine: (Line*)inLine;
26 | - (void)commentForSystemCall;
27 | - (void)commentForMsgSend: (char*)ioComment
28 | fromLine: (Line*)inLine;
29 |
30 | - (void)resetRegisters: (Line*)inLine;
31 | - (void)updateRegisters: (Line*)inLine;
32 | - (BOOL)restoreRegisters: (Line*)inLine;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Show md5 checksum
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Show md5 checksum
17 | Includes the md5 checksum of the executable file at the beginning of the output file.
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Show data sections
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Show data sections
17 | Prints the contents of all data sections at the end of the output file.
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/source/Categories/Arch64Specifics.h:
--------------------------------------------------------------------------------
1 | /*
2 | Arch64Specifics.h
3 |
4 | A category on Exe64Processor that contains most of the
5 | architecture-specific methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Exe64Processor.h"
13 |
14 | @interface Exe64Processor(Arch64Specifics)
15 |
16 | - (void)gatherFuncInfos;
17 | - (void)postProcessCodeLine: (Line64**)ioLine;
18 | - (BOOL)lineIsFunction: (Line64*)inLine;
19 | - (BOOL)codeIsBlockJump: (UInt8*)inCode;
20 | - (void)codeFromLine: (Line64*)inLine;
21 | - (void)checkThunk: (Line64*)inLine;
22 | - (BOOL)getThunkInfo: (ThunkInfo*)outInfo
23 | forLine: (Line64*)inLine;
24 |
25 | - (void)commentForLine: (Line64*)inLine;
26 | - (void)commentForSystemCall;
27 | - (void)commentForMsgSend: (char*)ioComment
28 | fromLine: (Line64*)inLine;
29 |
30 | - (void)resetRegisters: (Line64*)inLine;
31 | - (void)updateRegisters: (Line64*)inLine;
32 | - (BOOL)restoreRegisters: (Line64*)inLine;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/src/source/UserDefaultKeys.h:
--------------------------------------------------------------------------------
1 | /*
2 | UserDefaultKeys.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #define AskOutputDirKey @"AskOutputDir"
8 | #define DemangleCppNamesKey @"DemangleCppNames"
9 | #define EntabOutputKey @"EntabOutput"
10 | #define OpenOutputFileKey @"OpenOutputFile"
11 | #define OutputAppKey @"OutputApp"
12 | #define OutputFileExtensionKey @"OutputFileExtension"
13 | #define OutputFileNameKey @"OutputFileName"
14 | #define SeparateLogicalBlocksKey @"SeparateLogicalBlocks"
15 | #define ShowDataSectionKey @"ShowDataSection"
16 | #define ShowIvarTypesKey @"ShowIvarTypes"
17 | #define ShowLocalOffsetsKey @"ShowLocalOffsets"
18 | #define ShowMD5Key @"ShowMD5"
19 | #define ShowMethodReturnTypesKey @"ShowMethodReturnTypes"
20 | #define ShowReturnStatementsKey @"ShowReturnStatements"
21 | #define UseCustomNameKey @"UseCustomName"
22 | #define VerboseMsgSendsKey @"VerboseMsgSends"
23 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_11.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Location
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Location
17 | This
18 | option instructs otx to place the output file in the same folder as the
19 | executable(or the .app package) or to ask you where to save the output
20 | file.
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/source/SharedDefs.h:
--------------------------------------------------------------------------------
1 | /*
2 | SharedDefs.h
3 |
4 | Definitions shared by GUI and CLI targets.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | /* ProcOptions
10 |
11 | Options for processing executables. GUI target sets these using
12 | NSUserDefaults, CLI target sets them with command line arguments. This
13 | is necessary for the CLI target to behave consistently across
14 | invocations, and to keep it from altering the GUI target's prefs.
15 | */
16 | typedef struct
17 | { // CLI flags
18 | BOOL localOffsets; // l
19 | BOOL showCode; // C
20 | BOOL entabOutput; // e
21 | BOOL dataSections; // d
22 | BOOL checksum; // c
23 | BOOL verboseMsgSends; // m
24 | BOOL separateLogicalBlocks; // b
25 | BOOL demangleCppNames; // n
26 | BOOL returnTypes; // r
27 | BOOL variableTypes; // v
28 | BOOL returnStatements; // R
29 | BOOL debugMode; // -debug
30 | }
31 | ProcOptions;
32 |
--------------------------------------------------------------------------------
/src/source/Categories/Objc64Accessors.h:
--------------------------------------------------------------------------------
1 | /*
2 | Objc64Accessors.h
3 |
4 | What the filename says.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe64Processor.h"
12 |
13 | @interface Exe64Processor(ObjcAccessors)
14 |
15 | - (BOOL)getObjcClassPtr: (objc2_64_class_t**)outClass
16 | fromMethod: (UInt64)inAddress;
17 | - (BOOL)getObjcMethod: (Method64Info**)outMI
18 | fromAddress: (UInt64)inAddress;
19 | - (BOOL)getObjcMethodList: (objc2_64_method_list_t*)outList
20 | methods: (objc2_64_method_t**)outMethods
21 | fromAddress: (UInt64)inAddress;
22 | - (BOOL)getObjcDescription: (char**)outDescription
23 | fromObject: (const char*)inObject
24 | type: (UInt8)inType;
25 | - (BOOL)getObjcClass: (objc2_64_class_t*)outClass
26 | fromName: (const char*)inName;
27 | - (BOOL)getObjcClassPtr: (objc2_64_class_t**)outClassPtr
28 | fromName: (const char*)inName;
29 | - (BOOL)getObjcMetaClass: (objc2_64_class_t*)outClass
30 | fromClass: (objc2_64_class_t*)inClass;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_12.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Open file with application
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Open file with application
17 | If
18 | you would like otx to open the output file immediately after it is created, enter the name of your preferred viewer in this text field. Capitalization is ignored.
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | otx Help: Entab output
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Entab output
18 | Replaces
19 | multiple spaces with tabs where possible. This option reduces the
20 | output file size, but may look strange depending on the application
21 | used to view the output.
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Demangle names
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Demangle names
17 | Attempts to revert mangled C++ symbols to their original form.
18 |
19 | _Znwm
20 | or
21 | operator new(unsigned long)
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_7.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Show method types
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Show method types
17 | Displays the data type of the return value of ObjC methods.
18 |
19 | -(unsigned int)[CDropBox draggingEntered:]
20 | or
21 | -[CDropBox draggingEntered:]
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | otx
2 | ===
3 |
4 | [](http://vox.vg/)   
5 |
6 | The Mach-O disassembler.
7 |
8 | 
9 |
10 | Description
11 | -----------
12 |
13 | This is an up-to-date version of otx.
14 |
15 | Following changes has been made:
16 |
17 | * Based on 10.9 SDK.
18 | * 64bit binary.
19 | * Works with new otool came with Xcode 4.2+.
20 | * Source code compatible with Xcode 5+.
21 | * Tons of bug fixes.
22 |
23 |
24 | Changelog
25 | ---------
26 |
27 | Build 566:
28 |
29 | * Fix the Save menu. (#4)
30 |
31 | Build 565:
32 |
33 | * Fix the Open menu. (#3)
34 |
35 | Build 564:
36 |
37 | * No more symbolic link.
38 | * Minor UI fix.
39 |
40 | Build 563:
41 |
42 | * Minor UI updates.
43 |
44 | Build 562:
45 |
46 | * Update base SDK to 10.9 and Xcode 5.1.
47 |
48 | Build 561:
49 |
50 | * Initial release.
51 |
52 |
53 | License
54 | -------
55 |
56 | The otx project and all original otx source files are in the public domain.
57 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_10.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Filename
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Filename
17 | otx
18 | can use the name of the executable when creating the output file, or
19 | you may specify a name to use for all output files. You may also
20 | specify a filename extension, or let otx use the default "txt". These
21 | text fields are only starting points; they can always be overridden by
22 | the "Output:" text field in the main window.
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Show local offsets
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Show local offsets
17 | Displays the distance in bytes from the beginning of a function to each instruction.
18 |
19 | +196 00002c44 3c5f0002 addis r2,r31,0x2
20 | or
21 | 00002c44 3c5f0002 addis r2,r31,0x2
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_8.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Show variable types
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Show variable types
17 | Displays the data type of ObjC member variables.
18 |
19 | +100 00003564 807f0068 lwz r3,0x68(r31) (NSString)mOutputFileName
20 | or
21 | +100 00003564 807f0068 lwz r3,0x68(r31) mOutputFileName
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/source/CLIController.h:
--------------------------------------------------------------------------------
1 | /*
2 | CLIController.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | #import "SharedDefs.h"
10 | #import "ErrorReporter.h"
11 | #import "ProgressReporter.h"
12 |
13 | // Default ProcOptions values
14 | #define SHOW_LOCAL_OFFSETS YES
15 | #define SHOW_CODE YES
16 | #define DONT_ENTAB_OUTPUT NO
17 | #define DONT_SHOW_DATA_SECTIONS NO
18 | #define SHOW_CHECKSUM YES
19 | #define SHOW_VERBOSE_MSGSENDS YES
20 | #define DONT_SEPARATE_LOGICAL_BLOCKS NO
21 | #define DEMANGLE_CPP_NAMES YES
22 | #define SHOW_METHOD_RETURN_TYPES YES
23 | #define SHOW_VARIABLE_TYPES YES
24 | #define SHOW_RETURN_STATEMENTS YES
25 |
26 | // ============================================================================
27 |
28 | @interface CLIController : NSObject
29 | {
30 | @private
31 | NSURL* iOFile;
32 | cpu_type_t iArchSelector;
33 | uint32_t iFileArchMagic;
34 | NSString* iExeName;
35 | BOOL iVerify;
36 | BOOL iShowProgress;
37 | ProcOptions iOpts;
38 | }
39 |
40 | - (id)initWithArgs: (char**)argv
41 | count: (SInt32)argc;
42 | - (void)usage;
43 | - (void)processFile;
44 | - (void)verifyNops;
45 | - (void)newPackageFile: (NSURL*)inPackageFile;
46 | - (void)newOFile: (NSURL*)inOFile
47 | needsPath: (BOOL)inNeedsPath;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/src/source/Processors/X8664Processor.h:
--------------------------------------------------------------------------------
1 | /*
2 | X8664Processor.h
3 |
4 | A subclass of Exe64Processor that handles x86_64-specific issues.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe64Processor.h"
12 | #import "Deobfuscator.h"
13 |
14 | #define REX_BIT_ON (1 << 3)
15 | #define REX_BIT_OFF 0
16 |
17 | /*#define REX_W(r) ((r) >> 3 & 0x1)
18 | #define REX_R(r) ((r) >> 2 & 0x1) // extends "REG1"
19 | #define REX_X(r) ((r) >> 1 & 0x1)
20 | #define REX_B(r) ((r) & 0x1) // extends "REG2"*/
21 |
22 | #define REX_W(x) ((x) & 0x8)
23 | #define REX_R(x) ((x) & 0x4) // extends "REG1"
24 | #define REX_X(x) ((x) & 0x2)
25 | #define REX_B(x) ((x) & 0x1) // extends "REG2"
26 |
27 | #define XREG1(n, x) (REG1((n)) | (REX_R((x)) << 1))
28 | #define XREG2(n, x) (REG2((n)) | (REX_B(x) << 3))
29 |
30 | // Extended register identifiers in r/m field of mod r/m byte
31 | enum {
32 | R8 = 8,
33 | R9,
34 | R10,
35 | R11,
36 | R12,
37 | R13,
38 | R14,
39 | R15
40 | };
41 |
42 | // ============================================================================
43 |
44 | @interface X8664Processor : Exe64Processor
45 | {
46 | GP64RegisterInfo iStack[MAX_STACK_SIZE];
47 | GP64RegisterInfo iRegInfos[16];
48 |
49 | Var64Info* iLocalSelves; // 'self' copied to local variables
50 | uint32_t iNumLocalSelves;
51 | Var64Info* iLocalVars;
52 | uint32_t iNumLocalVars;
53 | UInt64 iHighestJumpTarget;
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Overview/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | otx Help
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | This document set is best viewed in a browser that supports frames. To access the first page Click here
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | otx Help: Preferences
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | This document set is best viewed in a browser that supports frames. To access the first page Click here
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/source/Categories/ObjcAccessors.h:
--------------------------------------------------------------------------------
1 | /*
2 | ObjcAccessors.h
3 |
4 | What the filename says.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe32Processor.h"
12 |
13 | @interface Exe32Processor(ObjcAccessors)
14 |
15 | - (BOOL)getObjcClassPtr: (objc_32_class_ptr*)outClass
16 | fromMethod: (uint32_t)inAddress;
17 | - (BOOL)getObjcClassPtr: (objc_32_class_ptr *)outClassPtr
18 | fromName: (const char*)inName;
19 | - (BOOL)getObjcMethod: (MethodInfo**)outMI
20 | fromAddress: (uint32_t)inAddress;
21 |
22 | // Obj-C 1 Only
23 | - (BOOL)getObjc1CatPtr: (objc1_32_category**)outCat
24 | fromMethod: (uint32_t)inAddress;
25 | - (BOOL)getObjc1MethodList: (objc1_32_method_list*)outList
26 | methods: (objc1_32_method**)outMethods
27 | fromAddress: (uint32_t)inAddress;
28 | - (BOOL)getObjc1Description: (char**)outDescription
29 | fromObject: (const char*)inObject
30 | type: (UInt8)inType;
31 | - (BOOL)getObjc1Symtab: (objc1_32_symtab*)outSymTab
32 | defs: (uint32_t **)outDefs
33 | fromModule: (objc1_32_module*)inModule;
34 | - (BOOL)getObjc1Class: (objc1_32_class*)outClass
35 | fromDef: (uint32_t)inDef;
36 | - (BOOL)getObjc1Category: (objc1_32_category*)outCat
37 | fromDef: (uint32_t)inDef;
38 | - (BOOL)getObjc1Class: (objc1_32_class*)outClass
39 | fromName: (const char*)inName;
40 | - (BOOL)getObjc1MetaClass: (objc1_32_class*)outClass
41 | fromClass: (objc1_32_class*)inClass;
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/src/source/SystemIncludes.h:
--------------------------------------------------------------------------------
1 | /*
2 | SystemIncludes.h
3 |
4 | In order to implement the struct shortcut, all system files that define
5 | structs need to be #included before the #defines. To make this easier,
6 | all such files are included from here, and other files simply include
7 | this file. The behavior of the #import directive makes this safe.
8 |
9 | This file is in the public domain.
10 | */
11 |
12 | #ifdef __OBJC__
13 | #import
14 | #endif
15 |
16 | #import
17 | #import
18 | #import
19 | #import
20 | #import
21 | #import
22 | #import
23 | #import
24 | #import
25 | #import
26 | #import
27 | #import
28 |
29 | #define fat_header struct fat_header
30 | #define fat_arch struct fat_arch
31 | #define mach_header struct mach_header
32 | #define mach_header_64 struct mach_header_64
33 | #define load_command struct load_command
34 | #define segment_command struct segment_command
35 | #define segment_command_64 struct segment_command_64
36 | #define symtab_command struct symtab_command
37 | #define dysymtab_command struct dysymtab_command
38 | #define nlist struct nlist
39 | #define nlist_64 struct nlist_64
40 | #define section struct section
41 | #define section_64 struct section_64
42 |
43 | // carpal tunnel inhibitors
44 | #define UTF8STRING(s) [(s) UTF8String]
45 | #define NSSTRING(s) [NSString stringWithUTF8String: (s)]
46 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Overview/chapter_1_section_2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Specifying files to analyze.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Specifying files to analyze.
17 | There
18 | are several ways to open an executable file in otx. You can drop a file
19 | onto the main window, or onto otx's icon either in the Finder or Dock.
20 | You can also use the "Open" command in otx's File menu. If you drop an
21 | application package(.app) onto otx, it will attempt to open the
22 | application's main executable file. In some cases, the application
23 | package and executable file have different names, and you must locate
24 | the executable file manually (Show Package Contents) and open it directly.
25 | Similarly, if you want to open secondary executable files inside an
26 | application package, such as frameworks, these must be located and
27 | opened manually.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | otx Help
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | This document set is best viewed in a browser that supports frames. To access the first page Click here
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/index_last.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | otx Help: Open file with application
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | This document set is best viewed in a browser that supports frames. To access the first page Click here
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Overview/index_last.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | otx Help: Specifying files to analyze.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | This document set is best viewed in a browser that supports frames. To access the first page Click here
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleDocumentTypes
8 |
9 |
10 | CFBundleOSTypes
11 |
12 | ****
13 |
14 | CFBundleTypeExtensions
15 |
16 | *
17 |
18 | CFBundleTypeName
19 | NSFilenamesPboardType
20 | CFBundleTypeRole
21 | Viewer
22 | LSTypeIsPackage
23 |
24 |
25 |
26 | CFBundleExecutable
27 | ${EXECUTABLE_NAME}
28 | CFBundleGetInfoString
29 | 0.17 (Public Domain, https://github.com/x43x61x69/OTX)
30 | CFBundleHelpBookFolder
31 | Help
32 | CFBundleHelpBookName
33 | otx Help
34 | CFBundleIconFile
35 | App Icon.icns
36 | CFBundleIdentifier
37 | $(PRODUCT_BUNDLE_IDENTIFIER)
38 | CFBundleInfoDictionaryVersion
39 | 6.0
40 | CFBundleName
41 | ${PRODUCT_NAME}
42 | CFBundlePackageType
43 | APPL
44 | CFBundleShortVersionString
45 | 0.17
46 | CFBundleSignature
47 | ot++
48 | CFBundleVersion
49 | 566
50 | LSApplicationCategoryType
51 | public.app-category.developer-tools
52 | NSHumanReadableCopyright
53 | The otx project and all original otx source files are in the public domain.
54 | NSMainNibFile
55 | MainMenu
56 | NSPrincipalClass
57 | NSApplication
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/source/SmoothViewAnimation.m:
--------------------------------------------------------------------------------
1 | /*
2 | SmoothViewAnimation.m
3 |
4 | Adapted from the smooth animation example in
5 | http://developer.apple.com/documentation/Cocoa/Conceptual/AnimationGuide/AnimationGuide.pdf
6 | This version caches the window in the new init method. It also no longer
7 | tweaks the window's origin. Used only vertically, it has not been tested
8 | with horizontal resizement.
9 |
10 | This file is in the public domain.
11 | */
12 |
13 | #import
14 |
15 | #import "SmoothViewAnimation.h"
16 |
17 | @implementation SmoothViewAnimation
18 |
19 | // initWithViewAnimations:
20 | // ----------------------------------------------------------------------------
21 |
22 | - (id)initWithViewAnimations: (NSArray*)viewAnimations
23 | {
24 | if ((self = [super initWithViewAnimations: viewAnimations]))
25 | {
26 | // Find the first window object in the array.
27 | uint32_t numAnimations = (uint32_t)[viewAnimations count];
28 | uint32_t i;
29 | id object;
30 | Class windowClass = [NSWindow class];
31 |
32 | for (i = 0; i < numAnimations; i++)
33 | {
34 | object = [[viewAnimations objectAtIndex: i]
35 | objectForKey: NSViewAnimationTargetKey];
36 |
37 | if ([object isKindOfClass: windowClass])
38 | {
39 | iWindow = object;
40 | break;
41 | }
42 | }
43 | }
44 |
45 | return self;
46 | }
47 |
48 | // setCurrentProgress:
49 | // ----------------------------------------------------------------------------
50 |
51 | - (void)setCurrentProgress: (NSAnimationProgress)progress
52 | {
53 | // Call super to update the progress value.
54 | [super setCurrentProgress: progress];
55 |
56 | if (!iWindow) // can't do much without a window
57 | return;
58 |
59 | // Update the window position. As stupid as this looks, [mWindow display]
60 | // just doesn't cut it.
61 | [iWindow setFrame: [iWindow frame] display: YES animate: YES];
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/src/source/Categories/Object64Loader.h:
--------------------------------------------------------------------------------
1 | /*
2 | Object64Loader.h
3 |
4 | A category on Exe64Processor that contains all the loadXXX methods.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe64Processor.h"
12 |
13 | @interface Exe64Processor(Object64Loader)
14 |
15 | - (BOOL)loadMachHeader;
16 | - (void)loadLCommands;
17 | - (void)loadObjcClassList;
18 | - (void)loadSegment: (segment_command_64*)inSegPtr;
19 | - (void)loadSymbols: (symtab_command*)inSymPtr;
20 | - (void)loadCStringSection: (section_64*)inSect;
21 | - (void)loadNSStringSection: (section_64*)inSect;
22 | - (void)loadLit4Section: (section_64*)inSect;
23 | - (void)loadLit8Section: (section_64*)inSect;
24 | - (void)loadTextSection: (section_64*)inSect;
25 | - (void)loadCoalTextSection: (section_64*)inSect;
26 | - (void)loadCoalTextNTSection: (section_64*)inSect;
27 | - (void)loadConstTextSection: (section_64*)inSect;
28 | - (void)loadObjcMethnameSection: (section_64*)inSect;
29 | - (void)loadObjcMethtypeSection: (section_64*)inSect;
30 | - (void)loadObjcClassnameSection: (section_64*)inSect;
31 | - (void)loadDataSection: (section_64*)inSect;
32 | - (void)loadCoalDataSection: (section_64*)inSect;
33 | - (void)loadCoalDataNTSection: (section_64*)inSect;
34 | - (void)loadConstDataSection: (section_64*)inSect;
35 | - (void)loadDyldDataSection: (section_64*)inSect;
36 | - (void)loadCFStringSection: (section_64*)inSect;
37 | - (void)loadNonLazySymbolSection: (section_64*)inSect;
38 | - (void)loadImpPtrSection: (section_64*)inSect;
39 | - (void)loadObjcClassListSection: (section_64*)inSect;
40 | - (void)loadObjcCatListSection: (section_64*)inSect;
41 | - (void)loadObjcConstSection: (section_64*)inSect;
42 | - (void)loadObjcProtoListSection: (section_64*)inSect;
43 | - (void)loadObjcSuperRefsSection: (section_64*)inSect;
44 | - (void)loadObjcClassRefsSection: (section_64*)inSect;
45 | - (void)loadObjcProtoRefsSection: (section_64*)inSect;
46 | - (void)loadObjcMsgRefsSection: (section_64*)inSect;
47 | - (void)loadObjcSelRefsSection: (section_64*)inSect;
48 | - (void)loadObjcDataSection: (section_64*)inSect;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/src/source/DropBox.h:
--------------------------------------------------------------------------------
1 | /*
2 | DropBox.h
3 |
4 | A subclass of NSBox that implements drag n drop. Drag hiliting mimics
5 | NSTextField's focus border.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | // Keep these <= 255 please.
13 | #define kBorderWidth 6
14 | #define kTexturedBorderWidth 7
15 |
16 | #define kFillAlpha 0.06f
17 |
18 | // Alpha values for each one-pixel frame, from outer to inner. The
19 | // outermost frame(s) overlay NSBox's border.
20 | static const float gAlphas[4][kBorderWidth] =
21 | {{0.9f, 0.7f, 0.5f, 0.3f, 0.2f, 0.0f}, // NSNoBorder
22 | {0.4f, 0.9f, 0.6f, 0.3f, 0.2f, 0.0f}, // NSLineBorder
23 | {0.4f, 0.4f, 0.8f, 0.6f, 0.4f, 0.2f}, // NSBezelBorder
24 | {0.4f, 0.4f, 0.8f, 0.6f, 0.4f, 0.2f}}; // NSGrooveBorder
25 |
26 | // Textured windows require a bit more.
27 | static const float gTexturedAlphas[4][kTexturedBorderWidth] =
28 | {{1.0f, 0.9f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f}, // NSNoBorder
29 | {0.4f, 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f}, // NSLineBorder
30 | {0.4f, 0.4f, 1.0f, 0.8f, 0.6f, 0.4f, 0.2f}, // NSBezelBorder
31 | {0.4f, 0.4f, 1.0f, 0.8f, 0.6f, 0.4f, 0.2f}}; // NSGrooveBorder
32 |
33 | // Leopard textured windows require a bit less.
34 | static const float gLeopardTexturedAlphas[4][kTexturedBorderWidth] =
35 | {{1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f, 0.0f}, // NSNoBorder
36 | {0.4f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f, 0.0f}, // NSLineBorder
37 | {0.4f, 0.4f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f}, // NSBezelBorder
38 | {0.4f, 0.4f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f}}; // NSGrooveBorder
39 |
40 | // ============================================================================
41 |
42 | @interface DropBox : NSBox
43 | {
44 | IBOutlet id iDelegate;
45 |
46 | BOOL iShowHilite;
47 | BOOL iFillRect;
48 | }
49 |
50 | - (void)setFillsRect: (BOOL)inFill;
51 |
52 | @end
53 |
54 | @interface NSObject(DropBoxDelegate)
55 |
56 | - (NSDragOperation)dropBox: (DropBox*)inDropBox
57 | dragDidEnter: (id )inItem;
58 | - (void)dropBox: (DropBox*)inDropBox
59 | dragDidExit: (id )inItem;
60 | - (BOOL)dropBox: (DropBox*)inDropBox
61 | didReceiveItem: (id )inItem;
62 |
63 | @end
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/toc_closed.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 | otx Help: TOC
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | otx Help
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Preferences
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Overview/toc_closed.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 | otx Help: TOC
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | otx Help
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Contents
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/source/Categories/ObjectLoader.h:
--------------------------------------------------------------------------------
1 | /*
2 | ObjectLoader.h
3 |
4 | A category on Exe32Processor that contains all the loadXXX methods.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe32Processor.h"
12 |
13 | @interface Exe32Processor(ObjectLoader)
14 |
15 | - (BOOL)loadMachHeader;
16 | - (void)loadLCommands;
17 | - (void)loadSegment: (segment_command*)inSegPtr;
18 | - (void)loadSymbols: (symtab_command*)inSymPtr;
19 | - (void)loadObjcSection: (section*)inSect;
20 | - (void)loadObjcModules;
21 | - (void)loadObjcClassList;
22 | - (void)loadCStringSection: (section*)inSect;
23 | - (void)loadNSStringSection: (section*)inSect;
24 | - (void)loadClassSection: (section*)inSect;
25 | - (void)loadMetaClassSection: (section*)inSect;
26 | - (void)loadIVarSection: (section*)inSect;
27 | - (void)loadObjcModSection: (section*)inSect;
28 | - (void)loadObjcSymSection: (section*)inSect;
29 | - (void)loadObjcMethnameSection: (section*)inSect;
30 | - (void)loadObjcMethtypeSection: (section*)inSect;
31 | - (void)loadObjcClassnameSection: (section*)inSect;
32 | - (void)loadLit4Section: (section*)inSect;
33 | - (void)loadLit8Section: (section*)inSect;
34 | - (void)loadTextSection: (section*)inSect;
35 | - (void)loadCoalTextSection: (section*)inSect;
36 | - (void)loadCoalTextNTSection: (section*)inSect;
37 | - (void)loadConstTextSection: (section*)inSect;
38 | - (void)loadDataSection: (section*)inSect;
39 | - (void)loadCoalDataSection: (section*)inSect;
40 | - (void)loadCoalDataNTSection: (section*)inSect;
41 | - (void)loadConstDataSection: (section*)inSect;
42 | - (void)loadDyldDataSection: (section*)inSect;
43 | - (void)loadCFStringSection: (section*)inSect;
44 | - (void)loadNonLazySymbolSection: (section*)inSect;
45 | - (void)loadObjcClassListSection: (section*)inSect;
46 | - (void)loadObjcCatListSection: (section*)inSect;
47 | - (void)loadObjcConstSection: (section*)inSect;
48 | - (void)loadObjcProtoListSection: (section*)inSect;
49 | - (void)loadObjcSuperRefsSection: (section*)inSect;
50 | - (void)loadObjcClassRefsSection: (section*)inSect;
51 | - (void)loadObjcProtoRefsSection: (section*)inSect;
52 | - (void)loadObjcMsgRefsSection: (section*)inSect;
53 | - (void)loadObjcSelRefsSection: (section*)inSect;
54 | - (void)loadObjcDataSection: (section*)inSect;
55 | - (void)loadImpPtrSection: (section*)inSect;
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/src/source/Categories/Searchers64.m:
--------------------------------------------------------------------------------
1 | /*
2 | Searchers64.m
3 |
4 | A category on Exe64Processor that contains the various binary search
5 | methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Searchers64.h"
13 |
14 | @implementation Exe64Processor(Searchers64)
15 |
16 | // findSymbolByAddress:
17 | // ----------------------------------------------------------------------------
18 |
19 | - (char*)findSymbolByAddress: (uint64_t)inAddress
20 | {
21 | if (!iFuncSyms)
22 | return NO;
23 |
24 | nlist_64 searchKey = {{0}, 0, 0, 0, inAddress};
25 | nlist_64* symbol = bsearch(&searchKey,
26 | iFuncSyms, iNumFuncSyms, sizeof(nlist_64),
27 | (COMPARISON_FUNC_TYPE)Sym_Compare_64);
28 |
29 | if (symbol)
30 | return (char*)((char *)iMachHeaderPtr + iStringTableOffset + symbol->n_un.n_strx);
31 | else
32 | return NULL;
33 | }
34 |
35 | // findClassMethod:byAddress:
36 | // ----------------------------------------------------------------------------
37 |
38 | - (BOOL)findClassMethod: (Method64Info**)outMI
39 | byAddress: (UInt64)inAddress;
40 | {
41 | if (!outMI)
42 | return NO;
43 |
44 | if (!iClassMethodInfos)
45 | {
46 | *outMI = NULL;
47 | return NO;
48 | }
49 |
50 | Method64Info searchKey = {{0, 0, inAddress}, {0}, NO};
51 |
52 | *outMI = bsearch(&searchKey,
53 | iClassMethodInfos, iNumClassMethodInfos, sizeof(Method64Info),
54 | (COMPARISON_FUNC_TYPE)
55 | (iSwapped ? Method64Info_Compare_Swapped : Method64Info_Compare));
56 |
57 | return (*outMI != NULL);
58 | }
59 |
60 | // findIvar:inClass:withOffset:
61 | // ----------------------------------------------------------------------------
62 | // TODO: keep a sorted list of ClassInfo's, where each ClassInfo keeps a sorted
63 | // list of objc2_ivar_t's.
64 |
65 | - (BOOL)findIvar: (objc2_64_ivar_t**)outIvar
66 | inClass: (objc2_64_class_t*)inClass
67 | withOffset: (UInt64)inOffset
68 | {
69 | if (!inClass || !outIvar)
70 | return NO;
71 |
72 | objc2_64_ivar_t searchKey = {inOffset, 0, 0, 0, 0};
73 |
74 | *outIvar = bsearch(&searchKey, iClassIvars, iNumClassIvars, sizeof(objc2_64_ivar_t),
75 | (COMPARISON_FUNC_TYPE)objc2_64_ivar_t_Compare);
76 |
77 | return (*outIvar != NULL);
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/src/source/Processors/X86Processor.h:
--------------------------------------------------------------------------------
1 | /*
2 | X86Processor.h
3 |
4 | A subclass of Exe32Processor that handles x86-specific issues.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe32Processor.h"
12 | #import "Deobfuscator.h"
13 |
14 | // Addressing modes in mod field of mod r/m byte.
15 | // See table 2.2 in the Pentium manual.
16 | #define MODimm 0 // [reg]
17 | #define MOD8 1 // [reg] + disp8
18 | #define MOD32 2 // [reg] + disp32
19 | #define MODx 3 // ignored
20 |
21 | // Addressing modes in r/m field of mod r/m byte.
22 | // See table 2.2 in the Pentium manual.
23 | #define DISP32 5 // disp32 when mod == 0
24 |
25 | // Register identifiers in r/m field of mod r/m byte
26 | enum {
27 | NO_REG = -1,
28 | EAX, // 0
29 | ECX, // 1
30 | EDX, // 2
31 | EBX, // 3
32 | ESP, // 4
33 | EBP, // 5
34 | ESI, // 6
35 | EDI // 7
36 | };
37 |
38 | // Macros for various x86 data
39 | #define LO(x) ((x) & 0xf) // bits 0-3
40 | #define HI(x) (((x) >> 4) & 0xf) // bits 4-7
41 | //#define DIR(x) (((x) >> 1) & 0x1) // bit 1
42 | #define MOD(x) (((x) >> 6) & 0x3) // bits 6-7
43 | #define REG1(x) (((x) >> 3) & 0x7) // bits 3-5
44 | #define REG2(x) ((x) & 0x7) // bits 0-2
45 | #define OPEXT(x) REG1((x))
46 | #define RM(x) REG2((x))
47 | #define HAS_SIB(x) (MOD((x)) != MODx && REG2((x)) == ESP)
48 | #define HAS_DISP8(x) (MOD((x)) == MOD8)
49 | #define HAS_REL_DISP32(x) (MOD((x)) == MOD32)
50 | #define HAS_ABS_DISP32(x) (MOD((x)) == MODimm && REG2((x)) == EBP)
51 |
52 | #define IS_JUMP(o, so) \
53 | ((o) == 0xe3 || (o) == 0xe9 || (o) == 0xeb || (o) == 0xc3 || \
54 | ((o) >= 0x71 && (o) <= 0x7f) || \
55 | ((o) == 0x0f && (so) >= 0x81 && (so) <= 0x8f))
56 | #define IS_CALL(o) ((o) == 0xe8)
57 | #define IS_RET(o) ((o) == 0xc3)
58 |
59 | // ============================================================================
60 |
61 | @interface X86Processor : Exe32Processor
62 | {
63 | GPRegisterInfo iStack[MAX_STACK_SIZE];
64 | GPRegisterInfo iRegInfos[8];
65 |
66 | VarInfo* iLocalSelves; // 'self' copied to local variables
67 | uint32_t iNumLocalSelves;
68 | VarInfo* iLocalVars;
69 | uint32_t iNumLocalVars;
70 | }
71 |
72 | - (void) printCurrentState: (uint32_t)currentAddress;
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Overview/chapter_1_section_1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | otx Help
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | otx
16 | Help
17 | otx
18 | stands for "object tool extended". otx uses otool(object tool) to
19 | disassemble a Mach-O executable file, then enhances the disassembled
20 | output. Simple enhancements include adding the machine code of each
21 | instruction as well as the offset of each instruction from the
22 | beginning of a function. More complicated enhancements include
23 | displaying the names of ObjC methods even if symbols have been
24 | stripped, and adding comments that describe member variables, function
25 | calls, static data and more.
26 |
27 |
28 |
29 | otx can open almost
30 | any Mach-O executable file you're likely to use- PPC or x86, single
31 | architecture or universal binary. When you open a universal binary, the
32 | popup menu show above allows you to select which architecture to
33 | disassemble. If you have lipo installed, you can easily separate the
34 | selected architecture using the "Thin" button.
35 |
36 | If you have obfuscated
37 | your code, you may find that otool's disassembly is less than desirable.
38 | To assist you, otx includes a very basic deobfuscator. By using the
39 | "Verify" button shown above, you can verify that otool will be able to
40 | correctly disassemble your executable. If this verification fails, otx
41 | will ask if you would like to save a deobfuscated copy of your executable.
42 | Should you choose to do so, the deobfuscated copy will be automatically
43 | opened for further processing. Currently, deobfuscation is only necessary
44 | for x86 executables.
45 |
46 | Refer to these sections:
47 |
48 |
49 |
50 | Specifying files to analyze.
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/source/Categories/ArchSpecifics.m:
--------------------------------------------------------------------------------
1 | /*
2 | ArchSpecifics.m
3 |
4 | A category on Exe32Processor that contains most of the
5 | architecture-specific methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "ArchSpecifics.h"
13 |
14 | @implementation Exe32Processor(ArchSpecifics)
15 |
16 | // gatherFuncInfos
17 | // ----------------------------------------------------------------------------
18 |
19 | - (void)gatherFuncInfos
20 | {}
21 |
22 | // postProcessCodeLine:
23 | // ----------------------------------------------------------------------------
24 |
25 | - (void)postProcessCodeLine: (Line**)ioLine
26 | {}
27 |
28 | // lineIsFunction:
29 | // ----------------------------------------------------------------------------
30 |
31 | - (BOOL)lineIsFunction: (Line*)inLine
32 | {
33 | return NO;
34 | }
35 |
36 | // codeIsBlockJump:
37 | // ----------------------------------------------------------------------------
38 |
39 | - (BOOL)codeIsBlockJump: (UInt8*)inCode
40 | {
41 | return NO;
42 | }
43 |
44 | // codeFromLine:
45 | // ----------------------------------------------------------------------------
46 |
47 | - (void)codeFromLine: (Line*)inLine
48 | {}
49 |
50 | // checkThunk:
51 | // ----------------------------------------------------------------------------
52 |
53 | - (void)checkThunk:(Line*)inLine
54 | {}
55 |
56 | // getThunkInfo:forLine:
57 | // ----------------------------------------------------------------------------
58 |
59 | - (BOOL)getThunkInfo: (ThunkInfo*)outInfo
60 | forLine: (Line*)inLine
61 | {
62 | return NO;
63 | }
64 |
65 | #pragma mark -
66 | // commentForLine:
67 | // ----------------------------------------------------------------------------
68 |
69 | - (void)commentForLine: (Line*)inLine
70 | {}
71 |
72 | // commentForSystemCall
73 | // ----------------------------------------------------------------------------
74 |
75 | - (void)commentForSystemCall
76 | {}
77 |
78 | // commentForMsgSend:fromLine:
79 | // ----------------------------------------------------------------------------
80 |
81 | - (void)commentForMsgSend: (char*)ioComment
82 | fromLine: (Line*)inLine
83 | {}
84 |
85 | #pragma mark -
86 | // resetRegisters:
87 | // ----------------------------------------------------------------------------
88 |
89 | - (void)resetRegisters: (Line*)inLine
90 | {}
91 |
92 | // updateRegisters:
93 | // ----------------------------------------------------------------------------
94 |
95 | - (void)updateRegisters: (Line*)inLine
96 | {}
97 |
98 | // restoreRegisters:
99 | // ----------------------------------------------------------------------------
100 |
101 | - (BOOL)restoreRegisters: (Line*)ioLine
102 | {
103 | return NO;
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/src/source/Categories/Arch64Specifics.m:
--------------------------------------------------------------------------------
1 | /*
2 | Arch64Specifics.m
3 |
4 | A category on Exe64Processor that contains most of the
5 | architecture-specific methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Arch64Specifics.h"
13 |
14 | @implementation Exe64Processor(Arch64Specifics)
15 |
16 | // gatherFuncInfos
17 | // ----------------------------------------------------------------------------
18 |
19 | - (void)gatherFuncInfos
20 | {}
21 |
22 | // postProcessCodeLine:
23 | // ----------------------------------------------------------------------------
24 |
25 | - (void)postProcessCodeLine: (Line64**)ioLine
26 | {}
27 |
28 | // lineIsFunction:
29 | // ----------------------------------------------------------------------------
30 |
31 | - (BOOL)lineIsFunction: (Line64*)inLine
32 | {
33 | return NO;
34 | }
35 |
36 | // codeIsBlockJump:
37 | // ----------------------------------------------------------------------------
38 |
39 | - (BOOL)codeIsBlockJump: (UInt8*)inCode
40 | {
41 | return NO;
42 | }
43 |
44 | // codeFromLine:
45 | // ----------------------------------------------------------------------------
46 |
47 | - (void)codeFromLine: (Line64*)inLine
48 | {}
49 |
50 | // checkThunk:
51 | // ----------------------------------------------------------------------------
52 |
53 | - (void)checkThunk:(Line64*)inLine
54 | {}
55 |
56 | // getThunkInfo:forLine:
57 | // ----------------------------------------------------------------------------
58 |
59 | - (BOOL)getThunkInfo: (ThunkInfo*)outInfo
60 | forLine: (Line64*)inLine
61 | {
62 | return NO;
63 | }
64 |
65 | #pragma mark -
66 | // commentForLine:
67 | // ----------------------------------------------------------------------------
68 |
69 | - (void)commentForLine: (Line64*)inLine
70 | {}
71 |
72 | // commentForSystemCall
73 | // ----------------------------------------------------------------------------
74 |
75 | - (void)commentForSystemCall
76 | {}
77 |
78 | // commentForMsgSend:fromLine:
79 | // ----------------------------------------------------------------------------
80 |
81 | - (void)commentForMsgSend: (char*)ioComment
82 | fromLine: (Line64*)inLine
83 | {}
84 |
85 | #pragma mark -
86 | // resetRegisters:
87 | // ----------------------------------------------------------------------------
88 |
89 | - (void)resetRegisters: (Line64*)inLine
90 | {}
91 |
92 | // updateRegisters:
93 | // ----------------------------------------------------------------------------
94 |
95 | - (void)updateRegisters: (Line64*)inLine
96 | {}
97 |
98 | // restoreRegisters:
99 | // ----------------------------------------------------------------------------
100 |
101 | - (BOOL)restoreRegisters: (Line64*)ioLine
102 | {
103 | return NO;
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Overview/toc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 | otx Help: TOC
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | otx Help
46 |
47 |
48 |
49 |
50 | Specifying files to analyze
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Preferences
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/src/source/Categories/SysUtils.m:
--------------------------------------------------------------------------------
1 | /*
2 | SysUtils.m
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 | #import
9 |
10 | #import "SystemIncludes.h" // for UTF8STRING()
11 | #import "SysUtils.h"
12 |
13 | @implementation NSObject(SysUtils)
14 |
15 | // checkOtool:
16 | // ----------------------------------------------------------------------------
17 |
18 | - (BOOL)checkOtool: (NSString*)filePath
19 | {
20 | NSString* otoolPath = [self pathForTool: @"otool"];
21 | NSTask* otoolTask = [[[NSTask alloc] init] autorelease];
22 | NSPipe* silence = [NSPipe pipe];
23 |
24 | [otoolTask setLaunchPath: otoolPath];
25 | [otoolTask setStandardInput: [NSPipe pipe]];
26 | [otoolTask setStandardOutput: silence];
27 | [otoolTask setStandardError: silence];
28 | [otoolTask launch];
29 | [otoolTask waitUntilExit];
30 |
31 | return ([otoolTask terminationStatus] == 1);
32 | }
33 |
34 | // pathForTool:
35 | // ----------------------------------------------------------------------------
36 |
37 | - (NSString*)pathForTool: (NSString*)toolName
38 | {
39 | // Xcode 5+: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool
40 |
41 | NSString* relToolBase = [NSString pathWithComponents:
42 | [NSArray arrayWithObjects: @"/", @"usr", @"bin", nil]];
43 | NSString* relToolPath = [relToolBase stringByAppendingPathComponent: toolName];
44 |
45 | NSString* selectToolPath = [relToolBase stringByAppendingPathComponent: @"xcode-select"];
46 | NSTask* selectTask = [[[NSTask alloc] init] autorelease];
47 | NSPipe* selectPipe = [NSPipe pipe];
48 | NSArray* args = [NSArray arrayWithObject: @"--print-path"];
49 |
50 | [selectTask setLaunchPath: selectToolPath];
51 | [selectTask setArguments: args];
52 | [selectTask setStandardInput: [NSPipe pipe]];
53 | [selectTask setStandardOutput: selectPipe];
54 | [selectTask launch];
55 | [selectTask waitUntilExit];
56 |
57 | int selectStatus = [selectTask terminationStatus];
58 |
59 | if (selectStatus == -1)
60 | return relToolPath;
61 |
62 | NSData* selectData = [[selectPipe fileHandleForReading] availableData];
63 | NSString* absToolPath = [[[NSString alloc] initWithBytes: [selectData bytes]
64 | length: [selectData length]
65 | encoding: NSUTF8StringEncoding] autorelease];
66 |
67 | absToolPath = [[[[absToolPath stringByTrimmingCharactersInSet:
68 | [NSCharacterSet whitespaceAndNewlineCharacterSet]]
69 | stringByAppendingPathComponent: @"Toolchains"]
70 | stringByAppendingPathComponent: @"XcodeDefault.xctoolchain"]
71 | stringByAppendingPathComponent: relToolPath];
72 |
73 | if (![[NSFileManager defaultManager] fileExistsAtPath:absToolPath]) {
74 | return relToolPath;
75 | }
76 |
77 | return absToolPath;
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/src/source/StolenDefs.h:
--------------------------------------------------------------------------------
1 | /*
2 | StolenDefs.h
3 |
4 | Definitions stolen from, or inspired by, Darwin & cctools.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #define rotr(x, n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
10 | #define rotl(x, n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
11 | #define rotr64(x, n) (((x) >> ((int)(n))) | ((x) << (64 - (int)(n))))
12 | #define rotl64(x, n) (((x) << ((int)(n))) | ((x) >> (64 - (int)(n))))
13 |
14 | /* section_info
15 | */
16 | typedef struct
17 | {
18 | section s;
19 | char* contents;
20 | uint32_t size;
21 | }
22 | section_info;
23 |
24 | typedef struct
25 | {
26 | section_64 s;
27 | char* contents;
28 | uint64_t size;
29 | }
30 | section_info_64;
31 |
32 | /* dyld_data_section
33 |
34 | Adapted from
35 | http://www.opensource.apple.com/darwinsource/10.4.7.ppc/cctools-590.23.6/libdyld/debug.h
36 | */
37 | typedef struct
38 | {
39 | void* stub_binding_helper_interface;
40 | void* _dyld_func_lookup;
41 | void* start_debug_thread;
42 | mach_port_t debug_port;
43 | thread_port_t debug_thread;
44 | void* dyld_stub_binding_helper;
45 | // unsigned long core_debug; // wrong size and ignored by us anyway
46 | }
47 | dyld_data_section;
48 |
49 |
50 |
51 | /* NSString
52 |
53 | From cctools-590/otool/print_objc.c, alternate definition in
54 | http://www.opensource.apple.com/darwinsource/10.4.7.ppc/objc4-267.1/runtime/objc-private.h
55 | */
56 | typedef struct {
57 | uint32_t isa; /* objc_class * */
58 | uint32_t chars; /* char * */
59 | uint32_t length; /* unsigned int */
60 | } nxstring_object;
61 |
62 | typedef struct {
63 | uint64_t isa; /* objc_class * */
64 | uint64_t chars; /* char * */
65 | uint32_t length; /* unsigned int */
66 | } nxstring_object_64;
67 |
68 |
69 | /* CFString
70 |
71 | The only piece of reverse-engineered data in otx. I was unable to find any
72 | documentation about the structure of CFStrings, but they appear to be
73 | NSStrings with an extra data member prepended. Following NSString's lead,
74 | i'm calling it 'isa'. The observed values of 'isa' change from app to app,
75 | but remain constant in each app. A little gdb effort could probably shed
76 | some light on what they actually point to, but otx has nothing to gain from
77 | that knowledge. Still, any feedback regarding this issue is most welcome.
78 | */
79 | typedef struct {
80 | uint32_t isa;
81 | nxstring_object oc_string;
82 | } cfstring_object;
83 |
84 | typedef struct {
85 | uint64_t isa;
86 | nxstring_object_64 oc_string;
87 | } cfstring_object_64;
88 |
89 |
90 |
91 |
92 | /* The isa field of an NSString is 0x7c8 (1992) when it exists in the
93 | (__DATA,__const) section. This makes it possible to identify both
94 | NSString's and CFString's. I can't find any documentation about the
95 | 1992 date, but it is assumed to be the date of birth of NSStrings.
96 | */
97 | #define typeid_NSString 0x000007c8
98 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/chapter_2_section_1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | otx Help: Preferences
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Preferences
17 |
18 | Refer to these sections:
19 |
20 |
21 |
22 | Show local offsets
23 |
24 |
25 |
26 | Show data sections
27 |
28 |
29 |
30 | Entab output
31 |
32 |
33 |
34 | Show md5 checksum
35 |
36 |
37 |
38 | Demangle names
39 |
40 |
41 |
42 | Show method types
43 |
44 |
45 |
46 | Show variable types
47 |
48 |
49 |
50 | Filename
51 |
52 |
53 |
54 | Location
55 |
56 |
57 | Open file with application
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/source/DropBox.m:
--------------------------------------------------------------------------------
1 | /*
2 | DropBox.m
3 |
4 | A subclass of NSBox that implements drag n drop. Drag hiliting mimics
5 | NSTextField's focus border.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "DropBox.h"
13 |
14 | @implementation DropBox
15 |
16 | // awakeFromNib
17 | // ----------------------------------------------------------------------------
18 |
19 | - (void)awakeFromNib
20 | {
21 | [self registerForDraggedTypes:
22 | [NSArray arrayWithObject: NSFilenamesPboardType]];
23 | }
24 |
25 | // setFillsRect:
26 | // ----------------------------------------------------------------------------
27 | // Call setFillsRect: YES to draw the entire frame hilited with kFillAlpha.
28 |
29 | - (void)setFillsRect: (BOOL)inFill
30 | {
31 | iFillRect = inFill;
32 | }
33 |
34 | // draggingEntered:
35 | // ----------------------------------------------------------------------------
36 |
37 | - (NSDragOperation)draggingEntered: (id)sender
38 | {
39 | NSDragOperation dragOp = NSDragOperationNone;
40 |
41 | if (iDelegate && [iDelegate respondsToSelector:
42 | @selector(dropBox:dragDidEnter:)])
43 | dragOp = [iDelegate dropBox: self dragDidEnter: sender];
44 |
45 | if (dragOp == NSDragOperationNone)
46 | return dragOp;
47 |
48 | iShowHilite = YES;
49 | [self setNeedsDisplay: YES];
50 |
51 | return dragOp;
52 | }
53 |
54 | // draggingExited:
55 | // ----------------------------------------------------------------------------
56 |
57 | - (void)draggingExited: (id)sender
58 | {
59 | iShowHilite = NO;
60 | [self setNeedsDisplay: YES];
61 |
62 | if (iDelegate && [iDelegate respondsToSelector:
63 | @selector(dropBox:dragDidExit:)])
64 | [iDelegate dropBox: self dragDidExit: sender];
65 | }
66 |
67 | // performDragOperation:
68 | // ----------------------------------------------------------------------------
69 |
70 | - (BOOL)performDragOperation: (id)sender
71 | {
72 | iShowHilite = NO;
73 | [self setNeedsDisplay: YES];
74 |
75 | if (!iDelegate)
76 | return NO;
77 |
78 | if ([iDelegate respondsToSelector: @selector(dropBox:didReceiveItem:)])
79 | return [iDelegate dropBox: self didReceiveItem: sender];
80 |
81 | return NO;
82 | }
83 |
84 | // drawRect:
85 | // ----------------------------------------------------------------------------
86 |
87 | - (void)drawRect: (NSRect)rect
88 | {
89 | [super drawRect: rect];
90 |
91 | if (!iShowHilite)
92 | return;
93 |
94 | NSBorderType borderType = [self borderType];
95 |
96 | if (borderType > 3)
97 | {
98 | fprintf(stderr, "DropBox: invalid NSBorderType: %lu\n", borderType);
99 | return;
100 | }
101 |
102 | NSWindow* window = [self window];
103 | UInt8 borderWidth;
104 | BOOL isTextured;
105 |
106 | if (window && ([window styleMask] & NSTexturedBackgroundWindowMask))
107 | {
108 | isTextured = YES;
109 | borderWidth = kTexturedBorderWidth;
110 | }
111 | else
112 | {
113 | isTextured = NO;
114 | borderWidth = kBorderWidth;
115 | }
116 |
117 | NSRect innerRect = rect;
118 | NSColor* baseColor = [NSColor keyboardFocusIndicatorColor];
119 | NSColor* color;
120 | UInt8 i;
121 |
122 | for (i = 0; i < borderWidth; i++)
123 | {
124 | color = [baseColor colorWithAlphaComponent: (isTextured) ?
125 | ((OS_IS_POST_TIGER) ? gLeopardTexturedAlphas[borderType][i] :
126 | gTexturedAlphas[borderType][i]) : gAlphas[borderType][i]];
127 | [color set];
128 | NSFrameRectWithWidthUsingOperation(
129 | innerRect, 1.0f, NSCompositeSourceOver);
130 | innerRect = NSInsetRect(innerRect, 1.0f, 1.0f);
131 | }
132 |
133 | if (iFillRect)
134 | {
135 | if (borderType == NSNoBorder || borderType == NSLineBorder)
136 | innerRect = NSInsetRect(innerRect, -1.0f, -1.0f);
137 |
138 | color = [baseColor colorWithAlphaComponent: kFillAlpha];
139 | [color set];
140 | NSRectFillUsingOperation(innerRect, NSCompositeSourceOver);
141 | }
142 | }
143 |
144 | @end
145 |
--------------------------------------------------------------------------------
/src/source/Processors/PPCProcessor.h:
--------------------------------------------------------------------------------
1 | /*
2 | PPCProcessor.h
3 |
4 | A subclass of ExeProcessor that handles PPC-specific issues.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Exe32Processor.h"
12 |
13 | // from cctools-590/otool/ppc-disasm.c
14 | // The various macros defined in that file get their names from the field
15 | // naming conventions given in the PowerPC Programming Environments Manual
16 | // available at http://www.freescale.com
17 | #define RT(x) (((x) >> 21) & 0x1f) // bits 21 - 25
18 | #define RA(x) (((x) >> 16) & 0x1f) // bits 16 - 20
19 | #define RB(x) (((x) >> 11) & 0x1f) // bits 11 - 15
20 | #define MB(x) (((x) >> 6) & 0x1f) // bits 6 - 10
21 | #define ME(x) (((x) >> 1) & 0x1f) // bits 1 - 5
22 | #define SV(x) ((x) & 0x1f) // bits 0 - 4 "Shift Value"
23 | #define SB(x) ((x) & 0x20) // bit 5 "Shift Bit"
24 | #define BO(x) RT((x))
25 | #define RS(x) RT((x))
26 |
27 | // otool masks the entire instruction with 0xfc000000, rather than accessing
28 | // the primary opcode field directly. Maybe this is to help each case in a
29 | // switch statement stand out, maybe it's faster, who knows... I define a
30 | // PO macro here, and use the values given in the PEM. The SO macro accesses
31 | // the unnamed 10-bit field that specifies secondary opcodes in an instruction
32 | // of the XO(extended operand) form. The SPR macro accesses the "special
33 | // register" field of mfspr and mtspr instructions(LR, CTR). SIMM and UIMM
34 | // access the signed and unsigned immediate values.
35 | #define PO(x) (((x) >> 26) & 0x3f) // bits 26 - 31
36 | #define SO(x) (((x) >> 1) & 0x3ff) // bits 1 - 10
37 | #define SPR(x) ((((x) >> 6) & 0x3e0) | (((x) >> 16) & 0x1f))
38 | #define UIMM(x) ((x) & 0xffff) // bits 0 - 15
39 | #define SIMM(x) (SInt16)((x) & 0xffff) // bits 0 - 15
40 | #define AA(x) (((x) >> 1) & 0x1) // bit 1
41 | #define LK(x) ((x) & 0x1) // bit 0
42 | #define BD(x) (SInt16)((x) & 0xfffc) // bits 2 - 15
43 |
44 | // bits 2 - 25, sign extended
45 | #define LI(x) (SInt32) \
46 | (((x) & 0x02000000) ? \
47 | ((x) & 0x03fffffc) | 0xfc000000 : \
48 | ((x) & 0x03fffffc))
49 |
50 | // SPR values
51 | #define LR 8
52 | #define CTR 9
53 |
54 | // indices into MachineState.regInfos array
55 | #define LRIndex 32
56 | #define CTRIndex 33
57 |
58 | #define IS_BLOCK_BRANCH(i) \
59 | ((PO(i) == 0x10 || PO(i) == 0x12 || PO(i) == 0x13) && \
60 | (!AA(i) && !LK(i)))
61 |
62 | #define IS_BRANCH_LINK(i) \
63 | ((PO(i) == 0x10 && LK(i)) || \
64 | (PO(i) == 0x12 && LK(i)) || \
65 | (PO(i) == 0x13 && (i & 0x7ff) == 0x421))
66 |
67 | #define IS_BRANCH_CONDITIONAL(i) \
68 | (((PO((i)) == 0x13 && SO((i)) == 0x10) || (PO((i)) == 0x10)) \
69 | && (BO((i)) != 0x14))
70 |
71 | #define IS_BLR(i) ((i) == 0x4e800020)
72 |
73 | // Addresses and names of functions in the ObjC runtime page, stolen from
74 | // http://www.opensource.apple.com/darwinsource/10.4.7.ppc/objc4-267.1/runtime/objc-rtp.h
75 |
76 | #define kRTAddress_objc_msgSend 0xfffeff00
77 | #define kRTAddress_objc_assign_ivar 0xfffefec0
78 | #define kRTAddress_objc_assign_global 0xfffefeb0
79 | #define kRTAddress_objc_assign_strongCast 0xfffefea0
80 |
81 | #define kRTName_objc_msgSend "_objc_msgSend_rtp"
82 | #define kRTName_objc_assign_ivar "_objc_assign_ivar_rtp"
83 | #define kRTName_objc_assign_global "_objc_assign_global_rtp"
84 | #define kRTName_objc_assign_strongCast "_objc_assign_strongCast_rtp"
85 |
86 | // Addresses and names of some dyld routines, stolen from
87 | // http://www.opensource.apple.com/darwinsource/10.4.7.ppc/Csu-58/dyld.s
88 |
89 | #define kDyldAddress_LaSymBindingEntry 0x8fe01000
90 | #define kDyldAddress_FuncLookupPointer 0x8fe01008
91 |
92 | #define kDyldName_LaSymBindingEntry "dyld_lazy_symbol_binding_entry_point"
93 | #define kDyldName_FuncLookupPointer "dyld_func_lookup_pointer"
94 |
95 | // ============================================================================
96 |
97 | @interface PPCProcessor : Exe32Processor
98 | {
99 | GPRegisterInfo iRegInfos[32];
100 | GPRegisterInfo iLR;
101 | GPRegisterInfo iCTR;
102 |
103 | VarInfo* iLocalSelves; // 'self' copied to local variables
104 | uint32_t iNumLocalSelves;
105 | VarInfo* iLocalVars;
106 | uint32_t iNumLocalVars;
107 | }
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/src/source/Categories/ListUtils.m:
--------------------------------------------------------------------------------
1 | /*
2 | ListUtils.m
3 |
4 | A category on Exe32Processor for linked list manipulation.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "ListUtils.h"
12 |
13 | @implementation Exe32Processor(ListUtils)
14 |
15 | // Each text line is stored in an element of a doubly-linked list. These are
16 | // vanilla textbook funcs for maintaining the list.
17 |
18 | // insertLine:before:inList:
19 | // ----------------------------------------------------------------------------
20 |
21 | - (void)insertLine: (Line*)inLine
22 | before: (Line*)nextLine
23 | inList: (Line**)listHead
24 | {
25 | if (!nextLine)
26 | return;
27 |
28 | if (nextLine == *listHead)
29 | *listHead = inLine;
30 |
31 | inLine->prev = nextLine->prev;
32 | inLine->next = nextLine;
33 | nextLine->prev = inLine;
34 |
35 | if (inLine->prev)
36 | inLine->prev->next = inLine;
37 | }
38 |
39 | // insertLine:after:inList:
40 | // ----------------------------------------------------------------------------
41 |
42 | - (void)insertLine: (Line*)inLine
43 | after: (Line*)prevLine
44 | inList: (Line**)listHead
45 | {
46 | if (!prevLine)
47 | {
48 | *listHead = inLine;
49 | return;
50 | }
51 |
52 | inLine->next = prevLine->next;
53 | inLine->prev = prevLine;
54 | prevLine->next = inLine;
55 |
56 | if (inLine->next)
57 | inLine->next->prev = inLine;
58 | }
59 |
60 | // replaceLine:withLine:inList:
61 | // ----------------------------------------------------------------------------
62 | // This non-standard method is used for merging the verbose and plain lists.
63 |
64 | - (void)replaceLine: (Line*)inLine
65 | withLine: (Line*)newLine
66 | inList: (Line**)listHead
67 | {
68 | if (!inLine || !newLine)
69 | return;
70 |
71 | if (inLine == *listHead)
72 | *listHead = newLine;
73 |
74 | newLine->next = inLine->next;
75 | newLine->prev = inLine->prev;
76 |
77 | if (newLine->next)
78 | newLine->next->prev = newLine;
79 |
80 | if (newLine->prev)
81 | newLine->prev->next = newLine;
82 |
83 | if (inLine->chars)
84 | free(inLine->chars);
85 |
86 | free(inLine);
87 | }
88 |
89 | // printLinesFromList:
90 | // ----------------------------------------------------------------------------
91 | // Print our modified lines to a FILE*. The FILE* is a real file in the GUI
92 | // target, and stdout in the CLI target.
93 |
94 | - (BOOL)printLinesFromList: (Line*)listHead
95 | {
96 | FILE* outFile = NULL;
97 |
98 | // In the CLI target, mOutputFilePath is nil.
99 | if (iOutputFilePath)
100 | {
101 | const char* outPath = UTF8STRING(iOutputFilePath);
102 | outFile = fopen(outPath, "w");
103 | }
104 | else
105 | outFile = stdout;
106 |
107 | if (!outFile)
108 | {
109 | perror("otx: unable to open output file");
110 | return NO;
111 | }
112 |
113 | Line* theLine = listHead;
114 |
115 | // Cache the fileno and use SYS_write for maximum speed.
116 | SInt32 fileNum = fileno(outFile);
117 |
118 | while (theLine)
119 | {
120 | if (syscall(SYS_write, fileNum, theLine->chars, theLine->length) == -1)
121 | {
122 | perror("otx: unable to write to output file");
123 |
124 | if (iOutputFilePath)
125 | {
126 | if (fclose(outFile) != 0)
127 | perror("otx: unable to close output file");
128 | }
129 |
130 | return NO;
131 | }
132 |
133 | theLine = theLine->next;
134 | }
135 |
136 | if (iOutputFilePath)
137 | {
138 | if (fclose(outFile) != 0)
139 | {
140 | perror("otx: unable to close output file");
141 | return NO;
142 | }
143 | }
144 |
145 | return YES;
146 | }
147 |
148 | // deleteLinesFromList:
149 | // ----------------------------------------------------------------------------
150 |
151 | - (void)deleteLinesFromList: (Line*)listHead
152 | {
153 | Line* theLine = listHead;
154 |
155 | while (theLine)
156 | {
157 | if (theLine->prev) // If there's one behind us...
158 | {
159 | free(theLine->prev->chars); // delete it.
160 | free(theLine->prev);
161 | }
162 |
163 | if (theLine->next) // If there are more...
164 | theLine = theLine->next; // jump to next one and continue.
165 | else
166 | { // This is the last one, delete it.
167 | free(theLine->chars);
168 | free(theLine);
169 | theLine = NULL;
170 | }
171 | }
172 | }
173 |
174 | // deleteLinesBefore:fromList:
175 | // ----------------------------------------------------------------------------
176 |
177 | - (void)deleteLinesBefore: (Line*)inLine
178 | fromList: (Line**)listHead
179 | {
180 | Line* theLine = *listHead;
181 |
182 | while (theLine)
183 | {
184 | if (theLine->prev) // If there's one behind us...
185 | {
186 | free(theLine->prev->chars); // delete it.
187 | free(theLine->prev);
188 | }
189 |
190 | if (theLine->next && theLine->next != inLine) // If there are more...
191 | theLine = theLine->next; // jump to next one and continue.
192 | else
193 | { // This is the last one, delete it.
194 | free(theLine->chars);
195 | free(theLine);
196 | theLine = NULL;
197 | }
198 | }
199 |
200 | // Update the head.
201 | *listHead = inLine;
202 | (*listHead)->prev = NULL;
203 | }
204 |
205 | @end
206 |
--------------------------------------------------------------------------------
/src/source/Categories/List64Utils.m:
--------------------------------------------------------------------------------
1 | /*
2 | List64Utils.m
3 |
4 | A category on Exe64Processor that contains the linked list
5 | manipulation methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "List64Utils.h"
13 |
14 | @implementation Exe64Processor(List64Utils)
15 |
16 | // Each text line is stored in an element of a doubly-linked list. These are
17 | // vanilla textbook funcs for maintaining the list.
18 |
19 | // insertLine:before:inList:
20 | // ----------------------------------------------------------------------------
21 |
22 | - (void)insertLine: (Line64*)inLine
23 | before: (Line64*)nextLine
24 | inList: (Line64**)listHead
25 | {
26 | if (!nextLine)
27 | return;
28 |
29 | if (nextLine == *listHead)
30 | *listHead = inLine;
31 |
32 | inLine->prev = nextLine->prev;
33 | inLine->next = nextLine;
34 | nextLine->prev = inLine;
35 |
36 | if (inLine->prev)
37 | inLine->prev->next = inLine;
38 | }
39 |
40 | // insertLine:after:inList:
41 | // ----------------------------------------------------------------------------
42 |
43 | - (void)insertLine: (Line64*)inLine
44 | after: (Line64*)prevLine
45 | inList: (Line64**)listHead
46 | {
47 | if (!prevLine)
48 | {
49 | *listHead = inLine;
50 | return;
51 | }
52 |
53 | inLine->next = prevLine->next;
54 | inLine->prev = prevLine;
55 | prevLine->next = inLine;
56 |
57 | if (inLine->next)
58 | inLine->next->prev = inLine;
59 | }
60 |
61 | // replaceLine:withLine:inList:
62 | // ----------------------------------------------------------------------------
63 | // This non-standard method is used for merging the verbose and plain lists.
64 |
65 | - (void)replaceLine: (Line64*)inLine
66 | withLine: (Line64*)newLine
67 | inList: (Line64**)listHead
68 | {
69 | if (!inLine || !newLine)
70 | return;
71 |
72 | if (inLine == *listHead)
73 | *listHead = newLine;
74 |
75 | newLine->next = inLine->next;
76 | newLine->prev = inLine->prev;
77 |
78 | if (newLine->next)
79 | newLine->next->prev = newLine;
80 |
81 | if (newLine->prev)
82 | newLine->prev->next = newLine;
83 |
84 | if (inLine->chars)
85 | free(inLine->chars);
86 |
87 | free(inLine);
88 | }
89 |
90 | // printLinesFromList:
91 | // ----------------------------------------------------------------------------
92 | // Print our modified lines to a FILE*. The FILE* is a real file in the GUI
93 | // target, and stdout in the CLI target.
94 |
95 | - (BOOL)printLinesFromList: (Line64*)listHead
96 | {
97 | FILE* outFile = NULL;
98 |
99 | // In the CLI target, mOutputFilePath is nil.
100 | if (iOutputFilePath)
101 | {
102 | const char* outPath = UTF8STRING(iOutputFilePath);
103 | outFile = fopen(outPath, "w");
104 | }
105 | else
106 | outFile = stdout;
107 |
108 | if (!outFile)
109 | {
110 | perror("otx: unable to open output file");
111 | return NO;
112 | }
113 |
114 | Line64* theLine = listHead;
115 |
116 | // Cache the fileno and use SYS_write for maximum speed.
117 | SInt32 fileNum = fileno(outFile);
118 |
119 | while (theLine)
120 | {
121 | if (syscall(SYS_write, fileNum, theLine->chars, theLine->length) == -1)
122 | {
123 | perror("otx: unable to write to output file");
124 |
125 | if (iOutputFilePath)
126 | {
127 | if (fclose(outFile) != 0)
128 | perror("otx: unable to close output file");
129 | }
130 |
131 | return NO;
132 | }
133 |
134 | theLine = theLine->next;
135 | }
136 |
137 | if (iOutputFilePath)
138 | {
139 | if (fclose(outFile) != 0)
140 | {
141 | perror("otx: unable to close output file");
142 | return NO;
143 | }
144 | }
145 |
146 | return YES;
147 | }
148 |
149 | // deleteLinesFromList:
150 | // ----------------------------------------------------------------------------
151 |
152 | - (void)deleteLinesFromList: (Line64*)listHead
153 | {
154 | Line64* theLine = listHead;
155 |
156 | while (theLine)
157 | {
158 | if (theLine->prev) // If there's one behind us...
159 | {
160 | free(theLine->prev->chars); // delete it.
161 | free(theLine->prev);
162 | }
163 |
164 | if (theLine->next) // If there are more...
165 | theLine = theLine->next; // jump to next one and continue.
166 | else
167 | { // This is the last one, delete it.
168 | free(theLine->chars);
169 | free(theLine);
170 | theLine = NULL;
171 | }
172 | }
173 | }
174 |
175 | // deleteLinesBefore:fromList:
176 | // ----------------------------------------------------------------------------
177 |
178 | - (void)deleteLinesBefore: (Line64*)inLine
179 | fromList: (Line64**)listHead
180 | {
181 | Line64* theLine = *listHead;
182 |
183 | while (theLine)
184 | {
185 | if (theLine->prev) // If there's one behind us...
186 | {
187 | free(theLine->prev->chars); // delete it.
188 | free(theLine->prev);
189 | }
190 |
191 | if (theLine->next && theLine->next != inLine) // If there are more...
192 | theLine = theLine->next; // jump to next one and continue.
193 | else
194 | { // This is the last one, delete it.
195 | free(theLine->chars);
196 | free(theLine);
197 | theLine = NULL;
198 | }
199 | }
200 |
201 | // Update the head.
202 | *listHead = inLine;
203 | (*listHead)->prev = NULL;
204 | }
205 |
206 | @end
207 |
--------------------------------------------------------------------------------
/src/English.lproj/Help/Contents/toc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 | otx Help: TOC
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/source/Categories/Searchers.m:
--------------------------------------------------------------------------------
1 | /*
2 | Searchers.m
3 |
4 | A category on Exe32Processor that contains the various binary search
5 | methods.
6 |
7 | This file is in the public domain.
8 | */
9 |
10 | #import
11 |
12 | #import "Searchers.h"
13 | #import "ObjcAccessors.h"
14 |
15 | @implementation Exe32Processor(Searchers)
16 |
17 | // findSymbolByAddress:
18 | // ----------------------------------------------------------------------------
19 |
20 | - (char*)findSymbolByAddress: (uint32_t)inAddress
21 | {
22 | if (!iFuncSyms)
23 | return NO;
24 |
25 | nlist searchKey = {{0}, 0, 0, 0, inAddress};
26 | nlist* symbol = (nlist*)bsearch(&searchKey,
27 | iFuncSyms, iNumFuncSyms, sizeof(nlist),
28 | (COMPARISON_FUNC_TYPE)Sym_Compare);
29 |
30 | if (symbol) {
31 | return (char*)((char *)iMachHeaderPtr + iStringTableOffset + symbol->n_un.n_strx);
32 | }else
33 | return NULL;
34 | }
35 |
36 | // findClassMethod:byAddress:
37 | // ----------------------------------------------------------------------------
38 |
39 | - (BOOL)findClassMethod: (MethodInfo**)outMI
40 | byAddress: (uint32_t)inAddress;
41 | {
42 | if (!outMI)
43 | return NO;
44 |
45 | if (!iClassMethodInfos)
46 | {
47 | *outMI = NULL;
48 | return NO;
49 | }
50 |
51 | uint32_t swappedAddress = inAddress;
52 |
53 | if (iSwapped)
54 | swappedAddress = OSSwapInt32(swappedAddress);
55 |
56 | MethodInfo searchKey = {0};
57 | searchKey.m.method_imp = swappedAddress;
58 |
59 | *outMI = bsearch(&searchKey,
60 | iClassMethodInfos, iNumClassMethodInfos, sizeof(MethodInfo),
61 | (COMPARISON_FUNC_TYPE)
62 | (iSwapped ? MethodInfo_Compare_Swapped : MethodInfo_Compare));
63 |
64 | return (*outMI != NULL);
65 | }
66 |
67 | // findCatMethod:byAddress:
68 | // ----------------------------------------------------------------------------
69 |
70 | - (BOOL)findCatMethod: (MethodInfo**)outMI
71 | byAddress: (uint32_t)inAddress;
72 | {
73 | if (!outMI)
74 | return NO;
75 |
76 | if (!iCatMethodInfos)
77 | {
78 | *outMI = NULL;
79 | return NO;
80 | }
81 |
82 | uint32_t swappedAddress = inAddress;
83 |
84 | if (iSwapped)
85 | swappedAddress = OSSwapInt32(swappedAddress);
86 |
87 | MethodInfo searchKey = {0};
88 | searchKey.m.method_imp = swappedAddress;
89 |
90 | *outMI = bsearch(&searchKey,
91 | iCatMethodInfos, iNumCatMethodInfos, sizeof(MethodInfo),
92 | (COMPARISON_FUNC_TYPE)
93 | (iSwapped ? MethodInfo_Compare_Swapped : MethodInfo_Compare));
94 |
95 | return (*outMI != NULL);
96 | }
97 |
98 | // findIvar:inClass:withOffset:
99 | // ----------------------------------------------------------------------------
100 |
101 | - (BOOL)findIvar: (objc1_32_ivar*)outIvar
102 | inClass: (objc1_32_class*)inClass
103 | withOffset: (uint32_t)inOffset
104 | {
105 | if (!inClass || !outIvar)
106 | return NO;
107 |
108 | // Loop thru inClass and all superclasses.
109 | objc1_32_class* theClassPtr = inClass;
110 | objc1_32_class theSwappedClass = *theClassPtr;
111 | objc1_32_class theDummyClass = {0};
112 | char* theSuperName = NULL;
113 | objc1_32_ivar_list* theIvars;
114 |
115 | while (theClassPtr)
116 | {
117 | // if (mSwapped)
118 | // swap_objc_class(&theSwappedClass);
119 |
120 | theIvars = (objc1_32_ivar_list*)[self getPointer:theSwappedClass.ivars type:NULL];
121 |
122 | if (!theIvars)
123 | { // Try again with the superclass.
124 | theSuperName = [self getPointer:theClassPtr->super_class type:NULL];
125 |
126 | if (!theSuperName)
127 | break;
128 |
129 | if (![self getObjc1Class:&theDummyClass fromName:theSuperName])
130 | break;
131 |
132 | theClassPtr = &theDummyClass;
133 |
134 | continue;
135 | }
136 |
137 | uint32_t numIvars = theIvars->ivar_count;
138 |
139 | if (iSwapped)
140 | numIvars = OSSwapInt32(numIvars);
141 |
142 | // It would be nice to use bsearch(3) here, but there's too much
143 | // swapping.
144 | SInt64 begin = 0;
145 | SInt64 end = numIvars - 1;
146 | SInt64 split = numIvars / 2;
147 | uint32_t offset;
148 |
149 | while (end >= begin)
150 | {
151 | offset = theIvars->ivar_list[split].ivar_offset;
152 |
153 | if (iSwapped)
154 | offset = OSSwapInt32(offset);
155 |
156 | if (offset == inOffset)
157 | {
158 | *outIvar = theIvars->ivar_list[split];
159 |
160 | if (iSwapped)
161 | swap_objc1_32_ivar(outIvar);
162 |
163 | return YES;
164 | }
165 |
166 | if (offset > inOffset)
167 | end = split - 1;
168 | else
169 | begin = split + 1;
170 |
171 | split = (begin + end) / 2;
172 | }
173 |
174 | // Try again with the superclass.
175 | theSuperName = [self getPointer:theClassPtr->super_class type:NULL];
176 |
177 | if (!theSuperName)
178 | break;
179 |
180 | if (![self getObjc1Class:&theDummyClass fromName:theSuperName])
181 | break;
182 |
183 | theClassPtr = &theDummyClass;
184 | }
185 |
186 | return NO;
187 | }
188 |
189 | // findIvar:inClass:withOffset:
190 | // ----------------------------------------------------------------------------
191 |
192 | - (BOOL)findIvar: (objc2_32_ivar_t**)outIvar
193 | inClass2: (objc2_32_class_t*)inClass
194 | withOffset: (uint32_t)inOffset
195 | {
196 | if (!inClass || !outIvar)
197 | return NO;
198 |
199 | objc2_64_ivar_t searchKey = {inOffset, 0, 0, 0, 0};
200 |
201 | *outIvar = bsearch(&searchKey, iClassIvars, iNumClassIvars, sizeof(objc2_32_ivar_t),
202 | (COMPARISON_FUNC_TYPE)objc2_32_ivar_t_Compare);
203 |
204 | return (*outIvar != NULL);
205 | }
206 |
207 | @end
208 |
--------------------------------------------------------------------------------
/src/source/ObjcTypes.m:
--------------------------------------------------------------------------------
1 | /*
2 | ObjcTypes.m
3 |
4 | Definitions shared by GUI and CLI targets.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 |
10 | #import "ObjcTypes.h"
11 |
12 |
13 | void swap_objc1_32_module(objc1_32_module *m)
14 | {
15 | m->version = OSSwapInt32(m->version);
16 | m->size = OSSwapInt32(m->size);
17 | m->name = OSSwapInt32(m->name);
18 | m->symtab = OSSwapInt32(m->symtab);
19 | }
20 |
21 |
22 | void swap_objc1_32_symtab(objc1_32_symtab *s)
23 | {
24 | s->sel_ref_cnt = OSSwapInt32(s->sel_ref_cnt);
25 | s->refs = OSSwapInt32(s->refs);
26 | s->cls_def_cnt = OSSwapInt16(s->cls_def_cnt);
27 | s->cat_def_cnt = OSSwapInt16(s->cat_def_cnt);
28 | }
29 |
30 |
31 | void swap_objc1_32_class(objc1_32_class *c)
32 | {
33 | c->isa = OSSwapInt32(c->isa);
34 | c->super_class = OSSwapInt32(c->super_class);
35 | c->name = OSSwapInt32(c->name);
36 | c->version = OSSwapInt32(c->version);
37 | c->info = OSSwapInt32(c->info);
38 | c->instance_size = OSSwapInt32(c->instance_size);
39 | c->ivars = OSSwapInt32(c->ivars);
40 | c->methodLists = OSSwapInt32(c->methodLists);
41 | c->cache = OSSwapInt32(c->cache);
42 | c->protocols = OSSwapInt32(c->protocols);
43 | }
44 |
45 |
46 | void swap_objc1_32_ivar(objc1_32_ivar *i)
47 | {
48 | i->ivar_name = OSSwapInt32(i->ivar_name);
49 | i->ivar_type = OSSwapInt32(i->ivar_type);
50 | i->ivar_offset = OSSwapInt32(i->ivar_offset);
51 | }
52 |
53 |
54 | void swap_objc1_32_category(objc1_32_category *c)
55 | {
56 | c->category_name = OSSwapInt32(c->category_name);
57 | c->class_name = OSSwapInt32(c->class_name);
58 | c->instance_methods = OSSwapInt32(c->instance_methods);
59 | c->class_methods = OSSwapInt32(c->class_methods);
60 | c->protocols = OSSwapInt32(c->protocols);
61 | }
62 |
63 |
64 | void swap_objc1_32_method_list(objc1_32_method_list *m)
65 | {
66 | m->obsolete = OSSwapInt32(m->obsolete);
67 | m->method_count = OSSwapInt32(m->method_count);
68 | }
69 |
70 |
71 | void swap_objc1_32_method(objc1_32_method *m)
72 | {
73 | m->method_name = OSSwapInt32(m->method_name);
74 | m->method_types = OSSwapInt32(m->method_types);
75 | m->method_imp = OSSwapInt32(m->method_imp);
76 | }
77 |
78 |
79 | void swap_objc1_64_module(objc1_64_module *m)
80 | {
81 | m->version = OSSwapInt64(m->version);
82 | m->size = OSSwapInt64(m->size);
83 | m->name = OSSwapInt64(m->name);
84 | m->symtab = OSSwapInt64(m->symtab);
85 | }
86 |
87 |
88 | void swap_objc1_64_symtab(objc1_64_symtab *s)
89 | {
90 | s->sel_ref_cnt = OSSwapInt64(s->sel_ref_cnt);
91 | s->refs = OSSwapInt64(s->refs);
92 | s->cls_def_cnt = OSSwapInt16(s->cls_def_cnt);
93 | s->cat_def_cnt = OSSwapInt16(s->cat_def_cnt);
94 | }
95 |
96 |
97 | void swap_objc1_64_class(objc1_64_class *c)
98 | {
99 | c->isa = OSSwapInt64(c->isa);
100 | c->super_class = OSSwapInt64(c->super_class);
101 | c->name = OSSwapInt64(c->name);
102 | c->version = OSSwapInt64(c->version);
103 | c->info = OSSwapInt64(c->info);
104 | c->instance_size = OSSwapInt64(c->instance_size);
105 | c->ivars = OSSwapInt64(c->ivars);
106 | c->methodLists = OSSwapInt64(c->methodLists);
107 | c->cache = OSSwapInt64(c->cache);
108 | c->protocols = OSSwapInt64(c->protocols);
109 | }
110 |
111 |
112 | void swap_objc1_64_ivar(objc1_64_ivar *i)
113 | {
114 | i->ivar_name = OSSwapInt64(i->ivar_name);
115 | i->ivar_type = OSSwapInt64(i->ivar_type);
116 | i->ivar_offset = OSSwapInt64(i->ivar_offset);
117 | }
118 |
119 |
120 | void swap_objc1_64_category(objc1_64_category *c)
121 | {
122 | c->category_name = OSSwapInt64(c->category_name);
123 | c->class_name = OSSwapInt64(c->class_name);
124 | c->instance_methods = OSSwapInt64(c->instance_methods);
125 | c->class_methods = OSSwapInt64(c->class_methods);
126 | c->protocols = OSSwapInt64(c->protocols);
127 | }
128 |
129 |
130 | void swap_objc1_64_method_list(objc1_64_method_list *m)
131 | {
132 | m->obsolete = OSSwapInt64(m->obsolete);
133 | m->method_count = OSSwapInt64(m->method_count);
134 | }
135 |
136 |
137 | void swap_objc1_64_method(objc1_64_method *m)
138 | {
139 | m->method_name = OSSwapInt64(m->method_name);
140 | m->method_types = OSSwapInt64(m->method_types);
141 | m->method_imp = OSSwapInt64(m->method_imp);
142 | }
143 |
144 |
145 | void swap_objc2_32_class(objc2_32_class_t *c)
146 | {
147 | c->isa = OSSwapInt32(c->isa);
148 | c->superclass = OSSwapInt32(c->superclass);
149 | c->cache = OSSwapInt32(c->cache);
150 | c->vtable = OSSwapInt32(c->vtable);
151 | c->data = OSSwapInt32(c->data);
152 | }
153 |
154 |
155 | void swap_objc2_32_method(objc2_32_method_t *m)
156 | {
157 | m->name = OSSwapInt32(m->name);
158 | m->types = OSSwapInt32(m->types);
159 | m->imp = OSSwapInt32(m->imp);
160 | }
161 |
162 |
163 | void swap_objc2_32_ivar(objc2_32_ivar_t *i)
164 | {
165 | i->offset = OSSwapInt64(i->offset);
166 | i->name = OSSwapInt32(i->name);
167 | i->type = OSSwapInt32(i->type);
168 | i->alignment = OSSwapInt32(i->alignment);
169 | i->size = OSSwapInt32(i->size);
170 | }
171 |
172 |
173 | void swap_objc2_64_class(objc2_64_class_t *c)
174 | {
175 | c->isa = OSSwapInt64(c->isa);
176 | c->superclass = OSSwapInt64(c->superclass);
177 | c->cache = OSSwapInt64(c->cache);
178 | c->vtable = OSSwapInt64(c->vtable);
179 | c->data = OSSwapInt64(c->data);
180 | }
181 |
182 |
183 | void swap_objc2_64_method(objc2_64_method_t *m)
184 | {
185 | m->name = OSSwapInt64(m->name);
186 | m->types = OSSwapInt64(m->types);
187 | m->imp = OSSwapInt64(m->imp);
188 | }
189 |
190 |
191 | void swap_objc2_64_ivar(objc2_64_ivar_t *i)
192 | {
193 | i->offset = OSSwapInt64(i->offset);
194 | i->name = OSSwapInt64(i->name);
195 | i->type = OSSwapInt64(i->type);
196 | i->alignment = OSSwapInt32(i->alignment);
197 | i->size = OSSwapInt32(i->size);
198 | }
199 |
200 |
--------------------------------------------------------------------------------
/src/source/AppController.h:
--------------------------------------------------------------------------------
1 | /*
2 | AppController.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | #import "DropBox.h"
10 | #import "ErrorReporter.h"
11 | #import "ProgressReporter.h"
12 |
13 | #define kOutputTextTag 100
14 | #define kOutputFileBaseTag 200
15 | #define kOutputFileExtTag 201
16 |
17 | #define kPrefsAnimationTime 0.12
18 | #define kMainAnimationTime 0.15
19 |
20 | #define NSXViewAnimationCustomEffectsKey @"NSXViewAnimationCustomEffectsKey"
21 |
22 | // There can be only one swap effect per animation in this implementation.
23 | #define NSXViewAnimationSwapAtBeginningEffect (1 << 0)
24 | #define NSXViewAnimationSwapAtEndEffect (1 << 1)
25 | #define NSXViewAnimationSwapAtBeginningAndEndEffect (1 << 2)
26 | #define NSXViewAnimationFadeOutAndSwapEffect (1 << 3)
27 |
28 | // These effects can be combined.
29 | #define NSXViewAnimationUpdateResizeMasksAtEndEffect (1 << 10)
30 | #define NSXViewAnimationUpdateWindowMinMaxSizesAtEndEffect (1 << 11)
31 | #define NSXViewAnimationPerformSelectorAtEndEffect (1 << 12)
32 | #define NSXViewAnimationOpenFileWithAppAtEndEffect (1 << 13)
33 |
34 | #define NSXViewAnimationSwapOldKey \
35 | @"NSXViewAnimationSwapOldKey" // NSView*
36 | #define NSXViewAnimationSwapNewKey \
37 | @"NSXViewAnimationSwapNewKey" // NSView*
38 |
39 | #define NSXViewAnimationResizeMasksArrayKey \
40 | @"NSXViewAnimationResizeMasksArrayKey" // NSArray* (uint32_t)
41 | #define NSXViewAnimationResizeViewsArrayKey \
42 | @"NSXViewAnimationResizeViewsArrayKey" // NSArray* (uint32_t)
43 |
44 | #define NSXViewAnimationWindowMinSizeKey \
45 | @"NSXViewAnimationWindowMinSizeKey" // NSValue* (NSSize*)
46 | #define NSXViewAnimationWindowMaxSizeKey \
47 | @"NSXViewAnimationWindowMaxSizeKey" // NSValue* (NSSize*)
48 |
49 | #define NSXViewAnimationSelectorKey \
50 | @"NSXViewAnimationSelectorKey" // NSValue* (SEL)
51 | #define NSXViewAnimationPerformInNewThreadKey \
52 | @"NSXViewAnimationPerformInNewThreadKey" // NSNumber* (BOOL)
53 |
54 | #define NSXViewAnimationFilePathKey \
55 | @"NSXViewAnimationFilePathKey" // NSString*
56 | #define NSXViewAnimationAppNameKey \
57 | @"NSXViewAnimationAppNameKey" // NSString*
58 |
59 | #define OTXPrefsToolbarID @"OTX Preferences Window Toolbar"
60 | #define PrefsGeneralToolbarItemID @"General Toolbar Item"
61 | #define PrefsOutputToolbarItemID @"Output Toolbar Item"
62 |
63 | #define PrefsToolbarItemsArray \
64 | [NSArray arrayWithObjects: PrefsGeneralToolbarItemID, \
65 | PrefsOutputToolbarItemID, nil]
66 |
67 | typedef struct
68 | {
69 | cpu_type_t type;
70 | cpu_subtype_t subtype;
71 | }
72 | CPUID;
73 |
74 | // ============================================================================
75 |
76 | @interface AppController : NSObject
77 | {
78 | @private
79 | // main window
80 | IBOutlet NSWindow* iMainWindow;
81 | IBOutlet NSPopUpButton* iArchPopup;
82 | IBOutlet NSButton* iThinButton;
83 | IBOutlet NSButton* iVerifyButton;
84 | IBOutlet NSTextField* iOutputText;
85 | IBOutlet NSTextField* iOutputLabelText;
86 | IBOutlet NSTextField* iPathText;
87 | IBOutlet NSTextField* iPathLabelText;
88 | IBOutlet NSTextField* iProgText;
89 | IBOutlet NSTextField* iTypeText;
90 | IBOutlet NSTextField* iTypeLabelText;
91 | IBOutlet NSProgressIndicator* iProgBar;
92 | IBOutlet NSButton* iSaveButton;
93 | IBOutlet DropBox* iDropBox;
94 | IBOutlet NSView* iMainView;
95 | IBOutlet NSView* iProgView;
96 |
97 | // prefs window
98 | IBOutlet NSWindow* iPrefsWindow;
99 | IBOutlet NSView* iPrefsGeneralView;
100 | IBOutlet NSView* iPrefsOutputView;
101 |
102 | NSURL* iObjectFile;
103 | cpu_type_t iSelectedArchCPUType;
104 | cpu_subtype_t iSelectedArchCPUSubType;
105 | CPUID iCPUIDs[4]; // refcons for iArchPopup
106 | uint32_t iFileArchMagic;
107 | BOOL iFileIsValid;
108 | BOOL iIgnoreArch;
109 | BOOL iExeIsFat;
110 | BOOL iProcessing;
111 | NSString* iExeName;
112 | NSString* iOutputFileLabel;
113 | NSString* iOutputFileName;
114 | NSString* iOutputFilePath;
115 | NSView** iPrefsViews;
116 | uint32_t iPrefsCurrentViewIndex;
117 | host_basic_info_data_t iHostInfo;
118 | NSShadow* iTextShadow;
119 | NSTimer* iIndeterminateProgBarMainThreadTimer;
120 | }
121 |
122 | // main window
123 | - (void)setupMainWindow;
124 | - (IBAction)showMainWindow: (id)sender;
125 | - (void)applyShadowToText: (NSTextField*)inText;
126 | - (IBAction)selectArch: (id)sender;
127 | - (IBAction)openExe: (id)sender;
128 | - (IBAction)syncOutputText: (id)sender;
129 | - (IBAction)attemptToProcessFile: (id)sender;
130 | - (IBAction)cancel: (id)sender;
131 | - (void)processFile;
132 | - (void)continueProcessingFile;
133 | - (void)adjustInterfaceForMultiThread;
134 | - (void)adjustInterfaceForSingleThread;
135 | - (void)processingThreadDidFinish: (NSString*)result;
136 | - (void)nudgeIndeterminateProgBar: (NSTimer*)timer;
137 |
138 | - (IBAction)thinFile: (id)sender;
139 | - (IBAction)verifyNops: (id)sender;
140 |
141 | - (void)refreshMainWindow;
142 | - (void)syncSaveButton;
143 |
144 | - (void)newPackageFile: (NSURL*)inPackageFile;
145 | - (void)newOFile: (NSURL*)inOFile
146 | needsPath: (BOOL)inNeedsPath;
147 | - (void)nopAlertDidEnd: (NSAlert*)alert
148 | returnCode: (int)returnCode
149 | contextInfo: (void*)contextInfo;
150 | - (void)showProgView;
151 | - (void)hideProgView: (BOOL)inAnimate
152 | openFile: (BOOL)inOpenFile;
153 |
154 | - (void)dupeFileAlertDidEnd: (NSAlert*)alert
155 | returnCode: (int)returnCode
156 | contextInfo: (void*)contextInfo;
157 |
158 | // prefs window
159 | - (void)setupPrefsWindow;
160 | - (IBAction)showPrefs: (id)sender;
161 | - (IBAction)switchPrefsViews: (id)sender;
162 |
163 | @end
164 |
--------------------------------------------------------------------------------
/src/source/Categories/Objc64Accessors.m:
--------------------------------------------------------------------------------
1 | /*
2 | Objc64Accessors.m
3 |
4 | What the filename says.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "Objc64Accessors.h"
12 | #import "Searchers64.h"
13 |
14 | @implementation Exe64Processor(Objc64Accessors)
15 |
16 | // getObjcClassPtr:fromMethod:
17 | // ----------------------------------------------------------------------------
18 | // Given a method imp address, return the class to which it belongs. This func
19 | // is called each time a new function is detected. If that function is known
20 | // to be an Obj-C method, it's class is returned. Otherwise this returns NULL.
21 |
22 | - (BOOL)getObjcClassPtr: (objc2_64_class_t**)outClass
23 | fromMethod: (UInt64)inAddress;
24 | {
25 | *outClass = NULL;
26 |
27 | Method64Info* theInfo = NULL;
28 | [self findClassMethod:&theInfo byAddress:inAddress];
29 |
30 | if (theInfo)
31 | *outClass = &theInfo->oc_class;
32 |
33 | return (*outClass != NULL);
34 | }
35 |
36 | // getObjcMethod:fromAddress:
37 | // ----------------------------------------------------------------------------
38 | // Given a method imp address, return the MethodInfo for it.
39 |
40 | - (BOOL)getObjcMethod: (Method64Info**)outMI
41 | fromAddress: (UInt64)inAddress;
42 | {
43 | *outMI = NULL;
44 | [self findClassMethod:outMI byAddress:inAddress];
45 |
46 | /* if (*outMI)
47 | return YES;
48 |
49 | [self findCatMethod:outMI byAddress:inAddress];*/
50 |
51 | return (*outMI != NULL);
52 | }
53 |
54 | // getObjcMethodList:methods:fromAddress: (was get_method_list)
55 | // ----------------------------------------------------------------------------
56 | // Removed the truncation flag. 'left' is no longer used by the caller.
57 |
58 | - (BOOL)getObjcMethodList: (objc2_64_method_list_t*)outList
59 | methods: (objc2_64_method_t**)outMethods
60 | fromAddress: (UInt64)inAddress;
61 | {
62 | /* uint32_t left, i;
63 |
64 | if (!outList)
65 | return NO;
66 |
67 | *outList = (objc_method_list){0};
68 |
69 | for (i = 0; i < iNumObjcSects; i++)
70 | {
71 | if (inAddress >= iObjcSects[i].s.addr &&
72 | inAddress < iObjcSects[i].s.addr + iObjcSects[i].s.size)
73 | {
74 | left = iObjcSects[i].s.size -
75 | (inAddress - iObjcSects[i].s.addr);
76 |
77 | if (left >= sizeof(objc_method_list) - sizeof(objc_method))
78 | {
79 | memcpy(outList, iObjcSects[i].contents +
80 | (inAddress - iObjcSects[i].s.addr),
81 | sizeof(objc_method_list) - sizeof(objc_method));
82 | left -= sizeof(objc_method_list) -
83 | sizeof(objc_method);
84 | *outMethods = (objc_method*)(iObjcSects[i].contents +
85 | (inAddress - iObjcSects[i].s.addr) +
86 | sizeof(objc_method_list) - sizeof(objc_method));
87 | }
88 | else
89 | {
90 | memcpy(outList, iObjcSects[i].contents +
91 | (inAddress - iObjcSects[i].s.addr), left);
92 | left = 0;
93 | *outMethods = NULL;
94 | }
95 |
96 | return YES;
97 | }
98 | }
99 |
100 | return NO;
101 | */
102 | return NO;
103 | }
104 |
105 | // getObjcDescription:fromObject:type:
106 | // ----------------------------------------------------------------------------
107 | // Given an Obj-C object, return it's description.
108 |
109 | - (BOOL)getObjcDescription: (char**)outDescription
110 | fromObject: (const char*)inObject
111 | type: (UInt8)inType
112 | {
113 | *outDescription = NULL;
114 |
115 | UInt64 theValue = 0;
116 |
117 | switch (inType)
118 | {
119 | case CFStringType:
120 | {
121 | cfstring_object_64 cfString = *(cfstring_object_64*)inObject;
122 |
123 | if (cfString.oc_string.length == 0)
124 | break;
125 |
126 | theValue = cfString.oc_string.chars;
127 |
128 | break;
129 | }
130 |
131 | case OCStrObjectType:
132 | {
133 | nxstring_object_64 ocString = *(nxstring_object_64*)inObject;
134 |
135 | if (ocString.length == 0)
136 | break;
137 |
138 | theValue = ocString.chars;
139 |
140 | break;
141 | }
142 |
143 | case OCGenericType:
144 | theValue = *(UInt64*)inObject;
145 |
146 | break;
147 |
148 | default:
149 | return NO;
150 | break;
151 | }
152 |
153 | if (iSwapped)
154 | theValue = OSSwapInt64(theValue);
155 |
156 | *outDescription = [self getPointer:theValue type:NULL];
157 |
158 | return (*outDescription != NULL);
159 | }
160 |
161 | // getObjcClass:fromName:
162 | // ----------------------------------------------------------------------------
163 | // Given a class name, return the class itself. This func is used to tie
164 | // categories to classes. We have 2 pointers to the same name, so pointer
165 | // equality is sufficient.
166 |
167 | - (BOOL)getObjcClass: (objc2_64_class_t*)outClass
168 | fromName: (const char*)inName;
169 | {
170 | uint32_t i;
171 | UInt64 namePtr;
172 |
173 | for (i = 0; i < iNumClassMethodInfos; i++)
174 | {
175 | objc2_64_class_ro_t* roData = (objc2_64_class_ro_t*)(iDataSect.contents +
176 | (uintptr_t)(iClassMethodInfos[i].oc_class.data - iDataSect.s.addr));
177 |
178 | namePtr = roData->name;
179 |
180 | if (iSwapped)
181 | namePtr = OSSwapInt64(namePtr);
182 |
183 | if ([self getPointer:namePtr type:NULL] == inName)
184 | {
185 | *outClass = iClassMethodInfos[i].oc_class;
186 | return YES;
187 | }
188 | }
189 |
190 | *outClass = (objc2_64_class_t){0};
191 | return NO;
192 | }
193 |
194 | // getObjcClassPtr:fromName:
195 | // ----------------------------------------------------------------------------
196 | // Same as above, but returns a pointer.
197 |
198 | - (BOOL)getObjcClassPtr: (objc2_64_class_t**)outClassPtr
199 | fromName: (const char*)inName;
200 | {
201 | uint32_t i;
202 | UInt64 namePtr;
203 |
204 | for (i = 0; i < iNumClassMethodInfos; i++)
205 | {
206 | objc2_64_class_ro_t* roData = (objc2_64_class_ro_t*)(iDataSect.contents +
207 | (uintptr_t)(iClassMethodInfos[i].oc_class.data - iDataSect.s.addr));
208 |
209 | namePtr = roData->name;
210 |
211 | if (iSwapped)
212 | namePtr = OSSwapInt64(namePtr);
213 |
214 | if ([self getPointer:namePtr type:NULL] == inName)
215 | {
216 | *outClassPtr = &iClassMethodInfos[i].oc_class;
217 | return YES;
218 | }
219 | }
220 |
221 | *outClassPtr = NULL;
222 | return NO;
223 | }
224 |
225 | // getObjcMetaClass:fromClass:
226 | // ----------------------------------------------------------------------------
227 |
228 | - (BOOL)getObjcMetaClass: (objc2_64_class_t*)outClass
229 | fromClass: (objc2_64_class_t*)inClass;
230 | {
231 | /* if (inClass->isa >= iMetaClassSect.s.addr &&
232 | inClass->isa < iMetaClassSect.s.addr + iMetaClassSect.s.size)
233 | {
234 | *outClass = *(objc_class*)(iMetaClassSect.contents +
235 | (inClass->isa - iMetaClassSect.s.addr));
236 |
237 | return YES;
238 | }*/
239 |
240 | return NO;
241 | }
242 |
243 | @end
244 |
--------------------------------------------------------------------------------
/src/source/Processors/Exe64Processor.h:
--------------------------------------------------------------------------------
1 | /*
2 | Exe64Processor.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | #import "ExeProcessor.h"
10 |
11 | /* MethodInfo
12 |
13 | Additional info pertaining to an Obj-C method.
14 | */
15 | typedef struct
16 | {
17 | objc2_64_method_t m;
18 | objc2_64_class_t oc_class;
19 | BOOL inst; // to determine '+' or '-'
20 | }
21 | Method64Info;
22 |
23 | /* GP64RegisterInfo
24 |
25 | Processor-specific subclasses maintain arrays of RegisterInfo's to
26 | simulate the state of registers in the CPU as each line of code is
27 | executed.
28 | */
29 | typedef struct
30 | {
31 | UInt64 value;
32 | BOOL isValid; // value can be trusted
33 | objc2_64_class_t* classPtr;
34 | char* className;
35 | char* messageRefSel; // selector for calls through pointers
36 | }
37 | GP64RegisterInfo;
38 |
39 | /* Var64Info
40 |
41 | Represents a local variable in the stack frame. Currently, copies of
42 | 'self' are maintained in the variable-sized array mLocalSelves, and
43 | variables pushed onto the stack in x86 code are maintained in the array
44 | mStack[MAX_STACK_SIZE]. May be used for other things in future.
45 |
46 | Note the semantic differences regarding stack frames:
47 |
48 | PPC x86
49 | --------------------------------------------------
50 | local vars stack ptr(r1) + offset base ptr(EBP) - offset
51 | args to current func --- base ptr(EBP) + offset
52 | args to called func --- stack ptr(ESP) + offset
53 | */
54 | typedef struct
55 | {
56 | GP64RegisterInfo regInfo;
57 | SInt32 offset;
58 | }
59 | Var64Info;
60 |
61 | /* Line64Info
62 |
63 | Used exclusively in the Line64 struct below, LineInfo encapsulates the
64 | details pertaining to a line of disassemled code that are not part
65 | of the basic linked list element.
66 | */
67 | typedef struct
68 | {
69 | UInt64 address;
70 | UInt8 code[16]; // machine code as int bytes
71 | UInt8 codeLength;
72 | BOOL isCode; // NO for function names, section names etc.
73 | BOOL isFunction; // YES if this is the first instruction in a function.
74 | BOOL isFunctionEnd; // YES if this is the last instruction in a function.
75 | }
76 | Line64Info;
77 |
78 | /* Line64
79 |
80 | Represents a line of text from otool's output. For each __text section,
81 | otool is called twice- with symbolic operands(-V) and without(-v). The
82 | resulting 2 text files are each read into a doubly-linked list of Line64's.
83 | Each Line64 contains a pointer to the corresponding Line64 in the other list.
84 | The reason for this approach is due to otool's inaccuracy in guessing
85 | symbols. From comments in ofile_print.c:
86 |
87 | "Both a verbose (symbolic) and non-verbose modes are supported to aid
88 | in seeing the values even if they are not correct."
89 |
90 | With both versions on hand, we can choose the better one for each Line64.
91 | The criteria for choosing is defined in chooseLine:. This does result in a
92 | slight loss of info, in the rare case that otool guesses correctly for
93 | any instruction that is not a function call.
94 | */
95 | struct Line64
96 | {
97 | char* chars; // C string
98 | size_t length; // C string length
99 | struct Line64* next; // next line in this list
100 | struct Line64* prev; // previous line in this list
101 | struct Line64* alt; // "this" line in the other list
102 | Line64Info info; // details
103 | };
104 |
105 | // "typedef struct Line64" doesn't work, so we do this instead.
106 | #define Line64 struct Line64
107 |
108 | /* Machine64State
109 |
110 | Saved state of the CPU registers and local copies of self. 'localSelves'
111 | is an array with 'numLocalSelves' items. 'regInfos' is an array whose
112 | count is defined by the processor-specific subclasses.
113 | */
114 | typedef struct
115 | {
116 | GP64RegisterInfo* regInfos;
117 | Var64Info* localSelves;
118 | uint32_t numLocalSelves;
119 | Var64Info* localVars;
120 | uint32_t numLocalVars;
121 | }
122 | Machine64State;
123 |
124 | /* Block64Info
125 |
126 | Info pertaining to a logical block of code. 'state' is the saved
127 | MachineState that should be restored upon entering this block.
128 | */
129 | typedef struct
130 | {
131 | UInt64 beginAddress;
132 | Line64* endLine;
133 | BOOL isEpilog;
134 | Machine64State state;
135 | }
136 | Block64Info;
137 |
138 | /* Function64Info
139 |
140 | Used for tracking the changing machine states between code blocks in a
141 | function. 'blocks' is an array with 'numBlocks' items.
142 | */
143 | typedef struct
144 | {
145 | UInt64 address;
146 | Block64Info* blocks;
147 | uint32_t numBlocks;
148 | uint32_t genericFuncNum; // 'AnonX' if > 0
149 | }
150 | Function64Info;
151 |
152 | // ============================================================================
153 |
154 | @interface Exe64Processor : ExeProcessor
155 | {
156 | @protected
157 | // guts
158 | mach_header_64* iMachHeaderPtr; // ptr to the orig header
159 | mach_header_64 iMachHeader; // (swapped?) copy of the header
160 | Line64* iVerboseLineListHead; // linked list the first
161 | Line64* iPlainLineListHead; // linked list the second
162 | Line64** iLineArray;
163 | uint32_t iNumLines;
164 | uint32_t iNumCodeLines;
165 | cpu_type_t iArchSelector;
166 | uint64_t iCurrentFunctionStart;
167 |
168 | // base pointers for indirect addressing
169 | SInt8 iCurrentThunk; // x86 register identifier
170 | UInt64 iCurrentFuncPtr; // PPC function address
171 |
172 | // symbols that point to functions
173 | nlist_64* iFuncSyms;
174 | uint32_t iNumFuncSyms;
175 |
176 | // FunctionInfo array
177 | Function64Info* iFuncInfos;
178 | uint32_t iNumFuncInfos;
179 |
180 | // Obj-C stuff
181 | Method64Info* iClassMethodInfos;
182 | uint32_t iNumClassMethodInfos;
183 | objc2_64_ivar_t* iClassIvars;
184 | uint32_t iNumClassIvars;
185 | objc2_64_class_t* iCurrentClass;
186 | BOOL iIsInstanceMethod;
187 |
188 | // Mach-O sections
189 | section_info_64 iObjcClassListSect;
190 | section_info_64 iObjcCatListSect; //
191 | section_info_64 iObjcConstSect;
192 | section_info_64 iObjcProtoListSect; //
193 | section_info_64 iObjcSuperRefsSect; //
194 | section_info_64 iObjcClassRefsSect;
195 | section_info_64 iObjcProtoRefsSect; //
196 | section_info_64 iObjcMsgRefsSect;
197 | section_info_64 iObjcSelRefsSect; //
198 | section_info_64 iObjcDataSect;
199 | section_info_64 iCStringSect;
200 | section_info_64 iNSStringSect;
201 | section_info_64 iLit4Sect;
202 | section_info_64 iLit8Sect;
203 | section_info_64 iTextSect;
204 | section_info_64 iCoalTextSect;
205 | section_info_64 iCoalTextNTSect;
206 | section_info_64 iConstTextSect;
207 | section_info_64 iObjcMethnameSect;
208 | section_info_64 iObjcMethtypeSect;
209 | section_info_64 iObjcClassnameSect;
210 | section_info_64 iDataSect;
211 | section_info_64 iCoalDataSect;
212 | section_info_64 iCoalDataNTSect;
213 | section_info_64 iConstDataSect;
214 | section_info_64 iDyldSect;
215 | section_info_64 iCFStringSect;
216 | section_info_64 iNLSymSect;
217 | section_info_64 iImpPtrSect;
218 | UInt64 iTextOffset;
219 | UInt64 iEndOfText;
220 | }
221 |
222 | - (id)initWithURL: (NSURL*)inURL
223 | controller: (id)inController
224 | options: (ProcOptions*)inOptions;
225 | - (void)deleteFuncInfos;
226 |
227 | // processors
228 | - (BOOL)processExe: (NSString*)inOutputFilePath;
229 | - (BOOL)populateLineLists;
230 | - (BOOL)populateLineList: (Line64**)inList
231 | verbosely: (BOOL)inVerbose
232 | fromSection: (char*)inSectionName
233 | afterLine: (Line64**)inLine
234 | includingPath: (BOOL)inIncludePath;
235 | - (BOOL)printDataSections;
236 | - (void)printDataSection: (section_info_64*)inSect
237 | toFile: (FILE*)outFile;
238 | - (BOOL)lineIsCode: (const char*)inLine;
239 |
240 | // customizers
241 | - (void)gatherLineInfos;
242 | - (void)findFunctions;
243 | - (UInt64)addressFromLine: (const char*)inLine;
244 | - (void)processLine: (Line64*)ioLine;
245 | - (void)processCodeLine: (Line64**)ioLine;
246 | - (void)chooseLine: (Line64**)ioLine;
247 | - (void)entabLine: (Line64*)ioLine;
248 | - (char*)getPointer: (UInt64)inAddr
249 | type: (UInt8*)outType;
250 |
251 | - (char*)selectorForMsgSend: (char*)outComment
252 | fromLine: (Line64*)inLine;
253 |
254 | - (void)insertMD5;
255 |
256 | #ifdef OTX_DEBUG
257 | - (void)printSymbol: (nlist_64)inSym;
258 | - (void)printBlocks: (uint32_t)inFuncIndex;
259 | #endif
260 |
261 | @end
262 |
263 | // ----------------------------------------------------------------------------
264 | // Comparison functions for qsort(3) and bsearch(3)
265 |
266 | static int
267 | Function64_Info_Compare(
268 | Function64Info* f1,
269 | Function64Info* f2)
270 | {
271 | if (f1->address < f2->address)
272 | return -1;
273 |
274 | return (f1->address > f2->address);
275 | }
276 |
277 | static int
278 | Method64Info_Compare(
279 | Method64Info* mi1,
280 | Method64Info* mi2)
281 | {
282 | if (mi1->m.imp < mi2->m.imp)
283 | return -1;
284 |
285 | return (mi1->m.imp > mi2->m.imp);
286 | }
287 |
288 | static int
289 | Method64Info_Compare_Swapped(
290 | Method64Info* mi1,
291 | Method64Info* mi2)
292 | {
293 | UInt64 imp1 = OSSwapInt64(mi1->m.imp);
294 | UInt64 imp2 = OSSwapInt64(mi2->m.imp);
295 |
296 | if (imp1 < imp2)
297 | return -1;
298 |
299 | return (imp1 > imp2);
300 | }
301 |
302 | static int
303 | objc2_64_ivar_t_Compare(
304 | objc2_64_ivar_t* i1,
305 | objc2_64_ivar_t* i2)
306 | {
307 | if (i1->offset < i2->offset)
308 | return -1;
309 |
310 | return (i1->offset > i2->offset);
311 | }
312 |
313 | // ----------------------------------------------------------------------------
314 | // Utils
315 |
316 | static void
317 | swap_method64_info(
318 | Method64Info* mi)
319 | {
320 | swap_objc2_64_method(&mi->m);
321 | swap_objc2_64_class(&mi->oc_class);
322 | }
323 |
--------------------------------------------------------------------------------
/src/source/Processors/Exe32Processor.h:
--------------------------------------------------------------------------------
1 | /*
2 | Exe32Processor.h
3 |
4 | This file is in the public domain.
5 | */
6 |
7 | #import
8 |
9 | #import "ExeProcessor.h"
10 |
11 | /* MethodInfo
12 |
13 | Additional info pertaining to an Obj-C method.
14 | */
15 | typedef struct
16 | {
17 | union {
18 | struct {
19 | objc1_32_method m;
20 | objc1_32_class oc_class;
21 | objc1_32_category oc_cat;
22 | };
23 | struct {
24 | objc2_32_method_t m2;
25 | objc2_32_class_t oc_class2;
26 | };
27 | };
28 | BOOL inst; // to determine '+' or '-'
29 | }
30 | MethodInfo;
31 |
32 | /* GPRegisterInfo
33 |
34 | Processor-specific subclasses maintain arrays of RegisterInfo's to
35 | simulate the state of registers in the CPU as each line of code is
36 | executed.
37 | */
38 | typedef struct
39 | {
40 | uint32_t value;
41 | BOOL isValid; // value can be trusted
42 | objc_32_class_ptr classPtr;
43 | objc1_32_category* catPtr;
44 | }
45 | GPRegisterInfo;
46 |
47 | /* VarInfo
48 |
49 | Represents a local variable in the stack frame. Currently, copies of
50 | 'self' are maintained in the variable-sized array mLocalSelves, and
51 | variables pushed onto the stack in x86 code are maintained in the array
52 | mStack[MAX_STACK_SIZE]. May be used for other things in future.
53 |
54 | Note the semantic differences regarding stack frames:
55 |
56 | PPC x86
57 | --------------------------------------------------
58 | local vars stack ptr(r1) + offset base ptr(EBP) - offset
59 | args to current func --- base ptr(EBP) + offset
60 | args to called func --- stack ptr(ESP) + offset
61 | */
62 | typedef struct
63 | {
64 | GPRegisterInfo regInfo;
65 | SInt32 offset;
66 | }
67 | VarInfo;
68 |
69 | /* LineInfo
70 |
71 | Used exclusively in the Line struct below, LineInfo encapsulates the
72 | details pertaining to a line of disassemled code that are not part
73 | of the basic linked list element.
74 | */
75 | typedef struct
76 | {
77 | uint32_t address;
78 | UInt8 code[16]; // machine code as int bytes
79 | UInt8 codeLength;
80 | BOOL isCode; // NO for function and section names etc.
81 | BOOL isFunction; // YES if this is the first instruction in a function.
82 | }
83 | LineInfo;
84 |
85 | /* Line
86 |
87 | Represents a line of text from otool's output. For each __text section,
88 | otool is called twice- with symbolic operands(-V) and without(-v). The
89 | resulting 2 text files are each read into a doubly-linked list of Line's.
90 | Each Line contains a pointer to the corresponding Line in the other list.
91 | The reason for this approach is due to otool's inaccuracy in guessing
92 | symbols. From comments in ofile_print.c:
93 |
94 | "Both a verbose (symbolic) and non-verbose modes are supported to aid
95 | in seeing the values even if they are not correct."
96 |
97 | With both versions on hand, we can choose the better one for each Line.
98 | The criteria for choosing is defined in chooseLine:. This does result in a
99 | slight loss of info, in the rare case that otool guesses correctly for
100 | any instruction that is not a function call.
101 | */
102 | struct Line
103 | {
104 | char* chars; // C string
105 | size_t length; // C string length
106 | struct Line* next; // next line in this list
107 | struct Line* prev; // previous line in this list
108 | struct Line* alt; // "this" line in the other list
109 | LineInfo info; // details
110 | };
111 |
112 | // "typedef struct Line" doesn't work, so we do this instead.
113 | #define Line struct Line
114 |
115 | /* MachineState
116 |
117 | Saved state of the CPU registers and local copies of self. 'localSelves'
118 | is an array with 'numLocalSelves' items. 'regInfos' is an array whose
119 | count is defined by the processor-specific subclasses.
120 | */
121 | typedef struct
122 | {
123 | GPRegisterInfo* regInfos;
124 | VarInfo* localSelves;
125 | uint32_t numLocalSelves;
126 | VarInfo* localVars;
127 | uint32_t numLocalVars;
128 | }
129 | MachineState;
130 |
131 | /* BlockInfo
132 |
133 | Info pertaining to a logical block of code. 'state' is the saved
134 | MachineState that should be restored upon entering this block.
135 | */
136 | typedef struct
137 | {
138 | uint32_t beginAddress;
139 | Line* endLine;
140 | BOOL isEpilog;
141 | MachineState state;
142 | }
143 | BlockInfo;
144 |
145 | /* FunctionInfo
146 |
147 | Used for tracking the changing machine states between code blocks in a
148 | function. 'blocks' is an array with 'numBlocks' items.
149 | */
150 | typedef struct
151 | {
152 | uint32_t address;
153 | BlockInfo* blocks;
154 | uint32_t numBlocks;
155 | uint32_t genericFuncNum; // 'AnonX' if > 0
156 | }
157 | FunctionInfo;
158 |
159 | // ============================================================================
160 |
161 | @interface Exe32Processor : ExeProcessor
162 | {
163 | @protected
164 | // guts
165 | mach_header* iMachHeaderPtr; // ptr to the orig header
166 | mach_header iMachHeader; // (swapped?) copy of the header
167 | Line* iVerboseLineListHead; // linked list the first
168 | Line* iPlainLineListHead; // linked list the second
169 | Line** iLineArray;
170 | uint32_t iNumLines;
171 | uint32_t iNumCodeLines;
172 | cpu_type_t iArchSelector;
173 | uint32_t iCurrentFunctionStart;
174 |
175 | // base pointers for indirect addressing
176 | uint32_t iCurrentFuncPtr; // PPC function address
177 |
178 | // symbols that point to functions
179 | nlist* iFuncSyms;
180 | uint32_t iNumFuncSyms;
181 |
182 | // FunctionInfo array
183 | FunctionInfo* iFuncInfos;
184 | uint32_t iNumFuncInfos;
185 |
186 | // Obj-C stuff
187 | section_info* iObjcSects;
188 | uint32_t iNumObjcSects;
189 | MethodInfo* iClassMethodInfos;
190 | uint32_t iNumClassMethodInfos;
191 | BOOL iIsInstanceMethod;
192 | uint8_t iObjcVersion; // 1 for objc1
193 |
194 | // When iObjcVersion=1, this points to a objc1_32_class
195 | // When iObjcVersion=2, this points to a objc2_32_class_t
196 | objc_32_class_ptr iCurrentClass;
197 |
198 | // Only valid when iObjcVersion=1
199 | objc1_32_category* iCurrentCat;
200 | MethodInfo* iCatMethodInfos;
201 | uint32_t iNumCatMethodInfos;
202 |
203 | // Only valid when iObjcVersion=2
204 | objc2_32_ivar_t* iClassIvars;
205 | uint32_t iNumClassIvars;
206 |
207 | // Mach-O sections
208 | section_info iCStringSect;
209 | section_info iNSStringSect;
210 | section_info iClassSect;
211 | section_info iMetaClassSect;
212 | section_info iIVarSect;
213 | section_info iObjcModSect;
214 | section_info iObjcSymSect;
215 | section_info iObjcMethnameSect;
216 | section_info iObjcMethtypeSect;
217 | section_info iObjcClassnameSect;
218 | section_info iObjcClassListSect;
219 | section_info iObjcCatListSect;
220 | section_info iObjcConstSect;
221 | section_info iObjcProtoListSect;
222 | section_info iObjcSuperRefsSect;
223 | section_info iObjcClassRefsSect;
224 | section_info iObjcProtoRefsSect;
225 | section_info iObjcMsgRefsSect;
226 | section_info iObjcSelRefsSect;
227 | section_info iObjcDataSect;
228 | section_info iLit4Sect;
229 | section_info iLit8Sect;
230 | section_info iTextSect;
231 | section_info iCoalTextSect;
232 | section_info iCoalTextNTSect;
233 | section_info iConstTextSect;
234 | section_info iDataSect;
235 | section_info iCoalDataSect;
236 | section_info iCoalDataNTSect;
237 | section_info iConstDataSect;
238 | section_info iDyldSect;
239 | section_info iCFStringSect;
240 | section_info iNLSymSect;
241 | section_info iImpPtrSect;
242 | uint32_t iTextOffset;
243 | uint32_t iEndOfText;
244 | }
245 |
246 | - (id)initWithURL: (NSURL*)inURL
247 | controller: (id)inController
248 | options: (ProcOptions*)inOptions;
249 | - (void)deleteFuncInfos;
250 |
251 | // processors
252 | - (BOOL)processExe: (NSString*)inOutputFilePath;
253 | - (BOOL)populateLineLists;
254 | - (BOOL)populateLineList: (Line**)inList
255 | verbosely: (BOOL)inVerbose
256 | fromSection: (char*)inSectionName
257 | afterLine: (Line**)inLine
258 | includingPath: (BOOL)inIncludePath;
259 | - (BOOL)printDataSections;
260 | - (void)printDataSection: (section_info*)inSect
261 | toFile: (FILE*)outFile;
262 | - (BOOL)lineIsCode: (const char*)inLine;
263 |
264 | // customizers
265 | - (void)gatherLineInfos;
266 | - (void)findFunctions;
267 | - (uint32_t)addressFromLine: (const char*)inLine;
268 | - (void)processLine: (Line*)ioLine;
269 | - (void)processCodeLine: (Line**)ioLine;
270 | - (void)chooseLine: (Line**)ioLine;
271 | - (void)entabLine: (Line*)ioLine;
272 | - (BOOL)getIvarName:(char **)outName type:(char **)outType withOffset:(uint32_t)offset inClass:(objc_32_class_ptr)classPtr;
273 | - (char*)getPointer: (uint32_t)inAddr
274 | type: (UInt8*)outType;
275 |
276 | - (char*)selectorForMsgSend: (char*)outComment
277 | fromLine: (Line*)inLine;
278 |
279 | - (void)insertMD5;
280 |
281 | #ifdef OTX_DEBUG
282 | - (void)printSymbol: (nlist)inSym;
283 | - (void)printBlocks: (uint32_t)inFuncIndex;
284 | #endif
285 |
286 | @end
287 |
288 | // ----------------------------------------------------------------------------
289 | // Comparison functions for qsort(3) and bsearch(3)
290 |
291 | static int
292 | Function_Info_Compare(
293 | FunctionInfo* f1,
294 | FunctionInfo* f2)
295 | {
296 | if (f1->address < f2->address)
297 | return -1;
298 |
299 | return (f1->address > f2->address);
300 | }
301 |
302 | static int
303 | Line_Address_Compare(
304 | Line** l1,
305 | Line** l2)
306 | {
307 | if ((*l1)->info.address < (*l2)->info.address)
308 | return -1;
309 |
310 | return ((*l1)->info.address > (*l2)->info.address);
311 | }
312 |
313 | static int
314 | MethodInfo_Compare(
315 | MethodInfo* mi1,
316 | MethodInfo* mi2)
317 | {
318 | if (mi1->m.method_imp < mi2->m.method_imp)
319 | return -1;
320 |
321 | return (mi1->m.method_imp > mi2->m.method_imp);
322 | }
323 |
324 | static int
325 | MethodInfo_Compare_Swapped(
326 | MethodInfo* mi1,
327 | MethodInfo* mi2)
328 | {
329 | uint32_t imp1 = mi1->m.method_imp;
330 | uint32_t imp2 = mi2->m.method_imp;
331 |
332 | imp1 = OSSwapInt32(imp1);
333 | imp2 = OSSwapInt32(imp2);
334 |
335 | if (imp1 < imp2)
336 | return -1;
337 |
338 | return (imp1 > imp2);
339 | }
340 |
--------------------------------------------------------------------------------
/src/source/Categories/ObjcAccessors.m:
--------------------------------------------------------------------------------
1 | /*
2 | ObjcAccessors.m
3 |
4 | What the filename says.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | #import
10 |
11 | #import "ObjcAccessors.h"
12 | #import "Searchers.h"
13 |
14 | @implementation Exe32Processor(ObjcAccessors)
15 |
16 | // getObjcClassPtr:fromMethod:
17 | // ----------------------------------------------------------------------------
18 | // Given a method imp address, return the class to which it belongs. This func
19 | // is called each time a new function is detected. If that function is known
20 | // to be an Obj-C method, it's class is returned. Otherwise this returns NULL.
21 |
22 | - (BOOL)getObjcClassPtr: (objc_32_class_ptr*)outClass
23 | fromMethod: (uint32_t)inAddress;
24 | {
25 | *outClass = NULL;
26 |
27 | MethodInfo* theInfo = NULL;
28 | [self findClassMethod:&theInfo byAddress:inAddress];
29 |
30 | if (theInfo)
31 | {
32 | if (iObjcVersion < 2)
33 | {
34 | *outClass = (objc_32_class_ptr)&theInfo->oc_class;
35 | }
36 | else if (iObjcVersion == 2)
37 | {
38 | *outClass = (objc_32_class_ptr)&theInfo->oc_class2;
39 | }
40 | }
41 |
42 | return (*outClass != NULL);
43 | }
44 |
45 | // getObjcClassPtr:fromName:
46 | // ----------------------------------------------------------------------------
47 | // Given a class name, return the class itself. This func is used to tie
48 | // categories to classes. We have 2 pointers to the same name, so pointer
49 | // equality is sufficient.
50 |
51 | - (BOOL)getObjcClassPtr: (objc_32_class_ptr *)outClassPtr
52 | fromName: (const char*)inName;
53 | {
54 | if (iObjcVersion < 2)
55 | {
56 | for (uint32_t i = 0; i < iNumClassMethodInfos; i++)
57 | {
58 | uint32_t namePtr = (uint32_t)iClassMethodInfos[i].oc_class.name;
59 |
60 | if (iSwapped)
61 | namePtr = OSSwapInt32(namePtr);
62 |
63 | if ([self getPointer:namePtr type:NULL] == inName)
64 | {
65 | *outClassPtr = (objc_32_class_ptr) &iClassMethodInfos[i].oc_class;
66 | return YES;
67 | }
68 | }
69 |
70 | }
71 | else if (iObjcVersion == 2)
72 | {
73 | for (uint32_t i = 0; i < iNumClassMethodInfos; i++)
74 | {
75 | objc2_32_class_ro_t* roData = (objc2_32_class_ro_t*)(iObjcConstSect.contents +
76 | (uintptr_t)(iClassMethodInfos[i].oc_class2.data - iObjcConstSect.s.addr));
77 |
78 | uint32_t namePtr = roData->name;
79 |
80 | if (iSwapped)
81 | namePtr = OSSwapInt32(namePtr);
82 |
83 | if ([self getPointer:namePtr type:NULL] == inName)
84 | {
85 | *outClassPtr = (objc_32_class_ptr) &iClassMethodInfos[i].oc_class2;
86 | return YES;
87 | }
88 | }
89 | }
90 |
91 | *outClassPtr = NULL;
92 |
93 | return NO;
94 | }
95 |
96 | // getObjcMethod:fromAddress:
97 | // ----------------------------------------------------------------------------
98 | // Given a method imp address, return the MethodInfo for it.
99 |
100 | - (BOOL)getObjcMethod: (MethodInfo**)outMI
101 | fromAddress: (uint32_t)inAddress;
102 | {
103 | *outMI = NULL;
104 |
105 | [self findClassMethod:outMI byAddress:inAddress];
106 |
107 | if (*outMI)
108 | return YES;
109 |
110 | [self findCatMethod:outMI byAddress:inAddress];
111 |
112 | return (*outMI != NULL);
113 | }
114 |
115 | // getObjc1CatPtr:fromMethod:
116 | // ----------------------------------------------------------------------------
117 | // Given a method imp address, return the category to which it belongs.
118 |
119 | - (BOOL)getObjc1CatPtr: (objc1_32_category**)outCat
120 | fromMethod: (uint32_t)inAddress;
121 | {
122 | *outCat = NULL;
123 |
124 | MethodInfo* theInfo = NULL;
125 | [self findCatMethod:&theInfo byAddress:inAddress];
126 |
127 | if (theInfo)
128 | *outCat = &theInfo->oc_cat;
129 |
130 | return (*outCat != NULL);
131 | }
132 |
133 | // getObjc1MethodList:methods:fromAddress: (was get_method_list)
134 | // ----------------------------------------------------------------------------
135 | // Removed the truncation flag. 'left' is no longer used by the caller.
136 |
137 | - (BOOL)getObjc1MethodList: (objc1_32_method_list*)outList
138 | methods: (objc1_32_method**)outMethods
139 | fromAddress: (uint32_t)inAddress;
140 | {
141 | uint32_t left, i;
142 |
143 | if (!outList)
144 | return NO;
145 |
146 | *outList = (objc1_32_method_list){0};
147 |
148 | for (i = 0; i < iNumObjcSects; i++)
149 | {
150 | if (inAddress >= iObjcSects[i].s.addr &&
151 | inAddress < iObjcSects[i].s.addr + iObjcSects[i].s.size)
152 | {
153 | left = iObjcSects[i].s.size -
154 | (inAddress - iObjcSects[i].s.addr);
155 |
156 | if (left >= sizeof(objc1_32_method_list) - sizeof(objc1_32_method))
157 | {
158 | memcpy(outList, iObjcSects[i].contents +
159 | (inAddress - iObjcSects[i].s.addr),
160 | sizeof(objc1_32_method_list) - sizeof(objc1_32_method));
161 | *outMethods = (objc1_32_method*)(iObjcSects[i].contents +
162 | (inAddress - iObjcSects[i].s.addr) +
163 | sizeof(objc1_32_method_list) - sizeof(objc1_32_method));
164 | }
165 | else
166 | {
167 | memcpy(outList, iObjcSects[i].contents +
168 | (inAddress - iObjcSects[i].s.addr), left);
169 | *outMethods = NULL;
170 | }
171 |
172 | return YES;
173 | }
174 | }
175 |
176 | return NO;
177 | }
178 |
179 | // getObjc1Description:fromObject:type:
180 | // ----------------------------------------------------------------------------
181 | // Given an Obj-C object, return it's description.
182 |
183 | - (BOOL)getObjc1Description: (char**)outDescription
184 | fromObject: (const char*)inObject
185 | type: (UInt8)inType
186 | {
187 | *outDescription = NULL;
188 |
189 | uint32_t theValue = 0;
190 |
191 | switch (inType)
192 | {
193 | case OCStrObjectType:
194 | {
195 | nxstring_object ocString = *(nxstring_object*)inObject;
196 |
197 | if (ocString.length == 0)
198 | break;
199 |
200 | theValue = ocString.chars;
201 |
202 | break;
203 | }
204 | case OCClassType:
205 | {
206 | objc1_32_class ocClass = *(objc1_32_class*)inObject;
207 |
208 | theValue = ocClass.name ? ocClass.name : ocClass.isa;
209 |
210 | break;
211 | }
212 | case OCModType:
213 | {
214 | objc1_32_module ocMod = *(objc1_32_module*)inObject;
215 |
216 | theValue = ocMod.name;
217 |
218 | break;
219 | }
220 | case OCGenericType:
221 | theValue = *(uint32_t*)inObject;
222 |
223 | break;
224 |
225 | default:
226 | return NO;
227 | break;
228 | }
229 |
230 | if (iSwapped)
231 | theValue = OSSwapInt32(theValue);
232 |
233 | *outDescription = [self getPointer:theValue type:NULL];
234 |
235 | return (*outDescription != NULL);
236 | }
237 |
238 | // getObjc1Symtab:defs:fromModule: (was get_symtab)
239 | // ----------------------------------------------------------------------------
240 | // Removed the truncation flag. 'left' is no longer used by the caller.
241 |
242 | - (BOOL)getObjc1Symtab: (objc1_32_symtab*)outSymTab
243 | defs: (uint32_t **)outDefs
244 | fromModule: (objc1_32_module*)inModule;
245 | {
246 | if (!outSymTab)
247 | return NO;
248 |
249 | uint32_t addr = inModule->symtab;
250 | uint32_t i, left;
251 |
252 | *outSymTab = (objc1_32_symtab){0};
253 |
254 | for (i = 0; i < iNumObjcSects; i++)
255 | {
256 | if (addr >= iObjcSects[i].s.addr &&
257 | addr < iObjcSects[i].s.addr + iObjcSects[i].size)
258 | {
259 | left = iObjcSects[i].size -
260 | (addr - iObjcSects[i].s.addr);
261 |
262 | if (left >= sizeof(objc1_32_symtab) - sizeof(uint32_t))
263 | {
264 | memcpy(outSymTab, iObjcSects[i].contents +
265 | (addr - iObjcSects[i].s.addr),
266 | sizeof(objc1_32_symtab) - sizeof(uint32_t));
267 | *outDefs = (uint32_t *)(iObjcSects[i].contents +
268 | (addr - iObjcSects[i].s.addr) +
269 | sizeof(objc1_32_symtab) - sizeof(uint32_t));
270 | }
271 | else
272 | {
273 | memcpy(outSymTab, iObjcSects[i].contents +
274 | (addr - iObjcSects[i].s.addr), left);
275 | *outDefs = NULL;
276 | }
277 |
278 | return YES;
279 | }
280 | }
281 |
282 | return NO;
283 | }
284 |
285 | // getObjc1Class:fromDef: (was get_objc_class)
286 | // ----------------------------------------------------------------------------
287 |
288 | - (BOOL)getObjc1Class: (objc1_32_class*)outClass
289 | fromDef: (uint32_t)inDef;
290 | {
291 | if (iObjcVersion < 2)
292 | {
293 | uint32_t i;
294 |
295 | for (i = 0; i < iNumObjcSects; i++)
296 | {
297 | if (inDef >= iObjcSects[i].s.addr &&
298 | inDef < iObjcSects[i].s.addr + iObjcSects[i].size)
299 | {
300 | *outClass = *(objc1_32_class*)(iObjcSects[i].contents +
301 | (inDef - iObjcSects[i].s.addr));
302 |
303 | return YES;
304 | }
305 | }
306 | }
307 |
308 | return NO;
309 | }
310 |
311 | // getObjc1Category:fromDef: (was get_objc_category)
312 | // ----------------------------------------------------------------------------
313 |
314 | - (BOOL)getObjc1Category: (objc1_32_category*)outCat
315 | fromDef: (uint32_t)inDef;
316 | {
317 | if (iObjcVersion < 2)
318 | {
319 | uint32_t i;
320 |
321 | for (i = 0; i < iNumObjcSects; i++)
322 | {
323 | if (inDef >= iObjcSects[i].s.addr &&
324 | inDef < iObjcSects[i].s.addr + iObjcSects[i].s.size)
325 | {
326 | *outCat = *(objc1_32_category*)(iObjcSects[i].contents +
327 | (inDef - iObjcSects[i].s.addr));
328 |
329 | return YES;
330 | }
331 | }
332 | }
333 |
334 | return NO;
335 | }
336 |
337 | // getObjc1Class:fromName:
338 | // ----------------------------------------------------------------------------
339 | // Given a class name, return the class itself. This func is used to tie
340 | // categories to classes. We have 2 pointers to the same name, so pointer
341 | // equality is sufficient.
342 |
343 | - (BOOL)getObjc1Class: (objc1_32_class *)outClass
344 | fromName: (const char*)inName;
345 | {
346 | uint32_t i, namePtr;
347 |
348 | for (i = 0; i < iNumClassMethodInfos; i++)
349 | {
350 | namePtr = (uint32_t)iClassMethodInfos[i].oc_class.name;
351 |
352 | if (iSwapped)
353 | namePtr = OSSwapInt32(namePtr);
354 |
355 | if ([self getPointer:namePtr type:NULL] == inName)
356 | {
357 | *outClass = iClassMethodInfos[i].oc_class;
358 | return YES;
359 | }
360 | }
361 |
362 | *outClass = (objc1_32_class){0};
363 |
364 | return NO;
365 | }
366 |
367 | // getObjc1MetaClass:fromClass:
368 | // ----------------------------------------------------------------------------
369 |
370 | - (BOOL)getObjc1MetaClass: (objc1_32_class*)outClass
371 | fromClass: (objc1_32_class*)inClass;
372 | {
373 | if (iObjcVersion < 2)
374 | {
375 | if (inClass->isa >= iMetaClassSect.s.addr &&
376 | inClass->isa < iMetaClassSect.s.addr + iMetaClassSect.s.size)
377 | {
378 | *outClass = *(objc1_32_class*)(iMetaClassSect.contents +
379 | (inClass->isa - iMetaClassSect.s.addr));
380 |
381 | return YES;
382 | }
383 | }
384 |
385 | return NO;
386 | }
387 |
388 | @end
389 |
--------------------------------------------------------------------------------
/src/source/ObjcTypes.h:
--------------------------------------------------------------------------------
1 | /*
2 | ObjcTypes.h
3 |
4 | Definitions shared by GUI and CLI targets.
5 |
6 | This file is in the public domain.
7 | */
8 |
9 |
10 | #import
11 |
12 | #pragma mark -
13 | #pragma mark Shared (32-bit)
14 |
15 | typedef struct {
16 | uint32_t isa; /* Class */
17 | uint32_t superclass; /* Class */
18 | } *objc_32_class_ptr;
19 |
20 |
21 | #pragma mark -
22 | #pragma mark Objective-C 1.0 (32-bit)
23 |
24 | typedef struct {
25 | uint32_t isa; /* Class */
26 | uint32_t super_class; /* Class */
27 | uint32_t name; /* const char * */
28 | int32_t version; /* long */
29 | int32_t info; /* long */
30 | int32_t instance_size; /* long */
31 | uint32_t ivars; /* struct objc_ivar_list * */
32 | uint32_t methodLists; /* struct objc_method_list ** */
33 | uint32_t cache; /* struct objc_cache * */
34 | uint32_t protocols; /* struct objc_protocol_list * */
35 | } objc1_32_class;
36 |
37 |
38 | typedef struct {
39 | uint32_t category_name; /* char * */
40 | uint32_t class_name; /* char * */
41 | uint32_t instance_methods; /* struct objc_method_list * */
42 | uint32_t class_methods; /* struct objc_method_list * */
43 | uint32_t protocols; /* struct objc_protocol_list * */
44 | } objc1_32_category;
45 |
46 |
47 | typedef struct {
48 | uint32_t next; /* struct objc_protocol_list * */
49 | uint32_t count; /* long */
50 | uint32_t list[1]; /* Protocol * */
51 | } objc1_32_protocol_list;
52 |
53 |
54 | typedef struct {
55 | uint32_t name; /* const char * */
56 | uint32_t value; /* const char * */
57 | } objc1_32_property_attribute_t;
58 |
59 |
60 | typedef struct {
61 | uint32_t ivar_name; /* char * */
62 | uint32_t ivar_type; /* char * */
63 | uint32_t ivar_offset;
64 | } objc1_32_ivar;
65 |
66 |
67 | typedef struct {
68 | int32_t ivar_count; /* int */
69 | objc1_32_ivar ivar_list[1]; /* variable length structure */
70 | } objc1_32_ivar_list;
71 |
72 |
73 | typedef struct {
74 | uint32_t method_name; /* SEL */
75 | uint32_t method_types; /* char * */
76 | uint32_t method_imp; /* IMP */
77 | } objc1_32_method;
78 |
79 |
80 | typedef struct {
81 | int32_t obsolete; /* struct objc_method_list * */
82 | int32_t method_count; /* int */
83 | objc1_32_method method_list[1]; /* variable length structure */
84 | } objc1_32_method_list;
85 |
86 |
87 | typedef struct {
88 | uint32_t name; /* SEL */
89 | uint32_t *types; /* char * */
90 | } objc1_32_method_description;
91 |
92 |
93 | typedef struct {
94 | uint32_t version; /* unsigned long */
95 | uint32_t size; /* unsigned long */
96 | uint32_t name; /* const char * */
97 | uint32_t symtab; /* objc_symtab * */
98 | } objc1_32_module;
99 |
100 |
101 | typedef struct {
102 | uint32_t sel_ref_cnt; /* unsigned long */
103 | uint32_t refs; /* SEL * */
104 | uint16_t cls_def_cnt; /* unsigned short */
105 | uint16_t cat_def_cnt; /* unsigned short */
106 | uint32_t defs[1]; /* void *, variable size */
107 | } objc1_32_symtab;
108 |
109 |
110 | typedef struct {
111 | uint32_t mask; /* unsigned int, total = mask + 1 */
112 | uint32_t occupied; /* unsigned int */
113 | uint32_t buckets[1]; /* Method */
114 | } objc1_32_cache;
115 |
116 |
117 | void swap_objc1_32_module(objc1_32_module *module);
118 | void swap_objc1_32_symtab(objc1_32_symtab *symtab);
119 | void swap_objc1_32_class(objc1_32_class *cls);
120 | void swap_objc1_32_ivar(objc1_32_ivar *ivar);
121 | void swap_objc1_32_category(objc1_32_category *category);
122 | void swap_objc1_32_method_list(objc1_32_method_list *methodList);
123 | void swap_objc1_32_method(objc1_32_method *method);
124 |
125 |
126 | #pragma mark -
127 | #pragma mark Objective-C 1.0 (64-bit)
128 |
129 | typedef struct {
130 | uint64_t isa; /* Class */
131 | uint64_t super_class; /* Class */
132 | uint64_t name; /* const char * */
133 | int64_t version; /* long */
134 | int64_t info; /* long */
135 | int64_t instance_size; /* long */
136 | uint64_t ivars; /* struct objc_ivar_list * */
137 | uint64_t methodLists; /* struct objc_method_list ** */
138 | uint64_t cache; /* struct objc_cache * */
139 | uint64_t protocols; /* struct objc_protocol_list * */
140 | } objc1_64_class;
141 |
142 |
143 | typedef struct {
144 | uint64_t category_name; /* char * */
145 | uint64_t class_name; /* char * */
146 | uint64_t instance_methods; /* struct objc_method_list * */
147 | uint64_t class_methods; /* struct objc_method_list * */
148 | uint64_t protocols; /* struct objc_protocol_list * */
149 | } objc1_64_category;
150 |
151 |
152 | typedef struct {
153 | uint64_t next; /* struct objc_protocol_list * */
154 | uint64_t count; /* long */
155 | uint64_t list[1]; /* Protocol * */
156 | } objc1_64_protocol_list;
157 |
158 |
159 | typedef struct {
160 | uint64_t name; /* const char * */
161 | uint64_t value; /* const char * */
162 | } objc1_64_property_attribute_t;
163 |
164 |
165 | typedef struct {
166 | uint64_t ivar_name; /* char * */
167 | uint64_t ivar_type; /* char * */
168 | uint64_t ivar_offset;
169 | uint32_t space;
170 | } objc1_64_ivar;
171 |
172 |
173 | typedef struct {
174 | int32_t ivar_count; /* int */
175 | int32_t space; /* int */
176 | objc1_64_ivar ivar_list[1]; /* variable length structure */
177 | } objc1_64_ivar_list;
178 |
179 |
180 | typedef struct {
181 | uint64_t method_name; /* SEL */
182 | uint64_t method_types; /* char * */
183 | uint64_t method_imp; /* IMP */
184 | } objc1_64_method;
185 |
186 |
187 | typedef struct {
188 | int64_t obsolete; /* struct objc_method_list * */
189 | int64_t method_count; /* int */
190 | int32_t space; /* int */
191 | objc1_64_method method_list[1]; /* variable length structure */
192 | } objc1_64_method_list;
193 |
194 |
195 | typedef struct {
196 | uint64_t name; /* SEL */
197 | uint64_t *types; /* char * */
198 | } objc1_64_method_description;
199 |
200 |
201 | typedef struct {
202 | uint64_t version; /* unsigned long */
203 | uint64_t size; /* unsigned long */
204 | uint64_t name; /* const char * */
205 | uint64_t symtab; /* objc_symtab * */
206 | } objc1_64_module;
207 |
208 |
209 | typedef struct {
210 | uint64_t sel_ref_cnt; /* unsigned long */
211 | uint64_t refs; /* SEL * */
212 | uint16_t cls_def_cnt; /* unsigned short */
213 | uint16_t cat_def_cnt; /* unsigned short */
214 | uint64_t defs[1]; /* void *, variable size */
215 | } objc1_64_symtab;
216 |
217 |
218 | typedef struct {
219 | uint32_t mask; /* unsigned int, total = mask + 1 */
220 | uint32_t occupied; /* unsigned int */
221 | uint64_t buckets[1]; /* Method */
222 | } objc1_64_cache;
223 |
224 |
225 | void swap_objc1_64_module(objc1_64_module *module);
226 | void swap_objc1_64_symtab(objc1_64_symtab *symtab);
227 | void swap_objc1_64_class(objc1_64_class *cls);
228 | void swap_objc1_64_ivar(objc1_64_ivar *ivar);
229 | void swap_objc1_64_category(objc1_64_category *category);
230 | void swap_objc1_64_method_list(objc1_64_method_list *methodList);
231 | void swap_objc1_64_method(objc1_64_method *method);
232 |
233 |
234 | /* ----------------------------------------------------------------------------
235 | Objective-C 2.0 private structs
236 |
237 | Copied and modified here because-
238 | The structs are private, unlike the earlier runtime.
239 | otx being 32-bit, the pointer fields need to be explicit about their size.
240 |
241 | For reference, the 'FOO' in 'typedef struct FOO' is the original private struct
242 | name, and the original pointer field types are saved as comments.
243 | */
244 |
245 |
246 | #pragma mark -
247 | #pragma mark Objective-C 2.0 (32-bit)
248 |
249 | typedef struct {
250 | uint32_t name; // SEL
251 | uint32_t types; // const char *
252 | uint32_t imp; // IMP
253 | } objc2_32_method_t;
254 |
255 |
256 | typedef struct {
257 | uint32_t entsize;
258 | uint32_t count;
259 | objc2_32_method_t first;
260 | } objc2_32_method_list_t;
261 |
262 |
263 | typedef struct {
264 | uint32_t imp; // IMP
265 | uint32_t sel; // SEL
266 | } objc2_32_message_ref_t;
267 |
268 |
269 | typedef struct {
270 | // *offset is 64-bit by accident even though other
271 | // fields restrict total instance size to 32-bit.
272 | uint64_t offset; // uintptr_t *
273 | uint32_t name; // const char *
274 | uint32_t type; // const char *
275 | uint32_t alignment;
276 | uint32_t size;
277 | } objc2_32_ivar_t;
278 |
279 |
280 | typedef struct {
281 | uint32_t entsize;
282 | uint32_t count;
283 | objc2_32_ivar_t first;
284 | } objc2_32_ivar_list_t;
285 |
286 |
287 | typedef struct {
288 | uint32_t isa; // id
289 | uint32_t name; // const char *
290 | uint32_t protocols; // struct objc2_protocol_list_t *
291 | uint32_t instanceMethods; // objc2_method_list_t *
292 | uint32_t classMethods; // objc2_method_list_t *
293 | uint32_t optionalInstanceMethods; // objc2_method_list_t *
294 | uint32_t optionalClassMethods; // objc2_method_list_t *
295 | uint32_t instanceProperties; // struct objc2_property_list *
296 | } objc2_32_protocol_t;
297 |
298 |
299 | typedef struct {
300 | // count is 64-bit by accident.
301 | uint64_t count; // uintptr_t
302 | uint32_t list[0]; // objc2_protocol_t *
303 | } objc2_32_protocol_list_t;
304 |
305 |
306 | typedef struct {
307 | uint32_t flags;
308 | uint32_t instanceStart;
309 | uint32_t instanceSize;
310 |
311 | uint32_t ivarLayout; // const uint8_t *
312 |
313 | uint32_t name; // const char *
314 | uint32_t baseMethods; // const objc2_method_list_t *
315 | uint32_t baseProtocols; // const objc2_protocol_list_t *
316 | uint32_t ivars; // const objc2_ivar_list_t *
317 |
318 | uint32_t weakIvarLayout; // const uint8_t *
319 | uint32_t baseProperties; // const struct objc2_property_list *
320 | } objc2_32_class_ro_t;
321 |
322 |
323 | typedef struct {
324 | uint32_t flags;
325 | uint32_t version;
326 |
327 | uint32_t ro; // const objc2_class_ro_t *
328 |
329 | uint32_t methods; // chained_method_list *
330 | uint32_t properties; // chained_property_list *
331 | uint32_t protocols; // objc2_protocol_list_t **
332 |
333 | uint32_t firstSubclass; // objc2_class_t *
334 | uint32_t nextSiblingClass; // objc2_class_t *
335 | } objc2_32_class_rw_t;
336 |
337 |
338 | typedef struct {
339 | uint32_t isa; // objc2_class_t *
340 | uint32_t superclass; // objc2_class_t *
341 | uint32_t cache; // Cache
342 | uint32_t vtable; // IMP *
343 | uint32_t data; // objc2_class_rw_t *
344 | } objc2_32_class_t;
345 |
346 |
347 | extern void swap_objc2_32_class(objc2_32_class_t *cls);
348 | extern void swap_objc2_32_method(objc2_32_method_t *method);
349 | extern void swap_objc2_32_ivar(objc2_32_ivar_t* ivar);
350 |
351 |
352 | #pragma mark -
353 | #pragma mark Objective-C 2.0 (64-bit)
354 |
355 | typedef struct {
356 | uint64_t name; // SEL
357 | uint64_t types; // const char *
358 | uint64_t imp; // IMP
359 | } objc2_64_method_t;
360 |
361 |
362 | typedef struct {
363 | uint32_t entsize;
364 | uint32_t count;
365 | objc2_64_method_t first;
366 | } objc2_64_method_list_t;
367 |
368 |
369 | typedef struct {
370 | uint64_t imp; // IMP
371 | uint64_t sel; // SEL
372 | } objc2_64_message_ref_t;
373 |
374 |
375 | typedef struct {
376 | // *offset is 64-bit by accident even though other
377 | // fields restrict total instance size to 32-bit.
378 | uint64_t offset; // uintptr_t *
379 | uint64_t name; // const char *
380 | uint64_t type; // const char *
381 | uint32_t alignment;
382 | uint32_t size;
383 | } objc2_64_ivar_t;
384 |
385 |
386 | typedef struct {
387 | uint32_t entsize;
388 | uint32_t count;
389 | objc2_64_ivar_t first;
390 | } objc2_64_ivar_list_t;
391 |
392 |
393 | typedef struct {
394 | uint64_t isa; // id
395 | uint64_t name; // const char *
396 | uint64_t protocols; // struct objc2_protocol_list_t *
397 | uint64_t instanceMethods; // objc2_method_list_t *
398 | uint64_t classMethods; // objc2_method_list_t *
399 | uint64_t optionalInstanceMethods; // objc2_method_list_t *
400 | uint64_t optionalClassMethods; // objc2_method_list_t *
401 | uint64_t instanceProperties; // struct objc2_property_list *
402 | } objc2_64_protocol_t;
403 |
404 |
405 | typedef struct {
406 | uint64_t count; // uintptr_t - count is 64-bit by accident.
407 | uint64_t list[0]; // objc2_protocol_t *
408 | } objc2_64_protocol_list_t;
409 |
410 |
411 | typedef struct {
412 | uint32_t flags;
413 | uint32_t instanceStart;
414 | uint32_t instanceSize;
415 | uint32_t reserved;
416 |
417 | uint64_t ivarLayout; // const uint8_t *
418 |
419 | uint64_t name; // const char *
420 | uint64_t baseMethods; // const objc2_method_list_t *
421 | uint64_t baseProtocols; // const objc2_protocol_list_t *
422 | uint64_t ivars; // const objc2_ivar_list_t *
423 |
424 | uint64_t weakIvarLayout; // const uint8_t *
425 | uint64_t baseProperties; // const struct objc2_property_list *
426 | } objc2_64_class_ro_t;
427 |
428 |
429 | typedef struct {
430 | uint32_t flags;
431 | uint32_t version;
432 |
433 | uint64_t ro; // const objc2_class_ro_t *
434 |
435 | uint64_t methods; // chained_method_list *
436 | uint64_t properties; // chained_property_list *
437 | uint64_t protocols; // objc2_protocol_list_t **
438 |
439 | uint64_t firstSubclass; // objc2_class_t *
440 | uint64_t nextSiblingClass; // objc2_class_t *
441 | } objc2_64_class_rw_t;
442 |
443 |
444 | typedef struct {
445 | uint64_t isa; // objc2_class_t *
446 | uint64_t superclass; // objc2_class_t *
447 | uint64_t cache; // Cache
448 | uint64_t vtable; // IMP *
449 | uint64_t data; // objc2_class_rw_t *
450 | } objc2_64_class_t;
451 |
452 | extern void swap_objc2_64_class(objc2_64_class_t *cls);
453 | extern void swap_objc2_64_method(objc2_64_method_t *method);
454 | extern void swap_objc2_64_ivar(objc2_64_ivar_t *ivar);
455 |
456 |
--------------------------------------------------------------------------------
/src/source/SyscallStrings.h:
--------------------------------------------------------------------------------
1 | /*
2 | SyscallStrings.h
3 |
4 | Adapted from .
5 |
6 | This file is in the public domain.
7 | */
8 |
9 | // Using 0 instead of "" for empty strings results in a nil pointer
10 | // instead of a pointer to zeroes.
11 |
12 | static const char* gSysCalls[371] = {
13 | "syscall", // 0
14 | "exit", // 1
15 | "fork", // 2
16 | "read", // 3
17 | "write", // 4
18 | "open", // 5
19 | "close", // 6
20 | "wait4", // 7
21 | 0, // 8
22 | "link", // 9
23 | "unlink", // 10
24 | 0, // 11
25 | "chdir", // 12
26 | "fchdir", // 13
27 | "mknod", // 14
28 | "chmod", // 15
29 | "chown", // 16
30 | "obreak", // 17
31 | "getfsstat", // 18
32 | 0, // 19
33 | "getpid", // 20
34 | 0,0, // 21, 2
35 | "setuid", // 23
36 | "getuid", // 24
37 | "geteuid", // 25
38 | "ptrace", // 26
39 | "recvmsg", // 27
40 | "sendmsg", // 28
41 | "recvfrom", // 29
42 | "accept", // 30
43 | "getpeername", // 31
44 | "getsockname", // 32
45 | "access", // 33
46 | "chflags", // 34
47 | "fchflags", // 35
48 | "sync", // 36
49 | "kill", // 37
50 | 0, // 38
51 | "getppid", // 39
52 | 0, // 40
53 | "dup", // 41
54 | "pipe", // 42
55 | "getegid", // 43
56 | "profil", // 44
57 | "ktrace", // 45
58 | "sigaction", // 46
59 | "getgid", // 47
60 | "sigprocmask", // 48
61 | "getlogin", // 49
62 | "setlogin", // 50
63 | "acct", // 51
64 | "sigpending", // 52
65 | "sigaltstack", // 53
66 | "ioctl", // 54
67 | "reboot", // 55
68 | "revoke", // 56
69 | "symlink", // 57
70 | "readlink", // 58
71 | "execve", // 59
72 | "umask", // 60
73 | "chroot", // 61
74 | 0,0,0, // 62 - 64
75 | "msync", // 65
76 | "vfork", // 66
77 | 0,0, // 67, 8
78 | "sbrk", // 69
79 | "sstk", // 70
80 | 0, // 71
81 | "ovadvise", // 72
82 | "munmap", // 73
83 | "mprotect", // 74
84 | "madvise", // 75
85 | 0,0, // 76, 7
86 | "mincore", // 78
87 | "getgroups", // 79
88 | "setgroups", // 80
89 | "getpgrp", // 81
90 | "setpgid", // 82
91 | "setitimer", // 83
92 | 0, // 84
93 | "swapon", // 85
94 | "getitimer", // 86
95 | 0,0, // 87, 8
96 | "getdtablesize", // 89
97 | "dup2", // 90
98 | 0, // 91
99 | "fcntl", // 92
100 | "select", // 93
101 | 0, // 94
102 | "fsync", // 95
103 | "setpriority", // 96
104 | "socket", // 97
105 | "connect", // 98
106 | 0, // 99
107 | "getpriority", // 100
108 | 0,0,0, // 101 - 103
109 | "bind", // 104
110 | "setsockopt", // 105
111 | "listen", // 106
112 | 0,0,0,0, // 107 - 110
113 | "sigsuspend", // 111
114 | 0,0,0,0, // 112 - 115
115 | "gettimeofday", // 116
116 | "getrusage", // 117
117 | "getsockopt", // 118
118 | 0, // 119
119 | "readv", // 120
120 | "writev", // 121
121 | "settimeofday", // 122
122 | "fchown", // 123
123 | "fchmod", // 124
124 | 0,0,0, // 125 - 127
125 | "rename", // 128
126 | 0,0, // 129, 130
127 | "flock", // 131
128 | "mkfifo", // 132
129 | "sendto", // 133
130 | "shutdown", // 134
131 | "socketpair", // 135
132 | "mkdir", // 136
133 | "rmdir", // 137
134 | "utimes", // 138
135 | "futimes", // 139
136 | "adjtime", // 140
137 | 0,0,0,0,0,0, // 141 - 146
138 | "setsid", // 147
139 | 0,0,0, // 148 - 150
140 | "getpgid", // 151
141 | "setprivexec", // 152
142 | "pread", // 153
143 | "pwrite", // 154
144 | "nfssvc", // 155
145 | 0, // 156
146 | "statfs", // 157
147 | "fstatfs", // 158
148 | "unmount", // 159
149 | 0, // 160
150 | "getfh", // 161
151 | 0,0,0, // 162 - 164
152 | "quotactl", // 165
153 | 0, // 166
154 | "mount", // 167
155 | 0,0, // 168, 9
156 | "table", // 170
157 | 0,0, // 171, 2
158 | "waitid", // 173
159 | 0,0, // 174, 5
160 | "add_profil", // 176
161 | 0,0,0, // 177 - 179
162 | "kdebug_trace", // 180
163 | "setgid", // 181
164 | "setegid", // 182
165 | "seteuid", // 183
166 | "sigreturn", // 184
167 | "chud", // 185
168 | 0,0, // 186, 7
169 | "stat", // 188
170 | "fstat", // 189
171 | "lstat", // 190
172 | "pathconf", // 191
173 | "fpathconf", // 192
174 | "getfsstat", // 193
175 | "getrlimit", // 194
176 | "setrlimit", // 195
177 | "getdirentries", // 196
178 | "mmap", // 197
179 | 0, // 198
180 | "lseek", // 199
181 | "truncate", // 200
182 | "ftruncate", // 201
183 | "__sysctl", // 202
184 | "mlock", // 203
185 | "munlock", // 204
186 | "undelete", // 205
187 | "ATsocket", // 206
188 | "ATgetmsg", // 207
189 | "ATputmsg", // 208
190 | "ATPsndreq", // 209
191 | "ATPsndrsp", // 210
192 | "ATPgetreq", // 211
193 | "ATPgetrsp", // 212
194 | 0, // 213
195 | "kqueue_from_portset_np", // 214
196 | "kqueue_portset_np", // 215
197 | "mkcomplex", // 216
198 | "statv", // 217
199 | "lstatv", // 218
200 | "fstatv", // 219
201 | "getattrlist", // 220
202 | "setattrlist", // 221
203 | "getdirentriesattr", // 222
204 | "exchangedata", // 223
205 | "checkuseraccess", // 224
206 | "searchfs", // 225
207 | "delete", // 226
208 | "copyfile", // 227
209 | 0,0, // 228, 9
210 | "poll", // 230
211 | "watchevent", // 231
212 | "waitevent", // 232
213 | "modwatch", // 233
214 | "getxattr", // 234
215 | "fgetxattr", // 235
216 | "setxattr", // 236
217 | "fsetxattr", // 237
218 | "removexattr", // 238
219 | "fremovexattr", // 239
220 | "listxattr", // 240
221 | "flistxattr", // 241
222 | "fsctl", // 242
223 | "initgroups", // 243
224 | 0,0,0, // 244 - 246
225 | "nfsclnt", // 247
226 | "fhopen", // 248
227 | 0, // 249
228 | "minherit", // 250
229 | "semsys", // 251
230 | "msgsys", // 252
231 | "shmsys", // 253
232 | "semctl", // 254
233 | "semget", // 255
234 | "semop", // 256
235 | "semconfig", // 257
236 | "msgctl", // 258
237 | "msgget", // 259
238 | "msgsnd", // 260
239 | "msgrcv", // 261
240 | "shmat", // 262
241 | "shmctl", // 263
242 | "shmdt", // 264
243 | "shmget", // 265
244 | "shm_open", // 266
245 | "shm_unlink", // 267
246 | "sem_open", // 268
247 | "sem_close", // 269
248 | "sem_unlink", // 270
249 | "sem_wait", // 271
250 | "sem_trywait", // 272
251 | "sem_post", // 273
252 | "sem_getvalue", // 274
253 | "sem_init", // 275
254 | "sem_destroy", // 276
255 | "open_extended", // 277
256 | "umask_extended", // 278
257 | "stat_extended", // 279
258 | "lstat_extended", // 280
259 | "fstat_extended", // 281
260 | "chmod_extended", // 282
261 | "fchmod_extended", // 283
262 | "access_extended", // 284
263 | "settid", // 285
264 | "gettid", // 286
265 | "setsgroups", // 287
266 | "getsgroups", // 288
267 | "setwgroups", // 289
268 | "getwgroups", // 290
269 | "mkfifo_extended", // 291
270 | "mkdir_extended", // 292
271 | "identitysvc", // 293
272 | 0,0, // 294, 5
273 | "load_shared_file", // 296
274 | "reset_shared_file", // 297
275 | "new_system_shared_regions", // 298
276 | "shared_region_map_file_np", // 299
277 | "shared_region_make_private_np", // 300
278 | 0,0,0,0,0,0,0,0,0, // 301 - 309
279 | "getsid", // 310
280 | "settid_with_pid", // 311
281 | 0, // 312
282 | "aio_fsync", // 313
283 | "aio_return", // 314
284 | "aio_suspend", // 315
285 | "aio_cancel", // 316
286 | "aio_error", // 317
287 | "aio_read", // 318
288 | "aio_write", // 319
289 | "lio_listio", // 320
290 | 0,0,0, // 321 - 323
291 | "mlockall", // 324
292 | "munlockall", // 325
293 | 0, // 326
294 | "issetugid", // 327
295 | "__pthread_kill", // 328
296 | "pthread_sigmask", // 329
297 | "sigwait", // 330
298 | "__disable_threadsignal", // 331
299 | "__pthread_markcancel", // 332
300 | "__pthread_canceled", // 333
301 | "__semwait_signal", // 334
302 | "utrace", // 335
303 | "proc_info", // 336
304 | 0,0,0,0,0,0,0,0,0,0,0,0,0, // 337 - 349
305 | "audit", // 350
306 | "auditon", // 351
307 | 0, // 352
308 | "getauid", // 353
309 | "setauid", // 354
310 | "getaudit", // 355
311 | "setaudit", // 356
312 | "getaudit_addr", // 357
313 | "setaudit_addr", // 358
314 | "auditctl", // 359
315 | 0,0, // 361, 2
316 | "kqueue", // 362
317 | "kevent", // 363
318 | "lchown", // 364
319 | "stack_snapshot", // 365
320 | 0,0,0,0, // 366 - 369
321 | "MAXSYSCALL" // 370
322 | };
323 |
--------------------------------------------------------------------------------