├── .gitignore ├── LICENSE ├── RDInjectionWizard.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── RDInjectionWizard ├── RDIWDeamonMaster.h ├── RDIWDeamonMaster.m ├── RDInjectionWizard-Info.plist ├── RDInjectionWizard-Prefix.pch ├── RDInjectionWizard.h ├── RDInjectionWizard.m └── en.lproj │ └── InfoPlist.strings ├── RDInjectionWizardTests ├── RDIWDaemonMasterTests.m ├── RDInjectionWizardTests-Info.plist ├── RDInjectionWizardTests.m ├── RDInjectionWizardTestsHost │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── RDInjectionWizardTestsHost-Info.plist │ ├── RDInjectionWizardTestsHost-Prefix.pch │ └── main.m ├── demoTarget64 │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── demoTarget64-Info.plist │ └── main.m └── libtestnoop64 │ ├── libtestnoop.h │ └── libtestnoop.m ├── README.md ├── injector ├── main.c ├── me.rodionovd.RDInjectionWizard.injector-Info.plist ├── me.rodionovd.RDInjectionWizard.injector-Launchd.plist └── rd_inject_library │ ├── rd_inject_library.c │ └── rd_inject_library.h └── unload_deamon.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # CocoaPods 2 | Pods/ 3 | # Finder 4 | .DS_Store 5 | # Xcode 6 | build/ 7 | *.pbxuser 8 | !default.pbxuser 9 | *.mode1v3 10 | !default.mode1v3 11 | *.mode2v3 12 | !default.mode2v3 13 | *.perspectivev3 14 | !default.perspectivev3 15 | xcuserdata 16 | *.xccheckout 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | *.xcuserstate 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Dmitry Rodionov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /RDInjectionWizard.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A2E2298197170BF00255B00 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0A2E2296197170BF00255B00 /* InfoPlist.strings */; }; 11 | 0A2E229C197170BF00255B00 /* RDInjectionWizard.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A2E229B197170BF00255B00 /* RDInjectionWizard.m */; }; 12 | 0A2E22A3197170BF00255B00 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A2E22A2197170BF00255B00 /* XCTest.framework */; }; 13 | 0A2E22A4197170BF00255B00 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A2E228D197170BF00255B00 /* Cocoa.framework */; }; 14 | 0A2E22A7197170BF00255B00 /* RDInjectionWizard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A2E228A197170BF00255B00 /* RDInjectionWizard.framework */; }; 15 | 0A2E22AF197170BF00255B00 /* RDInjectionWizardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A2E22AE197170BF00255B00 /* RDInjectionWizardTests.m */; }; 16 | 0A533F62199BA6DF0065F2D6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0A0C83001982E55700CBA7EC /* MainMenu.xib */; }; 17 | 0A61A27B1972AF0300728FAB /* RDIWDaemonMasterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A61A27A1972AF0300728FAB /* RDIWDaemonMasterTests.m */; }; 18 | 0A891D2B1980FE8A00CAF525 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A891D2A1980FE8A00CAF525 /* AppDelegate.m */; }; 19 | 0A891D321980FEA100CAF525 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A891D301980FEA100CAF525 /* main.m */; }; 20 | 0A8D0F5D197176960075B0E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A2E228D197170BF00255B00 /* Cocoa.framework */; }; 21 | 0A8D0F65197176960075B0E2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A8D0F64197176960075B0E2 /* main.m */; }; 22 | 0A8D0F6C197176960075B0E2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A8D0F6B197176960075B0E2 /* AppDelegate.m */; }; 23 | 0A8D0F8C197178210075B0E2 /* RDInjectionWizard.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A2E229A197170BF00255B00 /* RDInjectionWizard.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | 0A8D0F8D197178300075B0E2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A2E2290197170BF00255B00 /* Foundation.framework */; }; 25 | 0A8D0F901971860B0075B0E2 /* RDIWDeamonMaster.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A8D0F8E1971860B0075B0E2 /* RDIWDeamonMaster.h */; }; 26 | 0A8D0F911971860B0075B0E2 /* RDIWDeamonMaster.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A8D0F8F1971860B0075B0E2 /* RDIWDeamonMaster.m */; }; 27 | 0AAEE16619742203008C231A /* libtestnoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AAEE16519742203008C231A /* libtestnoop.h */; }; 28 | 0AAEE16819742203008C231A /* libtestnoop.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AAEE16719742203008C231A /* libtestnoop.m */; }; 29 | 0AAEE18419742291008C231A /* libtestnoop64.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 0AAEE16319742203008C231A /* libtestnoop64.dylib */; }; 30 | 0AAEE1BF19743FF3008C231A /* demoTarget64.app in Resources */ = {isa = PBXBuildFile; fileRef = 0AAEE1BD19743F95008C231A /* demoTarget64.app */; }; 31 | 0AEA0BF31972990700452D6E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 0AEA0BF21972990700452D6E /* main.c */; }; 32 | 0AFCE4441975745200D51EE6 /* rd_inject_library.c in Sources */ = {isa = PBXBuildFile; fileRef = 0AFCE4411975745200D51EE6 /* rd_inject_library.c */; }; 33 | 0AFEB84D197288B900BE2968 /* me.rodionovd.RDInjectionWizard.injector in Copy the XPC service */ = {isa = PBXBuildFile; fileRef = 0AFEB8401972876B00BE2968 /* me.rodionovd.RDInjectionWizard.injector */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | 0A0C83061982E58900CBA7EC /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 0A2E2289197170BF00255B00; 42 | remoteInfo = RDInjectionWizard; 43 | }; 44 | 0A0C83081982E58900CBA7EC /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = 0A2E2289197170BF00255B00; 49 | remoteInfo = RDInjectionWizard; 50 | }; 51 | 0A0C830A1982E66700CBA7EC /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = 0A8D0F5B197176950075B0E2; 56 | remoteInfo = RDInjectionWizardTestsHost; 57 | }; 58 | 0A2E22A5197170BF00255B00 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = 0A2E2289197170BF00255B00; 63 | remoteInfo = RDInjectionWizard; 64 | }; 65 | 0AA491C41983980A0096C481 /* PBXContainerItemProxy */ = { 66 | isa = PBXContainerItemProxy; 67 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 68 | proxyType = 1; 69 | remoteGlobalIDString = 0A2E2289197170BF00255B00; 70 | remoteInfo = RDInjectionWizard; 71 | }; 72 | 0AA491C61983980A0096C481 /* PBXContainerItemProxy */ = { 73 | isa = PBXContainerItemProxy; 74 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 75 | proxyType = 1; 76 | remoteGlobalIDString = 0A2E2289197170BF00255B00; 77 | remoteInfo = RDInjectionWizard; 78 | }; 79 | 0AAEE1861974229A008C231A /* PBXContainerItemProxy */ = { 80 | isa = PBXContainerItemProxy; 81 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 82 | proxyType = 1; 83 | remoteGlobalIDString = 0AAEE16219742203008C231A; 84 | remoteInfo = libtestnoop64; 85 | }; 86 | 0AAEE18A19742329008C231A /* PBXContainerItemProxy */ = { 87 | isa = PBXContainerItemProxy; 88 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 89 | proxyType = 1; 90 | remoteGlobalIDString = 0A2E2289197170BF00255B00; 91 | remoteInfo = RDInjectionWizard; 92 | }; 93 | 0AAEE1C019744008008C231A /* PBXContainerItemProxy */ = { 94 | isa = PBXContainerItemProxy; 95 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 96 | proxyType = 1; 97 | remoteGlobalIDString = 0AAEE1B319743F95008C231A; 98 | remoteInfo = demoTarget64; 99 | }; 100 | 0AFEB84B197288B100BE2968 /* PBXContainerItemProxy */ = { 101 | isa = PBXContainerItemProxy; 102 | containerPortal = 0A2E2281197170BF00255B00 /* Project object */; 103 | proxyType = 1; 104 | remoteGlobalIDString = 0AFEB83F1972876B00BE2968; 105 | remoteInfo = injector; 106 | }; 107 | /* End PBXContainerItemProxy section */ 108 | 109 | /* Begin PBXCopyFilesBuildPhase section */ 110 | 0A8D0FA71971A10E0075B0E2 /* Copy the XPC service */ = { 111 | isa = PBXCopyFilesBuildPhase; 112 | buildActionMask = 2147483647; 113 | dstPath = LaunchServices; 114 | dstSubfolderSpec = 1; 115 | files = ( 116 | 0AFEB84D197288B900BE2968 /* me.rodionovd.RDInjectionWizard.injector in Copy the XPC service */, 117 | ); 118 | name = "Copy the XPC service"; 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | 0AFEB83E1972876B00BE2968 /* CopyFiles */ = { 122 | isa = PBXCopyFilesBuildPhase; 123 | buildActionMask = 2147483647; 124 | dstPath = /usr/share/man/man1/; 125 | dstSubfolderSpec = 0; 126 | files = ( 127 | ); 128 | runOnlyForDeploymentPostprocessing = 1; 129 | }; 130 | /* End PBXCopyFilesBuildPhase section */ 131 | 132 | /* Begin PBXFileReference section */ 133 | 0A0C83011982E55700CBA7EC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 134 | 0A2E228A197170BF00255B00 /* RDInjectionWizard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RDInjectionWizard.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 135 | 0A2E228D197170BF00255B00 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 136 | 0A2E2290197170BF00255B00 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 137 | 0A2E2291197170BF00255B00 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 138 | 0A2E2292197170BF00255B00 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 139 | 0A2E2295197170BF00255B00 /* RDInjectionWizard-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RDInjectionWizard-Info.plist"; sourceTree = ""; }; 140 | 0A2E2297197170BF00255B00 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 141 | 0A2E2299197170BF00255B00 /* RDInjectionWizard-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RDInjectionWizard-Prefix.pch"; sourceTree = ""; }; 142 | 0A2E229A197170BF00255B00 /* RDInjectionWizard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RDInjectionWizard.h; sourceTree = ""; }; 143 | 0A2E229B197170BF00255B00 /* RDInjectionWizard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RDInjectionWizard.m; sourceTree = ""; }; 144 | 0A2E22A1197170BF00255B00 /* RDInjectionWizardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RDInjectionWizardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 145 | 0A2E22A2197170BF00255B00 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 146 | 0A2E22AA197170BF00255B00 /* RDInjectionWizardTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RDInjectionWizardTests-Info.plist"; sourceTree = ""; }; 147 | 0A2E22AE197170BF00255B00 /* RDInjectionWizardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RDInjectionWizardTests.m; sourceTree = ""; }; 148 | 0A61A27A1972AF0300728FAB /* RDIWDaemonMasterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RDIWDaemonMasterTests.m; sourceTree = ""; }; 149 | 0A891D291980FE8A00CAF525 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RDInjectionWizardTests/demoTarget64/AppDelegate.h; sourceTree = SOURCE_ROOT; }; 150 | 0A891D2A1980FE8A00CAF525 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = RDInjectionWizardTests/demoTarget64/AppDelegate.m; sourceTree = SOURCE_ROOT; }; 151 | 0A891D301980FEA100CAF525 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RDInjectionWizardTests/demoTarget64/main.m; sourceTree = SOURCE_ROOT; }; 152 | 0A8D0F5C197176950075B0E2 /* RDInjectionWizardTestsHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RDInjectionWizardTestsHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; 153 | 0A8D0F60197176960075B0E2 /* RDInjectionWizardTestsHost-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RDInjectionWizardTestsHost-Info.plist"; sourceTree = ""; }; 154 | 0A8D0F64197176960075B0E2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 155 | 0A8D0F66197176960075B0E2 /* RDInjectionWizardTestsHost-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RDInjectionWizardTestsHost-Prefix.pch"; sourceTree = ""; }; 156 | 0A8D0F6A197176960075B0E2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 157 | 0A8D0F6B197176960075B0E2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 158 | 0A8D0F8E1971860B0075B0E2 /* RDIWDeamonMaster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RDIWDeamonMaster.h; sourceTree = ""; }; 159 | 0A8D0F8F1971860B0075B0E2 /* RDIWDeamonMaster.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RDIWDeamonMaster.m; sourceTree = ""; }; 160 | 0A8D0F9719719F890075B0E2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 161 | 0AAEE16319742203008C231A /* libtestnoop64.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libtestnoop64.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 162 | 0AAEE16519742203008C231A /* libtestnoop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libtestnoop.h; sourceTree = ""; }; 163 | 0AAEE16719742203008C231A /* libtestnoop.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = libtestnoop.m; sourceTree = ""; }; 164 | 0AAEE1BD19743F95008C231A /* demoTarget64.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = demoTarget64.app; sourceTree = BUILT_PRODUCTS_DIR; }; 165 | 0AB8FD9B1981002800691034 /* demoTarget64-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "demoTarget64-Info.plist"; path = "RDInjectionWizardTests/demoTarget64/demoTarget64-Info.plist"; sourceTree = SOURCE_ROOT; }; 166 | 0AEA0BF21972990700452D6E /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = main.c; path = injector/main.c; sourceTree = SOURCE_ROOT; }; 167 | 0AEA0BF41972994100452D6E /* unload_deamon.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = unload_deamon.sh; sourceTree = ""; }; 168 | 0AFCE4411975745200D51EE6 /* rd_inject_library.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rd_inject_library.c; path = injector/rd_inject_library/rd_inject_library.c; sourceTree = SOURCE_ROOT; }; 169 | 0AFCE4421975745200D51EE6 /* rd_inject_library.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rd_inject_library.h; path = injector/rd_inject_library/rd_inject_library.h; sourceTree = SOURCE_ROOT; }; 170 | 0AFEB8401972876B00BE2968 /* me.rodionovd.RDInjectionWizard.injector */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = me.rodionovd.RDInjectionWizard.injector; sourceTree = BUILT_PRODUCTS_DIR; }; 171 | 0AFEB8491972884E00BE2968 /* me.rodionovd.RDInjectionWizard.injector-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "me.rodionovd.RDInjectionWizard.injector-Info.plist"; path = "injector/me.rodionovd.RDInjectionWizard.injector-Info.plist"; sourceTree = SOURCE_ROOT; }; 172 | 0AFEB84A1972884E00BE2968 /* me.rodionovd.RDInjectionWizard.injector-Launchd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "me.rodionovd.RDInjectionWizard.injector-Launchd.plist"; path = "injector/me.rodionovd.RDInjectionWizard.injector-Launchd.plist"; sourceTree = SOURCE_ROOT; }; 173 | /* End PBXFileReference section */ 174 | 175 | /* Begin PBXFrameworksBuildPhase section */ 176 | 0A2E2286197170BF00255B00 /* Frameworks */ = { 177 | isa = PBXFrameworksBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | 0A8D0F8D197178300075B0E2 /* Foundation.framework in Frameworks */, 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | }; 184 | 0A2E229E197170BF00255B00 /* Frameworks */ = { 185 | isa = PBXFrameworksBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | 0A2E22A7197170BF00255B00 /* RDInjectionWizard.framework in Frameworks */, 189 | 0A2E22A4197170BF00255B00 /* Cocoa.framework in Frameworks */, 190 | 0A2E22A3197170BF00255B00 /* XCTest.framework in Frameworks */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | 0A8D0F59197176950075B0E2 /* Frameworks */ = { 195 | isa = PBXFrameworksBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | 0A8D0F5D197176960075B0E2 /* Cocoa.framework in Frameworks */, 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | 0AAEE16019742203008C231A /* Frameworks */ = { 203 | isa = PBXFrameworksBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | 0AAEE1B719743F95008C231A /* Frameworks */ = { 210 | isa = PBXFrameworksBuildPhase; 211 | buildActionMask = 2147483647; 212 | files = ( 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | 0AFEB83D1972876B00BE2968 /* Frameworks */ = { 217 | isa = PBXFrameworksBuildPhase; 218 | buildActionMask = 2147483647; 219 | files = ( 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | }; 223 | /* End PBXFrameworksBuildPhase section */ 224 | 225 | /* Begin PBXGroup section */ 226 | 0A2E2280197170BF00255B00 = { 227 | isa = PBXGroup; 228 | children = ( 229 | 0A2E2293197170BF00255B00 /* RDInjectionWizard */, 230 | 0A8D0F9919719F890075B0E2 /* Privileged injection helper */, 231 | 0A8D0F8B197177E30075B0E2 /* Tests */, 232 | 0AEA0BF41972994100452D6E /* unload_deamon.sh */, 233 | 0A2E228C197170BF00255B00 /* Frameworks */, 234 | 0A2E228B197170BF00255B00 /* Products */, 235 | ); 236 | sourceTree = ""; 237 | }; 238 | 0A2E228B197170BF00255B00 /* Products */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | 0A2E228A197170BF00255B00 /* RDInjectionWizard.framework */, 242 | 0A2E22A1197170BF00255B00 /* RDInjectionWizardTests.xctest */, 243 | 0A8D0F5C197176950075B0E2 /* RDInjectionWizardTestsHost.app */, 244 | 0AFEB8401972876B00BE2968 /* me.rodionovd.RDInjectionWizard.injector */, 245 | 0AAEE16319742203008C231A /* libtestnoop64.dylib */, 246 | 0AAEE1BD19743F95008C231A /* demoTarget64.app */, 247 | ); 248 | name = Products; 249 | sourceTree = ""; 250 | }; 251 | 0A2E228C197170BF00255B00 /* Frameworks */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | 0A2E228D197170BF00255B00 /* Cocoa.framework */, 255 | 0A2E22A2197170BF00255B00 /* XCTest.framework */, 256 | 0A8D0F9719719F890075B0E2 /* Foundation.framework */, 257 | 0A2E228F197170BF00255B00 /* Other Frameworks */, 258 | ); 259 | name = Frameworks; 260 | sourceTree = ""; 261 | }; 262 | 0A2E228F197170BF00255B00 /* Other Frameworks */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | 0A2E2290197170BF00255B00 /* Foundation.framework */, 266 | 0A2E2291197170BF00255B00 /* CoreData.framework */, 267 | 0A2E2292197170BF00255B00 /* AppKit.framework */, 268 | ); 269 | name = "Other Frameworks"; 270 | sourceTree = ""; 271 | }; 272 | 0A2E2293197170BF00255B00 /* RDInjectionWizard */ = { 273 | isa = PBXGroup; 274 | children = ( 275 | 0A2E229A197170BF00255B00 /* RDInjectionWizard.h */, 276 | 0A2E229B197170BF00255B00 /* RDInjectionWizard.m */, 277 | 0A8D0F8E1971860B0075B0E2 /* RDIWDeamonMaster.h */, 278 | 0A8D0F8F1971860B0075B0E2 /* RDIWDeamonMaster.m */, 279 | 0A2E2294197170BF00255B00 /* Supporting Files */, 280 | ); 281 | path = RDInjectionWizard; 282 | sourceTree = ""; 283 | }; 284 | 0A2E2294197170BF00255B00 /* Supporting Files */ = { 285 | isa = PBXGroup; 286 | children = ( 287 | 0A2E2295197170BF00255B00 /* RDInjectionWizard-Info.plist */, 288 | 0A2E2296197170BF00255B00 /* InfoPlist.strings */, 289 | 0A2E2299197170BF00255B00 /* RDInjectionWizard-Prefix.pch */, 290 | ); 291 | name = "Supporting Files"; 292 | sourceTree = ""; 293 | }; 294 | 0A2E22A8197170BF00255B00 /* Cases */ = { 295 | isa = PBXGroup; 296 | children = ( 297 | 0A2E22AE197170BF00255B00 /* RDInjectionWizardTests.m */, 298 | 0A61A27A1972AF0300728FAB /* RDIWDaemonMasterTests.m */, 299 | 0A2E22A9197170BF00255B00 /* Supporting Files */, 300 | ); 301 | name = Cases; 302 | path = RDInjectionWizardTests; 303 | sourceTree = ""; 304 | }; 305 | 0A2E22A9197170BF00255B00 /* Supporting Files */ = { 306 | isa = PBXGroup; 307 | children = ( 308 | 0A2E22AA197170BF00255B00 /* RDInjectionWizardTests-Info.plist */, 309 | ); 310 | name = "Supporting Files"; 311 | sourceTree = ""; 312 | }; 313 | 0A8D0F5E197176960075B0E2 /* Tests Host */ = { 314 | isa = PBXGroup; 315 | children = ( 316 | 0A8D0F6A197176960075B0E2 /* AppDelegate.h */, 317 | 0A8D0F6B197176960075B0E2 /* AppDelegate.m */, 318 | 0A8D0F60197176960075B0E2 /* RDInjectionWizardTestsHost-Info.plist */, 319 | 0A8D0F5F197176960075B0E2 /* Supporting Files */, 320 | ); 321 | name = "Tests Host"; 322 | path = RDInjectionWizardTests/RDInjectionWizardTestsHost; 323 | sourceTree = ""; 324 | }; 325 | 0A8D0F5F197176960075B0E2 /* Supporting Files */ = { 326 | isa = PBXGroup; 327 | children = ( 328 | 0A8D0F64197176960075B0E2 /* main.m */, 329 | 0A8D0F66197176960075B0E2 /* RDInjectionWizardTestsHost-Prefix.pch */, 330 | ); 331 | name = "Supporting Files"; 332 | sourceTree = ""; 333 | }; 334 | 0A8D0F8B197177E30075B0E2 /* Tests */ = { 335 | isa = PBXGroup; 336 | children = ( 337 | 0A2E22A8197170BF00255B00 /* Cases */, 338 | 0A8D0F5E197176960075B0E2 /* Tests Host */, 339 | 0AAEE16419742203008C231A /* Dummy payload */, 340 | 0AAEE19119742D73008C231A /* Demo target */, 341 | ); 342 | name = Tests; 343 | sourceTree = ""; 344 | }; 345 | 0A8D0F9919719F890075B0E2 /* Privileged injection helper */ = { 346 | isa = PBXGroup; 347 | children = ( 348 | 0AEA0BF21972990700452D6E /* main.c */, 349 | 0AFCE4411975745200D51EE6 /* rd_inject_library.c */, 350 | 0AFCE4421975745200D51EE6 /* rd_inject_library.h */, 351 | 0AFEB8491972884E00BE2968 /* me.rodionovd.RDInjectionWizard.injector-Info.plist */, 352 | 0AFEB84A1972884E00BE2968 /* me.rodionovd.RDInjectionWizard.injector-Launchd.plist */, 353 | ); 354 | name = "Privileged injection helper"; 355 | path = helper; 356 | sourceTree = ""; 357 | }; 358 | 0AAEE16419742203008C231A /* Dummy payload */ = { 359 | isa = PBXGroup; 360 | children = ( 361 | 0AAEE16519742203008C231A /* libtestnoop.h */, 362 | 0AAEE16719742203008C231A /* libtestnoop.m */, 363 | ); 364 | name = "Dummy payload"; 365 | path = RDInjectionWizardTests/libtestnoop64; 366 | sourceTree = ""; 367 | }; 368 | 0AAEE19119742D73008C231A /* Demo target */ = { 369 | isa = PBXGroup; 370 | children = ( 371 | 0A891D291980FE8A00CAF525 /* AppDelegate.h */, 372 | 0A891D2A1980FE8A00CAF525 /* AppDelegate.m */, 373 | 0A0C83001982E55700CBA7EC /* MainMenu.xib */, 374 | 0AAEE19219742D73008C231A /* Supporting Files */, 375 | ); 376 | name = "Demo target"; 377 | path = RDInjectionWizardTests/demoTarget64; 378 | sourceTree = ""; 379 | }; 380 | 0AAEE19219742D73008C231A /* Supporting Files */ = { 381 | isa = PBXGroup; 382 | children = ( 383 | 0AB8FD9B1981002800691034 /* demoTarget64-Info.plist */, 384 | 0A891D301980FEA100CAF525 /* main.m */, 385 | ); 386 | name = "Supporting Files"; 387 | sourceTree = ""; 388 | }; 389 | /* End PBXGroup section */ 390 | 391 | /* Begin PBXHeadersBuildPhase section */ 392 | 0A2E2287197170BF00255B00 /* Headers */ = { 393 | isa = PBXHeadersBuildPhase; 394 | buildActionMask = 2147483647; 395 | files = ( 396 | 0A8D0F8C197178210075B0E2 /* RDInjectionWizard.h in Headers */, 397 | 0A8D0F901971860B0075B0E2 /* RDIWDeamonMaster.h in Headers */, 398 | ); 399 | runOnlyForDeploymentPostprocessing = 0; 400 | }; 401 | 0AAEE16119742203008C231A /* Headers */ = { 402 | isa = PBXHeadersBuildPhase; 403 | buildActionMask = 2147483647; 404 | files = ( 405 | 0AAEE16619742203008C231A /* libtestnoop.h in Headers */, 406 | ); 407 | runOnlyForDeploymentPostprocessing = 0; 408 | }; 409 | /* End PBXHeadersBuildPhase section */ 410 | 411 | /* Begin PBXNativeTarget section */ 412 | 0A2E2289197170BF00255B00 /* RDInjectionWizard */ = { 413 | isa = PBXNativeTarget; 414 | buildConfigurationList = 0A2E22B2197170BF00255B00 /* Build configuration list for PBXNativeTarget "RDInjectionWizard" */; 415 | buildPhases = ( 416 | 0A2E2285197170BF00255B00 /* Sources */, 417 | 0A2E2286197170BF00255B00 /* Frameworks */, 418 | 0A2E2287197170BF00255B00 /* Headers */, 419 | 0A2E2288197170BF00255B00 /* Resources */, 420 | 0A8D0FA71971A10E0075B0E2 /* Copy the XPC service */, 421 | ); 422 | buildRules = ( 423 | ); 424 | dependencies = ( 425 | 0AFEB84C197288B100BE2968 /* PBXTargetDependency */, 426 | ); 427 | name = RDInjectionWizard; 428 | productName = RDInjectionWizard; 429 | productReference = 0A2E228A197170BF00255B00 /* RDInjectionWizard.framework */; 430 | productType = "com.apple.product-type.framework"; 431 | }; 432 | 0A2E22A0197170BF00255B00 /* RDInjectionWizardTests */ = { 433 | isa = PBXNativeTarget; 434 | buildConfigurationList = 0A2E22B5197170BF00255B00 /* Build configuration list for PBXNativeTarget "RDInjectionWizardTests" */; 435 | buildPhases = ( 436 | 0A2E229D197170BF00255B00 /* Sources */, 437 | 0A2E229E197170BF00255B00 /* Frameworks */, 438 | 0A2E229F197170BF00255B00 /* Resources */, 439 | ); 440 | buildRules = ( 441 | ); 442 | dependencies = ( 443 | 0A2E22A6197170BF00255B00 /* PBXTargetDependency */, 444 | 0A0C830B1982E66700CBA7EC /* PBXTargetDependency */, 445 | 0A0C83071982E58900CBA7EC /* PBXTargetDependency */, 446 | 0A0C83091982E58900CBA7EC /* PBXTargetDependency */, 447 | 0AA491C51983980A0096C481 /* PBXTargetDependency */, 448 | 0AA491C71983980A0096C481 /* PBXTargetDependency */, 449 | ); 450 | name = RDInjectionWizardTests; 451 | productName = RDInjectionWizardTests; 452 | productReference = 0A2E22A1197170BF00255B00 /* RDInjectionWizardTests.xctest */; 453 | productType = "com.apple.product-type.bundle.unit-test"; 454 | }; 455 | 0A8D0F5B197176950075B0E2 /* RDInjectionWizardTestsHost */ = { 456 | isa = PBXNativeTarget; 457 | buildConfigurationList = 0A8D0F83197176960075B0E2 /* Build configuration list for PBXNativeTarget "RDInjectionWizardTestsHost" */; 458 | buildPhases = ( 459 | 0A8D0F58197176950075B0E2 /* Sources */, 460 | 0A8D0F59197176950075B0E2 /* Frameworks */, 461 | 0A8D0F5A197176950075B0E2 /* Resources */, 462 | ); 463 | buildRules = ( 464 | ); 465 | dependencies = ( 466 | 0AAEE18B19742329008C231A /* PBXTargetDependency */, 467 | 0AAEE1C119744008008C231A /* PBXTargetDependency */, 468 | 0AAEE1871974229A008C231A /* PBXTargetDependency */, 469 | ); 470 | name = RDInjectionWizardTestsHost; 471 | productName = RDInjectionWizardTestsHost; 472 | productReference = 0A8D0F5C197176950075B0E2 /* RDInjectionWizardTestsHost.app */; 473 | productType = "com.apple.product-type.application"; 474 | }; 475 | 0AAEE16219742203008C231A /* libtestnoop64 */ = { 476 | isa = PBXNativeTarget; 477 | buildConfigurationList = 0AAEE17819742204008C231A /* Build configuration list for PBXNativeTarget "libtestnoop64" */; 478 | buildPhases = ( 479 | 0AAEE15F19742203008C231A /* Sources */, 480 | 0AAEE16019742203008C231A /* Frameworks */, 481 | 0AAEE16119742203008C231A /* Headers */, 482 | ); 483 | buildRules = ( 484 | ); 485 | dependencies = ( 486 | ); 487 | name = libtestnoop64; 488 | productName = libtestnoop64; 489 | productReference = 0AAEE16319742203008C231A /* libtestnoop64.dylib */; 490 | productType = "com.apple.product-type.library.dynamic"; 491 | }; 492 | 0AAEE1B319743F95008C231A /* demoTarget64 */ = { 493 | isa = PBXNativeTarget; 494 | buildConfigurationList = 0AAEE1BA19743F95008C231A /* Build configuration list for PBXNativeTarget "demoTarget64" */; 495 | buildPhases = ( 496 | 0AAEE1B419743F95008C231A /* Sources */, 497 | 0AAEE1B719743F95008C231A /* Frameworks */, 498 | 0AAEE1B819743F95008C231A /* Resources */, 499 | ); 500 | buildRules = ( 501 | ); 502 | dependencies = ( 503 | ); 504 | name = demoTarget64; 505 | productName = demoTarget32; 506 | productReference = 0AAEE1BD19743F95008C231A /* demoTarget64.app */; 507 | productType = "com.apple.product-type.application"; 508 | }; 509 | 0AFEB83F1972876B00BE2968 /* injector */ = { 510 | isa = PBXNativeTarget; 511 | buildConfigurationList = 0AFEB8461972876C00BE2968 /* Build configuration list for PBXNativeTarget "injector" */; 512 | buildPhases = ( 513 | 0AFEB83C1972876B00BE2968 /* Sources */, 514 | 0AFEB83D1972876B00BE2968 /* Frameworks */, 515 | 0AFEB83E1972876B00BE2968 /* CopyFiles */, 516 | ); 517 | buildRules = ( 518 | ); 519 | dependencies = ( 520 | ); 521 | name = injector; 522 | productName = injector; 523 | productReference = 0AFEB8401972876B00BE2968 /* me.rodionovd.RDInjectionWizard.injector */; 524 | productType = "com.apple.product-type.tool"; 525 | }; 526 | /* End PBXNativeTarget section */ 527 | 528 | /* Begin PBXProject section */ 529 | 0A2E2281197170BF00255B00 /* Project object */ = { 530 | isa = PBXProject; 531 | attributes = { 532 | CLASSPREFIX = RD; 533 | LastUpgradeCheck = 0600; 534 | ORGANIZATIONNAME = rodionovd; 535 | TargetAttributes = { 536 | 0A2E22A0197170BF00255B00 = { 537 | TestTargetID = 0A2E2289197170BF00255B00; 538 | }; 539 | 0AAEE16219742203008C231A = { 540 | CreatedOnToolsVersion = 6.0; 541 | }; 542 | 0AAEE1B319743F95008C231A = { 543 | SystemCapabilities = { 544 | com.apple.Sandbox = { 545 | enabled = 0; 546 | }; 547 | }; 548 | }; 549 | }; 550 | }; 551 | buildConfigurationList = 0A2E2284197170BF00255B00 /* Build configuration list for PBXProject "RDInjectionWizard" */; 552 | compatibilityVersion = "Xcode 3.2"; 553 | developmentRegion = English; 554 | hasScannedForEncodings = 0; 555 | knownRegions = ( 556 | en, 557 | Base, 558 | ); 559 | mainGroup = 0A2E2280197170BF00255B00; 560 | productRefGroup = 0A2E228B197170BF00255B00 /* Products */; 561 | projectDirPath = ""; 562 | projectRoot = ""; 563 | targets = ( 564 | 0A2E2289197170BF00255B00 /* RDInjectionWizard */, 565 | 0AFEB83F1972876B00BE2968 /* injector */, 566 | 0A2E22A0197170BF00255B00 /* RDInjectionWizardTests */, 567 | 0A8D0F5B197176950075B0E2 /* RDInjectionWizardTestsHost */, 568 | 0AAEE16219742203008C231A /* libtestnoop64 */, 569 | 0AAEE1B319743F95008C231A /* demoTarget64 */, 570 | ); 571 | }; 572 | /* End PBXProject section */ 573 | 574 | /* Begin PBXResourcesBuildPhase section */ 575 | 0A2E2288197170BF00255B00 /* Resources */ = { 576 | isa = PBXResourcesBuildPhase; 577 | buildActionMask = 2147483647; 578 | files = ( 579 | 0A2E2298197170BF00255B00 /* InfoPlist.strings in Resources */, 580 | ); 581 | runOnlyForDeploymentPostprocessing = 0; 582 | }; 583 | 0A2E229F197170BF00255B00 /* Resources */ = { 584 | isa = PBXResourcesBuildPhase; 585 | buildActionMask = 2147483647; 586 | files = ( 587 | ); 588 | runOnlyForDeploymentPostprocessing = 0; 589 | }; 590 | 0A8D0F5A197176950075B0E2 /* Resources */ = { 591 | isa = PBXResourcesBuildPhase; 592 | buildActionMask = 2147483647; 593 | files = ( 594 | 0AAEE18419742291008C231A /* libtestnoop64.dylib in Resources */, 595 | 0AAEE1BF19743FF3008C231A /* demoTarget64.app in Resources */, 596 | ); 597 | runOnlyForDeploymentPostprocessing = 0; 598 | }; 599 | 0AAEE1B819743F95008C231A /* Resources */ = { 600 | isa = PBXResourcesBuildPhase; 601 | buildActionMask = 2147483647; 602 | files = ( 603 | 0A533F62199BA6DF0065F2D6 /* MainMenu.xib in Resources */, 604 | ); 605 | runOnlyForDeploymentPostprocessing = 0; 606 | }; 607 | /* End PBXResourcesBuildPhase section */ 608 | 609 | /* Begin PBXSourcesBuildPhase section */ 610 | 0A2E2285197170BF00255B00 /* Sources */ = { 611 | isa = PBXSourcesBuildPhase; 612 | buildActionMask = 2147483647; 613 | files = ( 614 | 0A2E229C197170BF00255B00 /* RDInjectionWizard.m in Sources */, 615 | 0A8D0F911971860B0075B0E2 /* RDIWDeamonMaster.m in Sources */, 616 | ); 617 | runOnlyForDeploymentPostprocessing = 0; 618 | }; 619 | 0A2E229D197170BF00255B00 /* Sources */ = { 620 | isa = PBXSourcesBuildPhase; 621 | buildActionMask = 2147483647; 622 | files = ( 623 | 0A2E22AF197170BF00255B00 /* RDInjectionWizardTests.m in Sources */, 624 | 0A61A27B1972AF0300728FAB /* RDIWDaemonMasterTests.m in Sources */, 625 | ); 626 | runOnlyForDeploymentPostprocessing = 0; 627 | }; 628 | 0A8D0F58197176950075B0E2 /* Sources */ = { 629 | isa = PBXSourcesBuildPhase; 630 | buildActionMask = 2147483647; 631 | files = ( 632 | 0A8D0F6C197176960075B0E2 /* AppDelegate.m in Sources */, 633 | 0A8D0F65197176960075B0E2 /* main.m in Sources */, 634 | ); 635 | runOnlyForDeploymentPostprocessing = 0; 636 | }; 637 | 0AAEE15F19742203008C231A /* Sources */ = { 638 | isa = PBXSourcesBuildPhase; 639 | buildActionMask = 2147483647; 640 | files = ( 641 | 0AAEE16819742203008C231A /* libtestnoop.m in Sources */, 642 | ); 643 | runOnlyForDeploymentPostprocessing = 0; 644 | }; 645 | 0AAEE1B419743F95008C231A /* Sources */ = { 646 | isa = PBXSourcesBuildPhase; 647 | buildActionMask = 2147483647; 648 | files = ( 649 | 0A891D321980FEA100CAF525 /* main.m in Sources */, 650 | 0A891D2B1980FE8A00CAF525 /* AppDelegate.m in Sources */, 651 | ); 652 | runOnlyForDeploymentPostprocessing = 0; 653 | }; 654 | 0AFEB83C1972876B00BE2968 /* Sources */ = { 655 | isa = PBXSourcesBuildPhase; 656 | buildActionMask = 2147483647; 657 | files = ( 658 | 0AFCE4441975745200D51EE6 /* rd_inject_library.c in Sources */, 659 | 0AEA0BF31972990700452D6E /* main.c in Sources */, 660 | ); 661 | runOnlyForDeploymentPostprocessing = 0; 662 | }; 663 | /* End PBXSourcesBuildPhase section */ 664 | 665 | /* Begin PBXTargetDependency section */ 666 | 0A0C83071982E58900CBA7EC /* PBXTargetDependency */ = { 667 | isa = PBXTargetDependency; 668 | target = 0A2E2289197170BF00255B00 /* RDInjectionWizard */; 669 | targetProxy = 0A0C83061982E58900CBA7EC /* PBXContainerItemProxy */; 670 | }; 671 | 0A0C83091982E58900CBA7EC /* PBXTargetDependency */ = { 672 | isa = PBXTargetDependency; 673 | target = 0A2E2289197170BF00255B00 /* RDInjectionWizard */; 674 | targetProxy = 0A0C83081982E58900CBA7EC /* PBXContainerItemProxy */; 675 | }; 676 | 0A0C830B1982E66700CBA7EC /* PBXTargetDependency */ = { 677 | isa = PBXTargetDependency; 678 | target = 0A8D0F5B197176950075B0E2 /* RDInjectionWizardTestsHost */; 679 | targetProxy = 0A0C830A1982E66700CBA7EC /* PBXContainerItemProxy */; 680 | }; 681 | 0A2E22A6197170BF00255B00 /* PBXTargetDependency */ = { 682 | isa = PBXTargetDependency; 683 | target = 0A2E2289197170BF00255B00 /* RDInjectionWizard */; 684 | targetProxy = 0A2E22A5197170BF00255B00 /* PBXContainerItemProxy */; 685 | }; 686 | 0AA491C51983980A0096C481 /* PBXTargetDependency */ = { 687 | isa = PBXTargetDependency; 688 | target = 0A2E2289197170BF00255B00 /* RDInjectionWizard */; 689 | targetProxy = 0AA491C41983980A0096C481 /* PBXContainerItemProxy */; 690 | }; 691 | 0AA491C71983980A0096C481 /* PBXTargetDependency */ = { 692 | isa = PBXTargetDependency; 693 | target = 0A2E2289197170BF00255B00 /* RDInjectionWizard */; 694 | targetProxy = 0AA491C61983980A0096C481 /* PBXContainerItemProxy */; 695 | }; 696 | 0AAEE1871974229A008C231A /* PBXTargetDependency */ = { 697 | isa = PBXTargetDependency; 698 | target = 0AAEE16219742203008C231A /* libtestnoop64 */; 699 | targetProxy = 0AAEE1861974229A008C231A /* PBXContainerItemProxy */; 700 | }; 701 | 0AAEE18B19742329008C231A /* PBXTargetDependency */ = { 702 | isa = PBXTargetDependency; 703 | target = 0A2E2289197170BF00255B00 /* RDInjectionWizard */; 704 | targetProxy = 0AAEE18A19742329008C231A /* PBXContainerItemProxy */; 705 | }; 706 | 0AAEE1C119744008008C231A /* PBXTargetDependency */ = { 707 | isa = PBXTargetDependency; 708 | target = 0AAEE1B319743F95008C231A /* demoTarget64 */; 709 | targetProxy = 0AAEE1C019744008008C231A /* PBXContainerItemProxy */; 710 | }; 711 | 0AFEB84C197288B100BE2968 /* PBXTargetDependency */ = { 712 | isa = PBXTargetDependency; 713 | target = 0AFEB83F1972876B00BE2968 /* injector */; 714 | targetProxy = 0AFEB84B197288B100BE2968 /* PBXContainerItemProxy */; 715 | }; 716 | /* End PBXTargetDependency section */ 717 | 718 | /* Begin PBXVariantGroup section */ 719 | 0A0C83001982E55700CBA7EC /* MainMenu.xib */ = { 720 | isa = PBXVariantGroup; 721 | children = ( 722 | 0A0C83011982E55700CBA7EC /* Base */, 723 | ); 724 | name = MainMenu.xib; 725 | sourceTree = ""; 726 | }; 727 | 0A2E2296197170BF00255B00 /* InfoPlist.strings */ = { 728 | isa = PBXVariantGroup; 729 | children = ( 730 | 0A2E2297197170BF00255B00 /* en */, 731 | ); 732 | name = InfoPlist.strings; 733 | sourceTree = ""; 734 | }; 735 | /* End PBXVariantGroup section */ 736 | 737 | /* Begin XCBuildConfiguration section */ 738 | 0A2E22B0197170BF00255B00 /* Debug */ = { 739 | isa = XCBuildConfiguration; 740 | buildSettings = { 741 | ALWAYS_SEARCH_USER_PATHS = NO; 742 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 743 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 744 | CLANG_CXX_LIBRARY = "libc++"; 745 | CLANG_ENABLE_MODULES = YES; 746 | CLANG_ENABLE_OBJC_ARC = YES; 747 | CLANG_WARN_BOOL_CONVERSION = YES; 748 | CLANG_WARN_CONSTANT_CONVERSION = YES; 749 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 750 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 751 | CLANG_WARN_EMPTY_BODY = YES; 752 | CLANG_WARN_ENUM_CONVERSION = YES; 753 | CLANG_WARN_INT_CONVERSION = YES; 754 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 755 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 756 | CODE_SIGN_IDENTITY = rodionovd; 757 | COPY_PHASE_STRIP = NO; 758 | GCC_C_LANGUAGE_STANDARD = "compiler-default"; 759 | GCC_DYNAMIC_NO_PIC = NO; 760 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 761 | GCC_OPTIMIZATION_LEVEL = 0; 762 | GCC_PREPROCESSOR_DEFINITIONS = ( 763 | "DEBUG=1", 764 | "$(inherited)", 765 | ); 766 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 767 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 768 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 769 | GCC_WARN_PEDANTIC = NO; 770 | GCC_WARN_UNDECLARED_SELECTOR = YES; 771 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 772 | GCC_WARN_UNUSED_FUNCTION = YES; 773 | GCC_WARN_UNUSED_VARIABLE = YES; 774 | MACOSX_DEPLOYMENT_TARGET = 10.9; 775 | ONLY_ACTIVE_ARCH = NO; 776 | SDKROOT = macosx; 777 | WARNING_CFLAGS = ( 778 | "-Wall", 779 | "-Wconversion", 780 | "-Wdeprecated-implementations", 781 | "-Wfloat-equal", 782 | "-Wimplicit-retain-self", 783 | "-Wnewline-eof", 784 | "-Wshadow", 785 | ); 786 | }; 787 | name = Debug; 788 | }; 789 | 0A2E22B1197170BF00255B00 /* Release */ = { 790 | isa = XCBuildConfiguration; 791 | buildSettings = { 792 | ALWAYS_SEARCH_USER_PATHS = NO; 793 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 794 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 795 | CLANG_CXX_LIBRARY = "libc++"; 796 | CLANG_ENABLE_MODULES = YES; 797 | CLANG_ENABLE_OBJC_ARC = YES; 798 | CLANG_WARN_BOOL_CONVERSION = YES; 799 | CLANG_WARN_CONSTANT_CONVERSION = YES; 800 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 801 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 802 | CLANG_WARN_EMPTY_BODY = YES; 803 | CLANG_WARN_ENUM_CONVERSION = YES; 804 | CLANG_WARN_INT_CONVERSION = YES; 805 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 806 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 807 | CODE_SIGN_IDENTITY = rodionovd; 808 | COPY_PHASE_STRIP = YES; 809 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 810 | ENABLE_NS_ASSERTIONS = NO; 811 | GCC_C_LANGUAGE_STANDARD = "compiler-default"; 812 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 813 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 814 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 815 | GCC_WARN_PEDANTIC = NO; 816 | GCC_WARN_UNDECLARED_SELECTOR = YES; 817 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 818 | GCC_WARN_UNUSED_FUNCTION = YES; 819 | GCC_WARN_UNUSED_VARIABLE = YES; 820 | MACOSX_DEPLOYMENT_TARGET = 10.9; 821 | OTHER_CFLAGS = "-DNDEBUG"; 822 | SDKROOT = macosx; 823 | WARNING_CFLAGS = ( 824 | "-Wall", 825 | "-Wconversion", 826 | "-Wdeprecated-implementations", 827 | "-Wfloat-equal", 828 | "-Wimplicit-retain-self", 829 | "-Wnewline-eof", 830 | "-Wshadow", 831 | ); 832 | }; 833 | name = Release; 834 | }; 835 | 0A2E22B3197170BF00255B00 /* Debug */ = { 836 | isa = XCBuildConfiguration; 837 | buildSettings = { 838 | COMBINE_HIDPI_IMAGES = YES; 839 | DYLIB_COMPATIBILITY_VERSION = 1; 840 | DYLIB_CURRENT_VERSION = 1; 841 | FRAMEWORK_VERSION = A; 842 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 843 | GCC_PREFIX_HEADER = "RDInjectionWizard/RDInjectionWizard-Prefix.pch"; 844 | INFOPLIST_FILE = "RDInjectionWizard/RDInjectionWizard-Info.plist"; 845 | INSTALL_PATH = "@loader_path/../Frameworks"; 846 | PRODUCT_NAME = "$(TARGET_NAME)"; 847 | WRAPPER_EXTENSION = framework; 848 | }; 849 | name = Debug; 850 | }; 851 | 0A2E22B4197170BF00255B00 /* Release */ = { 852 | isa = XCBuildConfiguration; 853 | buildSettings = { 854 | COMBINE_HIDPI_IMAGES = YES; 855 | DYLIB_COMPATIBILITY_VERSION = 1; 856 | DYLIB_CURRENT_VERSION = 1; 857 | FRAMEWORK_VERSION = A; 858 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 859 | GCC_PREFIX_HEADER = "RDInjectionWizard/RDInjectionWizard-Prefix.pch"; 860 | INFOPLIST_FILE = "RDInjectionWizard/RDInjectionWizard-Info.plist"; 861 | INSTALL_PATH = "@loader_path/../Frameworks"; 862 | PRODUCT_NAME = "$(TARGET_NAME)"; 863 | WRAPPER_EXTENSION = framework; 864 | }; 865 | name = Release; 866 | }; 867 | 0A2E22B6197170BF00255B00 /* Debug */ = { 868 | isa = XCBuildConfiguration; 869 | buildSettings = { 870 | BUNDLE_LOADER = "$(BUILD_DIR)/$(CONFIGURATION)/RDInjectionWizardTestsHost.app/Contents/MacOS/RDInjectionWizardTestsHost"; 871 | COMBINE_HIDPI_IMAGES = YES; 872 | FRAMEWORK_SEARCH_PATHS = ( 873 | "$(DEVELOPER_FRAMEWORKS_DIR)", 874 | "$(inherited)", 875 | ); 876 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 877 | GCC_PREFIX_HEADER = "RDInjectionWizard/RDInjectionWizard-Prefix.pch"; 878 | GCC_PREPROCESSOR_DEFINITIONS = ( 879 | "DEBUG=1", 880 | "$(inherited)", 881 | ); 882 | INFOPLIST_FILE = "RDInjectionWizardTests/RDInjectionWizardTests-Info.plist"; 883 | PRODUCT_NAME = "$(TARGET_NAME)"; 884 | TEST_HOST = "$(BUILD_DIR)/$(CONFIGURATION)/RDInjectionWizardTestsHost.app/Contents/MacOS/RDInjectionWizardTestsHost"; 885 | WRAPPER_EXTENSION = xctest; 886 | }; 887 | name = Debug; 888 | }; 889 | 0A2E22B7197170BF00255B00 /* Release */ = { 890 | isa = XCBuildConfiguration; 891 | buildSettings = { 892 | BUNDLE_LOADER = "$(BUILD_DIR)/$(CONFIGURATION)/RDInjectionWizardTestsHost.app/Contents/MacOS/RDInjectionWizardTestsHost"; 893 | COMBINE_HIDPI_IMAGES = YES; 894 | FRAMEWORK_SEARCH_PATHS = ( 895 | "$(DEVELOPER_FRAMEWORKS_DIR)", 896 | "$(inherited)", 897 | ); 898 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 899 | GCC_PREFIX_HEADER = "RDInjectionWizard/RDInjectionWizard-Prefix.pch"; 900 | INFOPLIST_FILE = "RDInjectionWizardTests/RDInjectionWizardTests-Info.plist"; 901 | PRODUCT_NAME = "$(TARGET_NAME)"; 902 | TEST_HOST = "$(BUILD_DIR)/$(CONFIGURATION)/RDInjectionWizardTestsHost.app/Contents/MacOS/RDInjectionWizardTestsHost"; 903 | WRAPPER_EXTENSION = xctest; 904 | }; 905 | name = Release; 906 | }; 907 | 0A8D0F84197176960075B0E2 /* Debug */ = { 908 | isa = XCBuildConfiguration; 909 | buildSettings = { 910 | COMBINE_HIDPI_IMAGES = YES; 911 | GCC_C_LANGUAGE_STANDARD = gnu99; 912 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 913 | GCC_PREFIX_HEADER = "RDInjectionWizardTests/RDInjectionWizardTestsHost/RDInjectionWizardTestsHost-Prefix.pch"; 914 | GCC_PREPROCESSOR_DEFINITIONS = ( 915 | "DEBUG=1", 916 | "$(inherited)", 917 | ); 918 | INFOPLIST_FILE = "$(SRCROOT)/RDInjectionWizardTests/RDInjectionWizardTestsHost/RDInjectionWizardTestsHost-Info.plist"; 919 | PRODUCT_NAME = "$(TARGET_NAME)"; 920 | WRAPPER_EXTENSION = app; 921 | }; 922 | name = Debug; 923 | }; 924 | 0A8D0F85197176960075B0E2 /* Release */ = { 925 | isa = XCBuildConfiguration; 926 | buildSettings = { 927 | COMBINE_HIDPI_IMAGES = YES; 928 | GCC_C_LANGUAGE_STANDARD = gnu99; 929 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 930 | GCC_PREFIX_HEADER = "RDInjectionWizardTests/RDInjectionWizardTestsHost/RDInjectionWizardTestsHost-Prefix.pch"; 931 | INFOPLIST_FILE = "$(SRCROOT)/RDInjectionWizardTests/RDInjectionWizardTestsHost/RDInjectionWizardTestsHost-Info.plist"; 932 | PRODUCT_NAME = "$(TARGET_NAME)"; 933 | WRAPPER_EXTENSION = app; 934 | }; 935 | name = Release; 936 | }; 937 | 0AAEE17419742204008C231A /* Debug */ = { 938 | isa = XCBuildConfiguration; 939 | buildSettings = { 940 | CLANG_WARN_UNREACHABLE_CODE = YES; 941 | DYLIB_COMPATIBILITY_VERSION = 1; 942 | DYLIB_CURRENT_VERSION = 1; 943 | ENABLE_STRICT_OBJC_MSGSEND = YES; 944 | EXECUTABLE_PREFIX = ""; 945 | GCC_C_LANGUAGE_STANDARD = gnu99; 946 | GCC_PREPROCESSOR_DEFINITIONS = ( 947 | "DEBUG=1", 948 | "$(inherited)", 949 | ); 950 | MTL_ENABLE_DEBUG_INFO = YES; 951 | ONLY_ACTIVE_ARCH = NO; 952 | PRODUCT_NAME = "$(TARGET_NAME)"; 953 | }; 954 | name = Debug; 955 | }; 956 | 0AAEE17519742204008C231A /* Release */ = { 957 | isa = XCBuildConfiguration; 958 | buildSettings = { 959 | CLANG_WARN_UNREACHABLE_CODE = YES; 960 | DYLIB_COMPATIBILITY_VERSION = 1; 961 | DYLIB_CURRENT_VERSION = 1; 962 | ENABLE_STRICT_OBJC_MSGSEND = YES; 963 | EXECUTABLE_PREFIX = ""; 964 | GCC_C_LANGUAGE_STANDARD = gnu99; 965 | MTL_ENABLE_DEBUG_INFO = NO; 966 | ONLY_ACTIVE_ARCH = NO; 967 | PRODUCT_NAME = "$(TARGET_NAME)"; 968 | }; 969 | name = Release; 970 | }; 971 | 0AAEE1BB19743F95008C231A /* Debug */ = { 972 | isa = XCBuildConfiguration; 973 | buildSettings = { 974 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 975 | CLANG_ENABLE_OBJC_ARC = YES; 976 | CLANG_WARN_UNREACHABLE_CODE = YES; 977 | CODE_SIGN_IDENTITY = rodionovd; 978 | COMBINE_HIDPI_IMAGES = YES; 979 | ENABLE_STRICT_OBJC_MSGSEND = YES; 980 | GCC_C_LANGUAGE_STANDARD = gnu99; 981 | GCC_PREPROCESSOR_DEFINITIONS = ( 982 | "DEBUG=1", 983 | "$(inherited)", 984 | ); 985 | INFOPLIST_FILE = "$(SRCROOT)/RDInjectionWizardTests/demoTarget64/demoTarget64-Info.plist"; 986 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 987 | MTL_ENABLE_DEBUG_INFO = YES; 988 | ONLY_ACTIVE_ARCH = NO; 989 | PRODUCT_NAME = demoTarget64; 990 | }; 991 | name = Debug; 992 | }; 993 | 0AAEE1BC19743F95008C231A /* Release */ = { 994 | isa = XCBuildConfiguration; 995 | buildSettings = { 996 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 997 | CLANG_ENABLE_OBJC_ARC = YES; 998 | CLANG_WARN_UNREACHABLE_CODE = YES; 999 | CODE_SIGN_IDENTITY = rodionovd; 1000 | COMBINE_HIDPI_IMAGES = YES; 1001 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1002 | GCC_C_LANGUAGE_STANDARD = gnu99; 1003 | INFOPLIST_FILE = "$(SRCROOT)/RDInjectionWizardTests/demoTarget64/demoTarget64-Info.plist"; 1004 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 1005 | MTL_ENABLE_DEBUG_INFO = NO; 1006 | PRODUCT_NAME = demoTarget64; 1007 | }; 1008 | name = Release; 1009 | }; 1010 | 0AFEB8471972876C00BE2968 /* Debug */ = { 1011 | isa = XCBuildConfiguration; 1012 | buildSettings = { 1013 | COPY_PHASE_STRIP = NO; 1014 | GCC_C_LANGUAGE_STANDARD = gnu99; 1015 | GCC_PREPROCESSOR_DEFINITIONS = ( 1016 | "DEBUG=1", 1017 | "$(inherited)", 1018 | ); 1019 | ONLY_ACTIVE_ARCH = NO; 1020 | OTHER_LDFLAGS = ( 1021 | "-sectcreate", 1022 | __TEXT, 1023 | __info_plist, 1024 | "\"injector/me.rodionovd.RDInjectionWizard.injector-Info.plist\"", 1025 | "-sectcreate", 1026 | __TEXT, 1027 | __launchd_plist, 1028 | "\"injector/me.rodionovd.RDInjectionWizard.injector-Launchd.plist\"", 1029 | ); 1030 | PRODUCT_NAME = me.rodionovd.RDInjectionWizard.injector; 1031 | STRIP_INSTALLED_PRODUCT = NO; 1032 | STRIP_STYLE = all; 1033 | }; 1034 | name = Debug; 1035 | }; 1036 | 0AFEB8481972876C00BE2968 /* Release */ = { 1037 | isa = XCBuildConfiguration; 1038 | buildSettings = { 1039 | COPY_PHASE_STRIP = NO; 1040 | GCC_C_LANGUAGE_STANDARD = gnu99; 1041 | ONLY_ACTIVE_ARCH = NO; 1042 | OTHER_LDFLAGS = ( 1043 | "-sectcreate", 1044 | __TEXT, 1045 | __info_plist, 1046 | "\"injector/me.rodionovd.RDInjectionWizard.injector-Info.plist\"", 1047 | "-sectcreate", 1048 | __TEXT, 1049 | __launchd_plist, 1050 | "\"injector/me.rodionovd.RDInjectionWizard.injector-Launchd.plist\"", 1051 | ); 1052 | PRODUCT_NAME = me.rodionovd.RDInjectionWizard.injector; 1053 | STRIP_INSTALLED_PRODUCT = NO; 1054 | STRIP_STYLE = all; 1055 | }; 1056 | name = Release; 1057 | }; 1058 | /* End XCBuildConfiguration section */ 1059 | 1060 | /* Begin XCConfigurationList section */ 1061 | 0A2E2284197170BF00255B00 /* Build configuration list for PBXProject "RDInjectionWizard" */ = { 1062 | isa = XCConfigurationList; 1063 | buildConfigurations = ( 1064 | 0A2E22B0197170BF00255B00 /* Debug */, 1065 | 0A2E22B1197170BF00255B00 /* Release */, 1066 | ); 1067 | defaultConfigurationIsVisible = 0; 1068 | defaultConfigurationName = Release; 1069 | }; 1070 | 0A2E22B2197170BF00255B00 /* Build configuration list for PBXNativeTarget "RDInjectionWizard" */ = { 1071 | isa = XCConfigurationList; 1072 | buildConfigurations = ( 1073 | 0A2E22B3197170BF00255B00 /* Debug */, 1074 | 0A2E22B4197170BF00255B00 /* Release */, 1075 | ); 1076 | defaultConfigurationIsVisible = 0; 1077 | defaultConfigurationName = Release; 1078 | }; 1079 | 0A2E22B5197170BF00255B00 /* Build configuration list for PBXNativeTarget "RDInjectionWizardTests" */ = { 1080 | isa = XCConfigurationList; 1081 | buildConfigurations = ( 1082 | 0A2E22B6197170BF00255B00 /* Debug */, 1083 | 0A2E22B7197170BF00255B00 /* Release */, 1084 | ); 1085 | defaultConfigurationIsVisible = 0; 1086 | defaultConfigurationName = Release; 1087 | }; 1088 | 0A8D0F83197176960075B0E2 /* Build configuration list for PBXNativeTarget "RDInjectionWizardTestsHost" */ = { 1089 | isa = XCConfigurationList; 1090 | buildConfigurations = ( 1091 | 0A8D0F84197176960075B0E2 /* Debug */, 1092 | 0A8D0F85197176960075B0E2 /* Release */, 1093 | ); 1094 | defaultConfigurationIsVisible = 0; 1095 | defaultConfigurationName = Release; 1096 | }; 1097 | 0AAEE17819742204008C231A /* Build configuration list for PBXNativeTarget "libtestnoop64" */ = { 1098 | isa = XCConfigurationList; 1099 | buildConfigurations = ( 1100 | 0AAEE17419742204008C231A /* Debug */, 1101 | 0AAEE17519742204008C231A /* Release */, 1102 | ); 1103 | defaultConfigurationIsVisible = 0; 1104 | defaultConfigurationName = Release; 1105 | }; 1106 | 0AAEE1BA19743F95008C231A /* Build configuration list for PBXNativeTarget "demoTarget64" */ = { 1107 | isa = XCConfigurationList; 1108 | buildConfigurations = ( 1109 | 0AAEE1BB19743F95008C231A /* Debug */, 1110 | 0AAEE1BC19743F95008C231A /* Release */, 1111 | ); 1112 | defaultConfigurationIsVisible = 0; 1113 | defaultConfigurationName = Release; 1114 | }; 1115 | 0AFEB8461972876C00BE2968 /* Build configuration list for PBXNativeTarget "injector" */ = { 1116 | isa = XCConfigurationList; 1117 | buildConfigurations = ( 1118 | 0AFEB8471972876C00BE2968 /* Debug */, 1119 | 0AFEB8481972876C00BE2968 /* Release */, 1120 | ); 1121 | defaultConfigurationIsVisible = 0; 1122 | defaultConfigurationName = Release; 1123 | }; 1124 | /* End XCConfigurationList section */ 1125 | }; 1126 | rootObject = 0A2E2281197170BF00255B00 /* Project object */; 1127 | } 1128 | -------------------------------------------------------------------------------- /RDInjectionWizard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RDInjectionWizard/RDIWDeamonMaster.h: -------------------------------------------------------------------------------- 1 | // 2 | // RDIWDeamonMaster.h 3 | // RDInjectionWizard 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | typedef enum { 10 | kSuccess, 11 | kCouldNotEstabilishXPCConnection 12 | } RDIWConnectionError; 13 | 14 | typedef void (^RDIWDaemonConnectionCallback)(id reply, RDIWConnectionError error); 15 | 16 | @interface RDIWDeamonMaster : NSObject 17 | /** 18 | * @abstract 19 | * One-of-a-kind deamon master. 20 | */ 21 | + (instancetype)sharedMaster __attribute__((const)); 22 | 23 | /** 24 | * @abstract 25 | * Asynchronously sends a "plese, inject this into that" message to the privileged 26 | * injector helper. 27 | * 28 | * @discussion 29 | * This method doesn't perform any verification of input parameters, so be careful. 30 | * 31 | * @param target a target process for injection 32 | * @param payload a payload library filename 33 | * @param callback a block to be called upon error or when helper's reply received 34 | */ 35 | - (void)tellDeamonToInjectTarget: (pid_t)target 36 | withPayload: (NSString *)payload 37 | completionHandler: (RDIWDaemonConnectionCallback)callback; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /RDInjectionWizard/RDIWDeamonMaster.m: -------------------------------------------------------------------------------- 1 | // 2 | // RDIWDeamonMaster.m 3 | // RDInjectionWizard 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | @import ServiceManagement; 9 | @import Security; 10 | 11 | #import 12 | #import 13 | #import "RDIWDeamonMaster.h" 14 | 15 | #define kRDIWDeamonMasterCallbackQueueLabel "me.rodionovd.RDIWDeamonMaster.callbackqueue" 16 | 17 | static NSString *kRDIWDeamonIdentifer = @"me.rodionovd.RDInjectionWizard.injector"; 18 | 19 | static pthread_mutex_t authorizationLock = PTHREAD_MUTEX_INITIALIZER; 20 | static pthread_mutex_t fileIOLock = PTHREAD_MUTEX_INITIALIZER; 21 | 22 | @interface RDIWDeamonMaster() 23 | { 24 | // A connection handle for our priveleged helper 25 | xpc_connection_t _connection; 26 | AuthorizationRef _authorization; 27 | // A dispatch queue to perform user's callbacks in 28 | dispatch_queue_t _callbackQueue; 29 | } 30 | - (BOOL)_initializeXPCConnection; 31 | - (BOOL)_copyHelperIntoHostAppBundle; 32 | - (BOOL)_registerDeamonWithLaunchd; 33 | - (BOOL)_removeHelperFromHostAppBundle; 34 | @end 35 | 36 | @implementation RDIWDeamonMaster 37 | 38 | + (instancetype)sharedMaster 39 | { 40 | static id master = nil; 41 | static dispatch_once_t onceToken; 42 | dispatch_once(&onceToken, ^{ 43 | master = [[[self class] alloc] init]; 44 | }); 45 | 46 | return (master); 47 | } 48 | 49 | - (instancetype)init 50 | { 51 | if ((self = [super init])) { 52 | _callbackQueue = dispatch_queue_create(kRDIWDeamonMasterCallbackQueueLabel, 53 | DISPATCH_QUEUE_CONCURRENT); 54 | } 55 | 56 | return (self); 57 | } 58 | 59 | - (void)tellDeamonToInjectTarget: (pid_t)target 60 | withPayload: (NSString *)payload 61 | completionHandler: (RDIWDaemonConnectionCallback)callback 62 | { 63 | if (![self _initializeXPCConnection]) { 64 | dispatch_async(_callbackQueue, ^{ 65 | if (callback) callback(nil, kCouldNotEstabilishXPCConnection); 66 | }); 67 | return; 68 | } 69 | 70 | /* Configure a request message */ 71 | xpc_object_t injection_request = xpc_dictionary_create(NULL, NULL, 0); 72 | xpc_dictionary_set_int64(injection_request, "target", target); 73 | xpc_dictionary_set_string(injection_request, "payload", [payload UTF8String]); 74 | 75 | if (callback) { 76 | xpc_connection_send_message_with_reply(_connection, injection_request, 77 | _callbackQueue, 78 | ^(xpc_object_t object) { 79 | callback(object, kSuccess); 80 | }); 81 | } else { 82 | xpc_connection_send_message(_connection, injection_request); 83 | } 84 | } 85 | 86 | 87 | - (BOOL)_initializeXPCConnection 88 | { 89 | if (_connection) { 90 | return YES; 91 | } 92 | pthread_mutex_lock(&fileIOLock); 93 | if (NO == [self _copyHelperIntoHostAppBundle]) { 94 | pthread_mutex_unlock(&fileIOLock); 95 | return NO; 96 | } 97 | if (NO == [self _registerDeamonWithLaunchd]) { 98 | pthread_mutex_unlock(&fileIOLock); 99 | return NO; 100 | } 101 | if (NO == [self _removeHelperFromHostAppBundle]) { 102 | pthread_mutex_unlock(&fileIOLock); 103 | return NO; 104 | } 105 | 106 | _connection = xpc_connection_create_mach_service([kRDIWDeamonIdentifer UTF8String], 107 | NULL, 108 | XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); 109 | if (!_connection) { 110 | NSLog(@"%s: Unable to create XPC connection", __PRETTY_FUNCTION__); 111 | pthread_mutex_unlock(&fileIOLock); 112 | return NO; 113 | } 114 | pthread_mutex_unlock(&fileIOLock); 115 | 116 | /* Every connection has to have an event handler set */ 117 | xpc_connection_set_event_handler(_connection, ^(xpc_object_t __unused event) { 118 | /* no-op */ 119 | }); 120 | xpc_connection_resume(_connection); 121 | 122 | return YES; 123 | } 124 | 125 | /** 126 | * Since we use SMJobBless() to bootstrap our helper deamon with launchd, 127 | * we need to play by the Apple's rules and store our helper inside a host 128 | * bundle's `Contents/Library/LaunchServices` subdirectory. 129 | */ 130 | - (BOOL)_copyHelperIntoHostAppBundle 131 | { 132 | /* Chech if we've already copied the helper */ 133 | NSFileManager *manager = [NSFileManager defaultManager]; 134 | NSString *new_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: 135 | @"Contents/Library/LaunchServices"]; 136 | new_path = [new_path stringByAppendingPathComponent: kRDIWDeamonIdentifer]; 137 | BOOL daemon_was_copied = [manager fileExistsAtPath: new_path]; 138 | if (daemon_was_copied) { 139 | return YES; 140 | } 141 | /* Locate the helper inside the framework bundle */ 142 | NSBundle *framework_bundle = [NSBundle bundleForClass: self.class]; 143 | if ([framework_bundle bundlePath].length == 0) { 144 | NSLog(@"%s: Could not locate framework bunlde", __PRETTY_FUNCTION__); 145 | return NO; 146 | } 147 | NSString *orig_path = [framework_bundle.bundlePath stringByAppendingPathComponent: 148 | @"LaunchServices"]; 149 | orig_path = [orig_path stringByAppendingPathComponent: kRDIWDeamonIdentifer]; 150 | BOOL original_helper_exists = [manager fileExistsAtPath: orig_path]; 151 | if (!original_helper_exists) { 152 | NSLog(@"%s: Could not find original helper location", __PRETTY_FUNCTION__); 153 | return NO; 154 | } 155 | /* Check if there's already a Contents/Library/LaunchServices directory */ 156 | NSError *error = nil; 157 | NSString *launchservices_dir = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: 158 | @"Contents/Library/LaunchServices"]; 159 | BOOL directory_exists = [manager fileExistsAtPath: launchservices_dir]; 160 | if (!directory_exists) { 161 | BOOL directory_created = [manager createDirectoryAtPath: launchservices_dir 162 | withIntermediateDirectories: YES 163 | attributes: nil 164 | error: &error]; 165 | if (!directory_created) { 166 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, error.localizedDescription); 167 | return NO; 168 | } 169 | } 170 | /* Copy the helper into the host's bundle */ 171 | error = nil; 172 | BOOL copied = [manager copyItemAtPath: orig_path toPath: new_path error: &error]; 173 | if (!copied) { 174 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, error.localizedDescription); 175 | return NO; 176 | } 177 | 178 | return YES; 179 | } 180 | 181 | - (BOOL)_registerDeamonWithLaunchd 182 | { 183 | /** Check if the injector deamon is already installed */ 184 | CFDictionaryRef job = SMJobCopyDictionary(kSMDomainSystemLaunchd, 185 | (__bridge CFStringRef)(kRDIWDeamonIdentifer)); 186 | if (job) { 187 | CFRelease(job); 188 | return YES; 189 | } 190 | 191 | pthread_mutex_lock(&authorizationLock); 192 | { 193 | /* Requst an authorization right to be able to register (install) our helper tool */ 194 | AuthorizationItem items[] = { 195 | ((AuthorizationItem){kSMRightBlessPrivilegedHelper, 0, NULL, 0}) 196 | }; 197 | uint32_t items_count = 1; 198 | AuthorizationRights authRights = {items_count, items}; 199 | AuthorizationFlags flags = ( 200 | kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | 201 | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights 202 | ); 203 | int status = AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, 204 | flags, &_authorization); 205 | if (status != errAuthorizationSuccess) { 206 | pthread_mutex_unlock(&authorizationLock); 207 | NSLog(@"%s: could not create authorization rights!", __PRETTY_FUNCTION__); 208 | return NO; 209 | } 210 | } 211 | pthread_mutex_unlock(&authorizationLock); 212 | 213 | /* Register the helper with launchd */ 214 | CFErrorRef error = NULL; 215 | Boolean blessed = SMJobBless(kSMDomainSystemLaunchd, 216 | (__bridge CFStringRef)(kRDIWDeamonIdentifer), 217 | _authorization, 218 | &error); 219 | if (!blessed) { 220 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, (__bridge NSError *)error); 221 | } 222 | 223 | return !!(blessed); 224 | } 225 | 226 | - (BOOL)_removeHelperFromHostAppBundle 227 | { 228 | NSFileManager *manager = [NSFileManager defaultManager]; 229 | NSString *helper_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: 230 | @"Contents/Library/LaunchServices"]; 231 | helper_path = [helper_path stringByAppendingPathComponent: kRDIWDeamonIdentifer]; 232 | BOOL helper_exists = [manager fileExistsAtPath: helper_path]; 233 | if (!helper_exists) { 234 | return YES; 235 | } 236 | /* Remove the helper itself */ 237 | NSError *error = nil; 238 | BOOL removed = [manager removeItemAtPath: helper_path error: &error]; 239 | if (!removed) { 240 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, error); 241 | return NO; 242 | } 243 | /* Remove the Contents/Library/LaunchServices directory if it's empty now */ 244 | NSString *launchServicesDir = [helper_path stringByDeletingLastPathComponent]; 245 | error = nil; 246 | NSArray *files = [manager contentsOfDirectoryAtPath: launchServicesDir error: &error]; 247 | if (files.count != 0 || error) { 248 | return YES; 249 | } 250 | error = nil; 251 | if ( ! [manager removeItemAtPath: launchServicesDir error: &error]) { 252 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, error); 253 | return NO; 254 | } 255 | /* Remove the Contents/Library/ directory if it's empty now */ 256 | NSString *libraryDir = [launchServicesDir stringByDeletingLastPathComponent]; 257 | error = nil; 258 | files = [manager contentsOfDirectoryAtPath: libraryDir error: &error]; 259 | if (files.count != 0 || error) { 260 | return YES; 261 | } 262 | error = nil; 263 | if ( ! [manager removeItemAtPath: libraryDir error: &error]) { 264 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, error); 265 | return NO; 266 | } 267 | 268 | return (YES); 269 | } 270 | 271 | @end 272 | -------------------------------------------------------------------------------- /RDInjectionWizard/RDInjectionWizard-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | me.rodionovd.RDInjectionWizard 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 0.1.2 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 12 25 | NSHumanReadableCopyright 26 | Copyright © 2014 rodionovd. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /RDInjectionWizard/RDInjectionWizard-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /RDInjectionWizard/RDInjectionWizard.h: -------------------------------------------------------------------------------- 1 | // 2 | // RDInjectionWizard.h 3 | // RDInjectionWizard 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | #import 9 | 10 | typedef enum { 11 | kInvalidProcessIdentifier, 12 | kInvalidPayload, 13 | kCouldNotCopyPayload, 14 | kCouldNotConnectToHelper, 15 | kInjectionFailed 16 | } RDInjectionError; 17 | 18 | typedef void (^RDInjectionSuccededBlock)(void); 19 | typedef void (^RDInjectionFailedBlock)(RDInjectionError error); 20 | 21 | @interface RDInjectionWizard : NSObject 22 | 23 | /// A target process' identifer 24 | @property (assign, readwrite) pid_t target; 25 | /// A path to the payload library/framework 26 | @property (copy, readwrite) NSString *payload; 27 | 28 | /** 29 | * @abstract 30 | * Initialize an injection wizard for a given target and payload filepath. 31 | * 32 | * @param target an identifer of the target process 33 | * @param payload a full path to the payload library 34 | * 35 | * @return some magic 36 | */ 37 | - (instancetype)initWithTarget: (pid_t)target payload: (NSString *)payload; 38 | 39 | /** 40 | * @abstract 41 | * Asynchronously inject the given target with the given payload library. 42 | * 43 | * @param success 44 | * The block to be executed on the completion of the injection. 45 | * It takes no arguments and has no return value. 46 | * @param failure 47 | * the block to be executed upon an injection error. 48 | * It has no return value and takes one argument: an error that occured during the injection. 49 | */ 50 | 51 | - (void)injectUsingCompletionBlockWithSuccess: (RDInjectionSuccededBlock) success 52 | failure: (RDInjectionFailedBlock) failure; 53 | /** 54 | * @abstract 55 | * Looks up a sandbox-friendly location of the payload. 56 | * 57 | * @discussion 58 | * Use this method if you want to copy the payload into a location within the target's 59 | * sandbox contaner that is said to be accessible by definition. 60 | * 61 | * @return a new unique filename for the payload inside the target's sandbox container 62 | */ 63 | - (NSString *)sandboxFriendlyPayloadPath; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /RDInjectionWizard/RDInjectionWizard.m: -------------------------------------------------------------------------------- 1 | // 2 | // RDInjectionWizard.m 3 | // RDInjectionWizard 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | #import 9 | #import "RDIWDeamonMaster.h" 10 | #import "RDInjectionWizard.h" 11 | 12 | #define kRDFallbackSandboxContainer ([@"~/Library/Fonts" stringByExpandingTildeInPath]) 13 | #define kRDInjectionWizardCallbackQueueLabel "me.rodionovd.RDInjectionWizard.callbackqueue" 14 | @interface RDInjectionWizard() 15 | { 16 | /* A dispatch queue to perform user's callbacks on */ 17 | dispatch_queue_t _callbackQueue; 18 | } 19 | 20 | @end 21 | 22 | @implementation RDInjectionWizard 23 | 24 | - (instancetype)initWithTarget: (pid_t)target payload: (NSString *)payload 25 | { 26 | if ((self = [super init])) { 27 | _payload = payload; 28 | _target = target; 29 | _callbackQueue = dispatch_queue_create(kRDInjectionWizardCallbackQueueLabel, DISPATCH_QUEUE_CONCURRENT); 30 | } 31 | return (self); 32 | } 33 | 34 | - (void)injectUsingCompletionBlockWithSuccess: (RDInjectionSuccededBlock) success 35 | failure: (RDInjectionFailedBlock) failure 36 | { 37 | if (_target < 0) { 38 | dispatch_async(_callbackQueue, ^{ 39 | if (failure) failure(kInvalidProcessIdentifier); 40 | }); 41 | return; 42 | } 43 | 44 | BOOL _payload_exists = [[NSFileManager defaultManager] fileExistsAtPath: _payload]; 45 | if (!_payload_exists) { 46 | dispatch_async(_callbackQueue, ^{ 47 | if (failure) failure(kInvalidPayload); 48 | }); 49 | return; 50 | } 51 | 52 | /* If our payload is a framework/bundle, use its executable path as a payload */ 53 | NSBundle *bundle = [NSBundle bundleWithPath: _payload]; 54 | if (bundle && [bundle.executablePath length] > 0) { 55 | [self setPayload: bundle.executablePath]; 56 | } 57 | 58 | NSString *sandbox_friendly_payload = [self sandboxFriendlyPayloadPath]; 59 | if ([sandbox_friendly_payload length] == 0) { 60 | dispatch_async(_callbackQueue, ^{ 61 | if (failure) failure(kInvalidPayload); 62 | }); 63 | return; 64 | } 65 | 66 | BOOL payload_was_copied = NO; 67 | if (NO == [sandbox_friendly_payload isEqualToString: _payload]) { 68 | payload_was_copied = YES; 69 | NSError *error = nil; 70 | BOOL copied = [[NSFileManager defaultManager] copyItemAtPath: _payload 71 | toPath: sandbox_friendly_payload 72 | error: &error]; 73 | if (!copied) { 74 | NSLog(@"%s: %@", __PRETTY_FUNCTION__, error); 75 | dispatch_async(_callbackQueue, ^{ 76 | if (failure) failure(kInvalidPayload); 77 | }); 78 | return; 79 | } 80 | } 81 | 82 | RDIWDeamonMaster *master = [RDIWDeamonMaster sharedMaster]; 83 | [master tellDeamonToInjectTarget: _target 84 | withPayload: sandbox_friendly_payload 85 | completionHandler: 86 | ^(xpc_object_t reply, RDIWConnectionError error) { 87 | /* Remove a payload copy if any */ 88 | if (payload_was_copied) { 89 | [[NSFileManager defaultManager] removeItemAtPath: sandbox_friendly_payload 90 | error: nil]; 91 | } 92 | /* Check the xpc reply for an injection error */ 93 | if (!reply) { 94 | NSLog(@"%s: daemon connection error: %d", __PRETTY_FUNCTION__, error); 95 | dispatch_async(self->_callbackQueue, ^{ 96 | if (failure) failure(kCouldNotConnectToHelper); 97 | }); 98 | return; 99 | } 100 | BOOL status = xpc_dictionary_get_bool(reply, "status"); 101 | if (status) { 102 | dispatch_async(self->_callbackQueue, ^{ 103 | if (success) success(); 104 | }); 105 | } else { 106 | dispatch_async(self->_callbackQueue, ^{ 107 | if (failure) failure(kInjectionFailed); 108 | }); 109 | } 110 | }]; 111 | 112 | return; 113 | } 114 | 115 | /* Apple's private API for checking sandbox status */ 116 | extern int sandbox_check(pid_t pid, const char *operation, int type, ...); 117 | extern int sandbox_container_path_for_pid(pid_t, char *buffer, size_t bufsize); 118 | 119 | - (NSString *)sandboxFriendlyPayloadPath 120 | { 121 | if (sandbox_check(_target, NULL, 0) == 0) { 122 | return _payload; 123 | } 124 | 125 | char *buf = malloc(sizeof(*buf) * MAXPATHLEN); 126 | if (!buf) { 127 | return _payload; 128 | } 129 | NSString *container = nil; 130 | if (sandbox_container_path_for_pid(_target, buf, MAXPATHLEN) == KERN_SUCCESS) { 131 | container = @(buf); 132 | } 133 | free(buf); 134 | 135 | if (container.length == 0) { 136 | container = kRDFallbackSandboxContainer; 137 | } 138 | NSString *unique_filename = [NSString stringWithFormat: @"%@.%f", 139 | [_payload lastPathComponent], 140 | [NSDate timeIntervalSinceReferenceDate]]; 141 | 142 | return [container stringByAppendingPathComponent: unique_filename]; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /RDInjectionWizard/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDIWDaemonMasterTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RDIWDaemonMasterTests.m 3 | // RDInjectionWizard 4 | // 5 | // Created by Dmitry Rodionov on 7/13/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RDIWDeamonMaster.h" 11 | 12 | @interface RDIWDaemonMasterTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation RDIWDaemonMasterTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testConnection 29 | { 30 | RDIWDeamonMaster *master = [RDIWDeamonMaster sharedMaster]; 31 | XCTestExpectation *callbackFiredExpectation = [self expectationWithDescription: @"callback fired"]; 32 | 33 | [master tellDeamonToInjectTarget: getpid() 34 | withPayload: @"placeholder" 35 | completionHandler: 36 | ^(xpc_object_t reply, RDIWConnectionError error) { 37 | 38 | XCTAssert(error == kSuccess); 39 | XCTAssert(reply); 40 | if (reply) { 41 | // It's just a connection test, so we don't care wheither it successed or fail 42 | // BOOL success = xpc_dictionary_get_bool(reply, "status"); 43 | // XCTAssertTrue(success); 44 | } 45 | [callbackFiredExpectation fulfill]; 46 | }]; 47 | 48 | [self waitForExpectationsWithTimeout: 10 handler: ^(NSError *error) { 49 | XCTAssertNil(error); 50 | }]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | me.rodionovd.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RDInjectionWizardTests.m 3 | // RDInjectionWizardTests 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "RDInjectionWizard.h" 12 | 13 | 14 | @interface RDInjectionWizardTests : XCTestCase 15 | 16 | @end 17 | 18 | @implementation RDInjectionWizardTests 19 | 20 | - (void)setUp 21 | { 22 | [super setUp]; 23 | // Put setup code here. This method is called before the invocation of each test method in the class. 24 | } 25 | 26 | - (void)tearDown 27 | { 28 | // Put teardown code here. This method is called after the invocation of each test method in the class. 29 | [super tearDown]; 30 | } 31 | 32 | 33 | 34 | - (void)testInjectionInto64BitSandboxedTarget 35 | { 36 | NSString *libnoop64 = [[NSBundle mainBundle] pathForResource: @"libtestnoop64" ofType: @"dylib"]; 37 | XCTAssert(libnoop64.length > 0); 38 | 39 | /* Use Mail.app as a target */ 40 | [[NSWorkspace sharedWorkspace] launchApplication: @"Mail"]; 41 | NSRunningApplication *mail = nil; 42 | do { 43 | mail = [[NSRunningApplication runningApplicationsWithBundleIdentifier: 44 | @"com.apple.mail"] firstObject]; 45 | } while (!mail); 46 | sleep(1); // let em initialize a bit 47 | XCTAssert(mail.processIdentifier > 0); 48 | 49 | RDInjectionWizard *wizard = [[RDInjectionWizard alloc] initWithTarget: mail.processIdentifier 50 | payload: libnoop64]; 51 | __block BOOL fired = NO; 52 | XCTestExpectation *callbackFiredExpectation = [self expectationWithDescription: @"callback fired"]; 53 | [wizard injectUsingCompletionBlockWithSuccess: ^{ 54 | fired = YES; 55 | [callbackFiredExpectation fulfill]; 56 | } failure: ^(RDInjectionError error) { 57 | fired = YES; 58 | XCTFail(@"This test should pass, but here we've got an error: %d", error); 59 | [callbackFiredExpectation fulfill]; 60 | }]; 61 | 62 | [self waitForExpectationsWithTimeout: 10 63 | handler: 64 | ^(NSError *error) { 65 | [mail terminate]; 66 | XCTAssertNil(error); 67 | XCTAssert(fired); 68 | }]; 69 | } 70 | 71 | - (void)testInjectionInto64BitTarget 72 | { 73 | NSURL *target_url = [[NSBundle mainBundle] URLForResource: @"demoTarget64" withExtension: @"app"]; 74 | XCTAssert(target_url.absoluteString.length > 0); 75 | 76 | NSError *launchError = nil; 77 | [[NSWorkspace sharedWorkspace] launchApplicationAtURL: target_url 78 | options: (NSWorkspaceLaunchDefault | NSWorkspaceLaunchAndHide) 79 | configuration: nil 80 | error: &launchError]; 81 | XCTAssertNil(launchError); 82 | NSRunningApplication *target64 = nil; 83 | do { 84 | target64 = [[NSRunningApplication runningApplicationsWithBundleIdentifier: 85 | @"me.rodionovd.RDInjectionWizard.demoTarget64"] firstObject]; 86 | } while (!target64); 87 | sleep(1); // let em initialize a bit 88 | XCTAssert(target64.processIdentifier > 0); 89 | 90 | NSString *libnoop64 = [[NSBundle mainBundle] pathForResource: @"libtestnoop64" ofType: @"dylib"]; 91 | XCTAssert(libnoop64.length > 0); 92 | 93 | RDInjectionWizard *wizard = [[RDInjectionWizard alloc] initWithTarget: target64.processIdentifier 94 | payload: libnoop64]; 95 | __block BOOL fired = NO; 96 | XCTestExpectation *callbackFiredExpectation = [self expectationWithDescription: @"callback fired"]; 97 | [wizard injectUsingCompletionBlockWithSuccess: ^{ 98 | fired = YES; 99 | [callbackFiredExpectation fulfill]; 100 | } failure: ^(RDInjectionError error) { 101 | fired = YES; 102 | XCTFail(@"This test should pass, but here we've got an error: %d", error); 103 | [callbackFiredExpectation fulfill]; 104 | }]; 105 | 106 | [self waitForExpectationsWithTimeout: 10 107 | handler: 108 | ^(NSError *error) { 109 | [target64 terminate]; 110 | XCTAssertNil(error); 111 | XCTAssert(fired); 112 | }]; 113 | 114 | } 115 | 116 | - (void)testInvalidPayload 117 | { 118 | XCTestExpectation *callbackFiredExpectation = [self expectationWithDescription: @"callback fired"]; 119 | RDInjectionWizard *wizard = [[RDInjectionWizard alloc] initWithTarget: getpid() 120 | payload: @"invalid"]; 121 | __block BOOL fired = NO; 122 | [wizard injectUsingCompletionBlockWithSuccess: ^{ 123 | fired = YES; 124 | XCTFail(@"This test should not succeed"); 125 | [callbackFiredExpectation fulfill]; 126 | } failure: ^(RDInjectionError error) { 127 | fired = YES; 128 | XCTAssert(error == kInvalidPayload); 129 | [callbackFiredExpectation fulfill]; 130 | }]; 131 | 132 | [self waitForExpectationsWithTimeout: 10 133 | handler: 134 | ^(NSError *error) { 135 | XCTAssert(fired); 136 | }]; 137 | } 138 | 139 | - (void)testInvalidPid 140 | { 141 | XCTestExpectation *callbackFiredExpectation = [self expectationWithDescription: @"callback fired"]; 142 | pid_t invalid_target = -123; 143 | NSString *valid_payload = [[NSBundle bundleForClass: 144 | NSClassFromString(@"RDInjectionWizard")] bundlePath]; 145 | XCTAssert(valid_payload.length > 0); 146 | 147 | RDInjectionWizard *wizard = [[RDInjectionWizard alloc] initWithTarget: invalid_target 148 | payload: valid_payload]; 149 | __block BOOL fired = NO; 150 | [wizard injectUsingCompletionBlockWithSuccess: ^{ 151 | fired = YES; 152 | XCTFail(@"This test should not succeed"); 153 | [callbackFiredExpectation fulfill]; 154 | 155 | } failure: ^(RDInjectionError error) { 156 | fired = YES; 157 | XCTAssert(error == kInvalidProcessIdentifier); 158 | [callbackFiredExpectation fulfill]; 159 | }]; 160 | 161 | [self waitForExpectationsWithTimeout: 10 162 | handler: 163 | ^(NSError *error) { 164 | XCTAssert(fired); 165 | }]; 166 | } 167 | 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTestsHost/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // RDInjectionWizardTestsHost 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @property (assign) IBOutlet NSWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTestsHost/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // RDInjectionWizardTestsHost 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 14 | { 15 | // Insert code here to initialize your application 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTestsHost/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTestsHost/RDInjectionWizardTestsHost-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | me.rodionovd.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2014 rodionovd. All rights reserved. 29 | NSPrincipalClass 30 | NSApplication 31 | SMPrivilegedExecutables 32 | 33 | me.rodionovd.RDInjectionWizard.injector 34 | certificate leaf[subject.CN] /* check if even codesigned; who cares, anyway */ 35 | 36 | LSUIElement 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTestsHost/RDInjectionWizardTestsHost-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/RDInjectionWizardTestsHost/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // RDInjectionWizardTestsHost 4 | // 5 | // Created by Dmitry Rodionov on 7/12/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) 12 | { 13 | return NSApplicationMain(argc, argv); 14 | } 15 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/demoTarget64/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // demoTarget32 4 | // 5 | // Created by Dmitry Rodionov on 7/14/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/demoTarget64/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // demoTarget32 4 | // 5 | // Created by Dmitry Rodionov on 7/14/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @property (weak) IBOutlet NSWindow *window; 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 20 | // Insert code here to initialize your application 21 | } 22 | 23 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 24 | // Insert code here to tear down your application 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/demoTarget64/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 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 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | Default 535 | 536 | 537 | 538 | 539 | 540 | 541 | Left to Right 542 | 543 | 544 | 545 | 546 | 547 | 548 | Right to Left 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | Default 560 | 561 | 562 | 563 | 564 | 565 | 566 | Left to Right 567 | 568 | 569 | 570 | 571 | 572 | 573 | Right to Left 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/demoTarget64/demoTarget64-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | me.rodionovd.RDInjectionWizard.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSApplicationCategoryType 26 | public.app-category.developer-tools 27 | LSMinimumSystemVersion 28 | ${MACOSX_DEPLOYMENT_TARGET} 29 | NSHumanReadableCopyright 30 | Copyright © 2014 rodionovd. All rights reserved. 31 | NSMainNibFile 32 | MainMenu 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/demoTarget64/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // demoTarget32 4 | // 5 | // Created by Dmitry Rodionov on 7/14/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/libtestnoop64/libtestnoop.h: -------------------------------------------------------------------------------- 1 | // 2 | // libtestnoop.h 3 | // libtestnoop 4 | // 5 | // Created by Dmitry Rodionov on 7/14/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * A simple Cocoa library that prints "Hello, hack!" into stderr 13 | * on load. 14 | */ 15 | @interface libtestnoop : NSObject 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RDInjectionWizardTests/libtestnoop64/libtestnoop.m: -------------------------------------------------------------------------------- 1 | // 2 | // libtestnoop.m 3 | // libtestnoop 4 | // 5 | // Created by Dmitry Rodionov on 7/14/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #import "libtestnoop.h" 10 | 11 | @implementation libtestnoop 12 | 13 | + (void)load 14 | { 15 | @autoreleasepool { 16 | NSLog(@"Hello, Hack!"); 17 | } 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### You can create everything. You can destroy everything as well. 💉 2 | 3 | `RDInjectionWizard` is a small Objective-C framework for injecting our own code into another running applications. That is: you can create plugins for your favorite applications, modify system utilities (remember the [Dropbox's Finder hack](http://stackoverflow.com/questions/8380562/) to show icons over folders?) and make fun! 4 | 5 | To help you with this, `RDInjectionWizard` has a simple API for loading a prepared dynamic library into your target: 6 | 7 | ```objc 8 | pid_t target_proc = ...; 9 | NSString *payload_path = @"/tmp/finder_payload.dylib" 10 | RDInjectionWizard *wizard = [[RDInjectionWizard alloc] initWithTarget: target_proc 11 | payload: payload_path]; 12 | [wizard injectUsingCompletionBlockWithSuccess: ^{ 13 | NSLog(@"Yay, we've loaded some code into Finder!"); 14 | } failrue: ^(RDInjectionError error) { 15 | NSLog(@"Ooops, something went wrong. Error code: %d", error); 16 | }]; 17 | ``` 18 | > You can find way more examples in tests files within the `/RDInjectionWizardTests` directory of this repo. 19 | 20 | Please take into account that, since the project is still in alpha version, there're some limitations: 21 | * The only supported target arhitecture is `x86_64`. I'm not sure about adding i386, but pull requests are welcome; 22 | * ~~It is only tested on OS X 10.9. See [issue #1](https://github.com/rodionovd/RDInjectionWizard/issues/1).~~ It does work on both 10.9 and 10.10; 23 | * API is unstable and is going to change in the future; 24 | 25 | *I also guess you're more interested in the [`develop`](https://github.com/rodionovd/RDInjectionWizard/tree/develop) branch.* 26 | 27 | #### What's the payload? 28 | ----- 29 | Note that your payload is a dynamic library that have either a **constructor** function: 30 | ```cpp 31 | __attribute__((constructor)) 32 | void this_function_will_be_launched_when_the_library_is_injected_into_target_process(void) 33 | { 34 | /* Do all the scary things here ... */ 35 | fprintf(stderr, "Hello from payload!"); 36 | draw_finder_folder_icons_and_more(); 37 | } 38 | ``` 39 | or an Objective-C **class implementing** the `+load` method: 40 | 41 | ```objc 42 | @implementation KWFinderModifer 43 | 44 | + (void)load 45 | { 46 | NSLog(@"Hello from payload!"); 47 | [self drawFinderIcons]; 48 | } 49 | 50 | @end 51 | ``` 52 | 53 | > If your payload have both a constructor and a class with `+load` method, both will be executed at this point, so choose only one. 54 | 55 | #### How to set it up 56 | ------ 57 | Pretty simple! 58 | 59 | 1. First, compile your own version of `RDInjectionWizard` using the project in this repository, add this framework to your project (don't forget to create a Copy File build phase for it) and link your application against the `RDInjectionWizard`. 60 | 61 | **Don't forget to change a `Code Signing Identity` project setting to your own certificate name. *Make sure that you're using the same certificate for your main project.*** 62 | 63 | 2. Next, open your application's Info.plist and add the following key to the dictionary there: 64 | 65 | ```xml 66 | SMPrivilegedExecutables 67 | 68 | me.rodionovd.RDInjectionWizard.injector 69 | certificate leaf[subject.CN] 70 | 71 | ``` 72 | You need this because `RDInjectionWizard` uses a privileged XPC helper tool internally (in order to perform any injection), and this tool (following the Apple's rules) must match in security requirements with its host application that appears to be your application. So you're just saying «Hey OS X, I do know about this helper, allow me to work with them". 73 | 74 | #### Interfaces 75 | 76 | > **Please note that these APIs is subject to change in future versions of the framework!** 77 | 78 | `RDInjectionWizard` exports only one self-titled class that have the following methods: 79 | 80 | ----- 81 | **`-initWithTarget:payload:`** 82 | Initialize an injection wizard for a given target and payload filepath.   83 | ```objc 84 | - (instancetype)initWithTarget: (pid_t)target payload: (NSString *)payload; 85 | ``` 86 | **Parameters** 87 | 88 | Parameter | Type | Description 89 | :--------: | :-----------: | :---------- 90 | `target` | `pid_t` | the identifer of the target process 91 | `payload` | `NSString *` | the full path to the payload library 92 | 93 | **Return value** 94 | An initialized injection wizard ready to be used in a wild. 95 | 96 | ----- 97 | **`-injectUsingCompletionBlockWithSuccess:failrue:`** 98 | Asynchronously inject the given target with the given payload library. 99 | 100 | ```objc 101 | - (void)injectUsingCompletionBlockWithSuccess: (RDInjectionSuccededBlock) success 102 | failure: (RDInjectionFailedBlock) failure; 103 | ``` 104 | 105 | **Parameters** 106 | 107 | Parameter | Type | Description 108 | :--------: | :-----------: | :---------- 109 | `success` | `RDInjectionSuccededBlock` | The block to be executed on the completion of the injection. It takes no arguments and has no return value 110 | `failure` | `RDInjectionFailedBlock` | The block to be executed upon an injection error. It has no return value and takes one argument: an error that occured during the injection 111 | 112 | ----- 113 | **`-sandboxFriendlyPayloadPath`** 114 | Looks up a sandbox-friendly location of the payload. 115 | 116 | ```objc 117 | - (NSString *)sandboxFriendlyPayloadPath; 118 | ``` 119 | 120 | **Return value** 121 | A new unique filename for the payload inside the target's sandbox container. 122 | 123 | **Discussion** 124 | Use this method if you want to copy the payload into a location within the target's sandbox contaner that is said to be accessible for this process. 125 | 126 | 127 | 128 | ------ 129 | 🔓 130 | If you found any bug(s) or something, please open an issue or a pull request — I'd appreciate your help! `(^,,^)` 131 | 132 | ------ 133 | 134 | *Dmitry Rodionov, 2014* 135 | *i.am.rodionovd@gmail.com* 136 | -------------------------------------------------------------------------------- /injector/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // main.c 3 | // injector 4 | // 5 | // Created by Dmitry Rodionov on 7/13/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include "rd_inject_library.h" 12 | 13 | #define kIdleExitTimeoutSec (10) 14 | #define kDefaultIdleTime (dispatch_time(DISPATCH_TIME_NOW, kIdleExitTimeoutSec * NSEC_PER_SEC)) 15 | #define kDeamonIdentifer "me.rodionovd.RDInjectionWizard.injector" 16 | 17 | static dispatch_source_t idle_exit_timer = NULL; 18 | 19 | static bool main_routine(xpc_object_t dictionary) 20 | { 21 | pid_t target = (pid_t)xpc_dictionary_get_int64(dictionary, "target"); 22 | if (target <= 0) { 23 | return false; 24 | } 25 | const char *payload_path = xpc_dictionary_get_string(dictionary, "payload"); 26 | syslog(LOG_NOTICE, "Inject (%d) <- [%s] ", target, payload_path); 27 | if (!payload_path) { 28 | return false; 29 | } 30 | return (KERN_SUCCESS == rd_inject_library(target, payload_path)); 31 | } 32 | 33 | static void __XPC_Connection_Handler(xpc_connection_t connection) { 34 | xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { 35 | if (xpc_get_type(event) != XPC_TYPE_ERROR) { 36 | 37 | /* Pause an idle-exit timer */ 38 | dispatch_source_set_timer(idle_exit_timer, DISPATCH_TIME_FOREVER, 0, 0); 39 | { 40 | bool success = main_routine(event); 41 | xpc_connection_t remote = xpc_dictionary_get_remote_connection(event); 42 | xpc_object_t reply = xpc_dictionary_create_reply(event); 43 | xpc_dictionary_set_bool(reply, "status", success); 44 | xpc_connection_send_message(remote, reply); 45 | xpc_release(reply); 46 | } 47 | /* Reset the timer */ 48 | dispatch_source_set_timer(idle_exit_timer, kDefaultIdleTime, 0, 0); 49 | } else { 50 | // error handling? 51 | } 52 | }); 53 | 54 | xpc_connection_resume(connection); 55 | } 56 | 57 | int main(__unused int argc, __unused const char *argv[]) { 58 | xpc_connection_t service = xpc_connection_create_mach_service(kDeamonIdentifer, 59 | dispatch_get_main_queue(), 60 | XPC_CONNECTION_MACH_SERVICE_LISTENER); 61 | if (!service) { 62 | syslog(LOG_NOTICE, "Failed to create an XPC service."); 63 | exit(EXIT_FAILURE); 64 | } 65 | 66 | syslog(LOG_NOTICE, "Configuring connection event handler for helper"); 67 | xpc_connection_set_event_handler(service, ^(xpc_object_t connection) { 68 | __XPC_Connection_Handler(connection); 69 | }); 70 | 71 | /* Set up an idle-exit timer. @see kIdleExitTimeoutSec for timeout value. */ 72 | idle_exit_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, 73 | dispatch_get_main_queue()); 74 | if (!idle_exit_timer) { 75 | syslog(LOG_NOTICE, "Failed to create an idle-exit timer source."); 76 | exit(EXIT_FAILURE); 77 | } 78 | dispatch_set_context(idle_exit_timer, NULL); 79 | dispatch_source_set_event_handler_f(idle_exit_timer, (void (*)(void *))exit); 80 | dispatch_source_set_timer(idle_exit_timer, kDefaultIdleTime, 0, 0); 81 | dispatch_resume(idle_exit_timer); 82 | 83 | xpc_connection_resume(service); 84 | dispatch_main(); 85 | xpc_release(service); 86 | 87 | return EXIT_SUCCESS; 88 | } 89 | -------------------------------------------------------------------------------- /injector/me.rodionovd.RDInjectionWizard.injector-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | me.rodionovd.RDInjectionWizard.injector 7 | CFBundleInfoDictionaryVersion 8 | 6.0 9 | CFBundleName 10 | me.rodionovd.RDInjectionWizard.injector 11 | CFBundleVersion 12 | 1.0 13 | SMAuthorizedClients 14 | 15 | certificate leaf[subject.CN] /* exists */ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /injector/me.rodionovd.RDInjectionWizard.injector-Launchd.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | me.rodionovd.RDInjectionWizard.injector 7 | MachServices 8 | 9 | me.rodionovd.RDInjectionWizard.injector 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /injector/rd_inject_library/rd_inject_library.c: -------------------------------------------------------------------------------- 1 | // 2 | // rd_inject_library.c 3 | // rd_inject_library 4 | // 5 | // Created by Dmitry Rodionov on 5/31/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "rd_inject_library.h" 22 | 23 | #define kRDRemoteStackSize (25*1024) 24 | #define kRDShouldJumpToDlopen 0xabad1dea 25 | 26 | #define RDFailOnError(function) {if (err != KERN_SUCCESS) {syslog(LOG_NOTICE, "[%d] %s failed with error: %s\n", \ 27 | __LINE__-1, function, mach_error_string(err)); return (err);}} 28 | 29 | #pragma mark - Private Interface 30 | 31 | static int load_library_into_task(task_t task, const char *library_path, void **return_value); 32 | static mach_port_t 33 | init_exception_port_for_thread(thread_act_t thread, thread_state_flavor_t thread_flavor); 34 | static bool process_is_64_bit(pid_t proc); 35 | 36 | /* Received from xnu/bsd/uxkern/ux_exception.c 37 | * (Apple's XNU version 2422.90.20) 38 | */ 39 | typedef struct { 40 | mach_msg_header_t Head; 41 | /* start of the kernel processed data */ 42 | mach_msg_body_t msgh_body; 43 | mach_msg_port_descriptor_t thread; 44 | mach_msg_port_descriptor_t task; 45 | /* end of the kernel processed data */ 46 | NDR_record_t NDR; 47 | exception_type_t exception; 48 | mach_msg_type_number_t codeCnt; 49 | mach_exception_data_t code; 50 | /* some times RCV_TO_LARGE probs */ 51 | char pad[512]; 52 | } exc_msg_t; 53 | 54 | #pragma mark - Implementation 55 | 56 | int rd_inject_library(pid_t target_proc, const char *library_path) 57 | { 58 | int err = KERN_FAILURE; 59 | if (target_proc <= 0 || !library_path) { 60 | return (err); 61 | } 62 | 63 | /* Yeah, I know, there're lots of i386 apps. 64 | * No. 65 | * There aren't. 66 | * YOLO. 67 | */ 68 | bool proc64bit = process_is_64_bit(target_proc); 69 | if (!proc64bit) { 70 | syslog(LOG_NOTICE, "[The target task should be a 64 bit process]"); 71 | goto end; 72 | } 73 | 74 | task_t task; 75 | /* You should be a member of procmod users group in order to 76 | * use task_for_pid(). Being root is OK. */ 77 | err = task_for_pid(mach_task_self(), target_proc, &task); 78 | if (err != KERN_SUCCESS) { 79 | syslog(LOG_NOTICE, "task_for_pid() failed with error: %s [%d]", 80 | mach_error_string(err), err); 81 | goto end; 82 | } 83 | void *remote_dlopen_return_value = NULL; 84 | err = load_library_into_task(task, library_path, &remote_dlopen_return_value); 85 | if (err != KERN_SUCCESS) { 86 | syslog(LOG_NOTICE, "load_library_into_task() failed with error: %s [%d]", 87 | mach_error_string(err), err); 88 | goto end; 89 | } 90 | if (remote_dlopen_return_value == NULL) { 91 | err = KERN_INVALID_OBJECT; 92 | syslog(LOG_NOTICE, "Remote dlopen() failed"); 93 | goto end; 94 | } 95 | 96 | end: 97 | return (err); 98 | } 99 | 100 | /** 101 | * @abstract 102 | * Check wheither the given task is a 64 bit process. 103 | * 104 | * @return YES 105 | * Means the process' architecture is x86_64 (also ppcp64, but who cares) 106 | * @return NO 107 | * Means it's not 108 | */ 109 | static 110 | bool process_is_64_bit(pid_t proc) 111 | { 112 | int mib[4] = { 113 | CTL_KERN, KERN_PROC, KERN_PROC_PID, proc 114 | }; 115 | struct kinfo_proc info; 116 | size_t size = sizeof(info); 117 | 118 | if (sysctl(mib, 4, &info, &size, NULL, 0) == KERN_SUCCESS) { 119 | return (info.kp_proc.p_flag & P_LP64); 120 | } else { 121 | return false; 122 | } 123 | } 124 | 125 | /** 126 | * @abstract 127 | * Load a library into a given task. 128 | * 129 | * @discussion 130 | * This function creates a remote thread inside the task and perform dlopen() 131 | * on this thread. 132 | * 133 | * As the created thead is a plain mach thread, we also need to convert it into a UNIX 134 | * pthead before calling dlopen(). To do that we'll set up an exeption handler for the 135 | * remote thread, then call _pthread_set_self() with invalid return address on it, catch 136 | * an EXC_BAD_ACCESS exception, re-configure the thread to call dlopen() and resume it. 137 | * We'll also gracefully terminate the thread when dlopen() returned. 138 | * 139 | * @return 140 | * KERN_SUCCESS if injection was done without errors 141 | * @return 142 | * KERN_FAILRUE if there're some injection errors 143 | */ 144 | static 145 | int load_library_into_task(task_t task, const char *library_path, void **return_value) 146 | { 147 | if (!task) return KERN_INVALID_ARGUMENT; 148 | int err = KERN_FAILURE; 149 | 150 | /* Copy the library path into target's address space */ 151 | size_t path_size = strlen(library_path) + 1; 152 | mach_vm_address_t rlibrary = 0; 153 | err = mach_vm_allocate(task, &rlibrary, path_size, VM_FLAGS_ANYWHERE); 154 | RDFailOnError("mach_vm_allocate"); 155 | err = mach_vm_write(task, rlibrary, (vm_offset_t)library_path, 156 | (mach_msg_type_number_t)path_size); 157 | RDFailOnError("mach_vm_write"); 158 | 159 | /* Compose a fake backtrace and allocate remote stack. */ 160 | uint64_t fake_backtrace[] = { 161 | kRDShouldJumpToDlopen 162 | }; 163 | mach_vm_address_t stack = 0; 164 | err = mach_vm_allocate(task, &stack, (kRDRemoteStackSize + sizeof(fake_backtrace)), 165 | VM_FLAGS_ANYWHERE); 166 | RDFailOnError("mach_vm_allocate"); 167 | 168 | /* Reserve some place for a pthread struct */ 169 | mach_vm_address_t pthread_struct = stack; 170 | 171 | /* Copy the backtrace to the top of remote stack */ 172 | err = mach_vm_write(task, (stack + kRDRemoteStackSize), (vm_offset_t)fake_backtrace, 173 | (mach_msg_type_number_t)sizeof(fake_backtrace)); 174 | RDFailOnError("mach_vm_write"); 175 | 176 | /* Initialize a remote thread state */ 177 | x86_thread_state64_t state; 178 | memset(&state, 0, sizeof(state)); 179 | state.__rbp = stack; 180 | state.__rsp = stack + kRDRemoteStackSize; 181 | 182 | /* We'll jump right into _pthread_set_self() to convert 183 | * our mach thread into real POSIX thread */ 184 | void *pthread_set_self = dlsym(RTLD_DEFAULT, "_pthread_set_self"); 185 | if (!pthread_set_self) { 186 | err = KERN_INVALID_HOST; 187 | RDFailOnError("dlsym(\"_pthread_set_self\")"); 188 | } 189 | state.__rip = (mach_vm_address_t)pthread_set_self; 190 | state.__rdi = pthread_struct; 191 | /* Store the library path here for dlopen() */ 192 | state.__rbx = rlibrary; 193 | 194 | /* Create a remote thread, set up an exception port for it 195 | * (so we will be able to handle ECX_BAD_ACCESS exceptions) */ 196 | thread_act_t remote_thread = 0; 197 | err = thread_create(task, &remote_thread); 198 | RDFailOnError("thead_create"); 199 | err = thread_set_state(remote_thread, x86_THREAD_STATE64, 200 | (thread_state_t)&state, x86_THREAD_STATE64_COUNT); 201 | RDFailOnError("thread_set_state"); 202 | 203 | mach_port_t exception_port = 0; 204 | exception_port = init_exception_port_for_thread(remote_thread, x86_THREAD_STATE64); 205 | if (!exception_port) { 206 | err = KERN_FAILURE; 207 | RDFailOnError("init_exception_handler_for_thread"); 208 | } 209 | err = thread_resume(remote_thread); 210 | RDFailOnError("thread_resume"); 211 | 212 | /* Exception handling loop */ 213 | while (1) { 214 | /* Use exc_server() as a generic server for sending/receiving exception messages */ 215 | extern boolean_t exc_server(mach_msg_header_t *request, mach_msg_header_t *reply); 216 | err = mach_msg_server_once(exc_server, sizeof(exc_msg_t), exception_port, 0); 217 | RDFailOnError("mach_msg_server_once"); 218 | 219 | thread_basic_info_data_t thread_basic_info; 220 | mach_msg_type_number_t thread_basic_info_count = THREAD_BASIC_INFO_COUNT; 221 | err = thread_info(remote_thread, THREAD_BASIC_INFO, 222 | (thread_info_t)&thread_basic_info, &thread_basic_info_count); 223 | RDFailOnError("thread_info"); 224 | 225 | /* Chech if we've already suspended the thread inside our exception handler */ 226 | if (thread_basic_info.suspend_count > 0) { 227 | /* So retrive the dlopen() return value first */ 228 | if (return_value) { 229 | x86_thread_state64_t updated_state; 230 | mach_msg_type_number_t state_count = x86_THREAD_STATE64_COUNT; 231 | err = thread_get_state(remote_thread, x86_THREAD_STATE64, 232 | (thread_state_t)&updated_state, &state_count); 233 | RDFailOnError("thread_get_state"); 234 | *return_value = (void *)updated_state.__rax; 235 | } 236 | 237 | /* then terminate the remote thread */ 238 | err = thread_terminate(remote_thread); 239 | RDFailOnError("thead_terminate"); 240 | /* and do some memory clean-up */ 241 | err = mach_vm_deallocate(task, rlibrary, path_size); 242 | RDFailOnError("mach_vm_deallocate"); 243 | err = mach_vm_deallocate(task, stack, kRDRemoteStackSize); 244 | RDFailOnError("mach_vm_deallocate"); 245 | err = mach_port_deallocate(mach_task_self(), exception_port); 246 | RDFailOnError("mach_port_deallocate"); 247 | break; 248 | } 249 | } 250 | 251 | return err; 252 | } 253 | 254 | 255 | /** 256 | * @abstract 257 | * Initialize an EXC_BAD_ACCESS exception port for the given thread, and set it 258 | * for this thread. 259 | * 260 | * @return 261 | * An identifier of the initialized exception port for catching EXC_BAD_ACCESS 262 | * @return 263 | * (0) that means the kernel failed to initizalize the exception port for the given thread 264 | */ 265 | static 266 | mach_port_t init_exception_port_for_thread(thread_act_t thread, thread_state_flavor_t thread_flavor) 267 | { 268 | int err = KERN_FAILURE; 269 | /* Allocate an exception port */ 270 | mach_port_name_t exception_port; 271 | err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &exception_port); 272 | if (err != KERN_SUCCESS) return (0); 273 | err = mach_port_insert_right(mach_task_self(), exception_port, exception_port, 274 | MACH_MSG_TYPE_MAKE_SEND); 275 | if (err != KERN_SUCCESS) return (0); 276 | /* Assign this port to our thread */ 277 | err = thread_set_exception_ports(thread, EXC_MASK_ALL, 278 | exception_port, EXCEPTION_STATE_IDENTITY, 279 | thread_flavor); 280 | if (err != KERN_SUCCESS) return (0); 281 | 282 | return exception_port; 283 | } 284 | 285 | 286 | #pragma clang diagnostic push 287 | #pragma clang diagnostic ignored "-Wmissing-prototypes" 288 | /** 289 | * @abstract 290 | * Custom EXC_BAD_ACCESS exception handler, called by exc_server(). 291 | * 292 | * @return 293 | * KERN_SUCCESS indicates that we've reset a thread state and it's ready to be run again 294 | * @return 295 | * MIG_NO_REPLY indicates that we've terminated or suspended the thread, so the kernel won't 296 | * handle it anymore. This one also breaks our exception handling loop, so we 297 | * can finish the injection process 298 | * @return 299 | * KERN_FAILURE indicates that we was not expect this kind of exception and the kernel should 300 | * find another handler for it 301 | * 302 | */ 303 | __attribute__((visibility("default"))) 304 | kern_return_t 305 | catch_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, 306 | mach_port_t task, exception_type_t exception, 307 | exception_data_t code, mach_msg_type_number_t code_count, 308 | int *flavor, thread_state_t in_state, 309 | mach_msg_type_number_t in_state_count, 310 | thread_state_t out_state, 311 | mach_msg_type_number_t *out_state_count) 312 | { 313 | #pragma unused (exception_port, task) 314 | #pragma unused (exception, code, code_count, in_state_count, out_state, out_state_count) 315 | 316 | if (*flavor != x86_THREAD_STATE64) { 317 | return KERN_FAILURE; 318 | } 319 | 320 | if (((x86_thread_state64_t *)in_state)->__rip == kRDShouldJumpToDlopen) { 321 | /* Prepare the thread to execute dlopen() */ 322 | ((x86_thread_state64_t *)out_state)->__rip = (uint64_t)&dlopen; 323 | ((x86_thread_state64_t *)out_state)->__rsi = RTLD_NOW | RTLD_LOCAL; 324 | ((x86_thread_state64_t *)out_state)->__rdi = ((x86_thread_state64_t *)in_state)->__rbx; 325 | /* Preserve the stack pointer */ 326 | uint64_t stack = ((x86_thread_state64_t *)in_state)->__rsp; 327 | ((x86_thread_state64_t *)out_state)->__rsp = stack; 328 | /* Indicate that we've updateed this thread state and ready to resume it */ 329 | *out_state_count = x86_THREAD_STATE64_COUNT; 330 | 331 | return KERN_SUCCESS; 332 | } 333 | /* In any other case we want to gracefully terminate the thread, so our 334 | * target won't crash. */ 335 | thread_suspend(thread); 336 | 337 | return MIG_NO_REPLY; 338 | } 339 | #pragma clang diagnostic pop // ignored "-Wmissing-prototypes" 340 | -------------------------------------------------------------------------------- /injector/rd_inject_library/rd_inject_library.h: -------------------------------------------------------------------------------- 1 | // 2 | // rd_inject_library.h 3 | // rd_inject_library 4 | // 5 | // Created by Dmitry Rodionov on 5/31/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #pragma once 10 | 11 | /** 12 | * @abstract 13 | * Loads (injects) a dynamic library into a target process. 14 | * 15 | * @discussion 16 | * This function creates new thread in the target process and runs dlopen() on it. 17 | * 18 | * @see internal load_library_into_task() for details 19 | * 20 | * @param target 21 | * The identifer of the target process 22 | * @param library_path 23 | * The full path of the library to be injected 24 | * 25 | * @return KERN_SUCCESS 26 | * Means the completion of injection and library loading 27 | * @return KERN_INVALID_OBJECT 28 | * Means that the remote dlopen() failed to open the library 29 | * @return KERN_FAILURE 30 | * Means an error occured while injecting into the target 31 | */ 32 | int rd_inject_library(pid_t target, const char *library_path); 33 | -------------------------------------------------------------------------------- /unload_deamon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Unloading from Launchd..." 3 | sudo launchctl unload /Library/LaunchDaemons/me.rodionovd.RDInjectionWizard.injector.plist 4 | 5 | echo "Cleaning up /Library/LaunchDaemons/" 6 | sudo rm -f /Library/LaunchDaemons/me.rodionovd.RDInjectionWizard.injector.plist 7 | sudo rm -f /Library/PrivilegedHelperTools/me.rodionovd.RDInjectionWizard.injector.plist 8 | --------------------------------------------------------------------------------