├── .gitignore ├── SwiftMachOverride.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ └── SwiftMachOverride.xcscheme └── xcuserdata │ └── lombardo.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── SwiftMachOverride ├── SwiftMachOverride-Bridging-Header.h ├── mach │ ├── libudis86 │ │ ├── decode.c │ │ ├── decode.h │ │ ├── extern.h │ │ ├── input.c │ │ ├── input.h │ │ ├── itab.c │ │ ├── itab.h │ │ ├── syn-att.c │ │ ├── syn-intel.c │ │ ├── syn.c │ │ ├── syn.h │ │ ├── types.h │ │ ├── udint.h │ │ ├── udis86.c │ │ └── udis86.h │ ├── mach_override.c │ └── mach_override.h ├── main.swift └── override.c └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Xcode Patch 26 | *.xcodeproj/* 27 | !*.xcodeproj/project.pbxproj 28 | !*.xcodeproj/xcshareddata/ 29 | !*.xcworkspace/contents.xcworkspacedata 30 | /*.gcno 31 | -------------------------------------------------------------------------------- /SwiftMachOverride.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E8740965229B15300026A310 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8740964229B15300026A310 /* main.swift */; }; 11 | E8740981229B15820026A310 /* mach_override.c in Sources */ = {isa = PBXBuildFile; fileRef = E874096F229B15820026A310 /* mach_override.c */; }; 12 | E8740982229B15820026A310 /* itab.c in Sources */ = {isa = PBXBuildFile; fileRef = E8740973229B15820026A310 /* itab.c */; }; 13 | E8740983229B15820026A310 /* udis86.c in Sources */ = {isa = PBXBuildFile; fileRef = E8740977229B15820026A310 /* udis86.c */; }; 14 | E8740984229B15820026A310 /* decode.c in Sources */ = {isa = PBXBuildFile; fileRef = E8740978229B15820026A310 /* decode.c */; }; 15 | E8740985229B15820026A310 /* syn-att.c in Sources */ = {isa = PBXBuildFile; fileRef = E8740979229B15820026A310 /* syn-att.c */; }; 16 | E8740986229B15820026A310 /* input.c in Sources */ = {isa = PBXBuildFile; fileRef = E874097B229B15820026A310 /* input.c */; }; 17 | E8740987229B15820026A310 /* syn-intel.c in Sources */ = {isa = PBXBuildFile; fileRef = E874097C229B15820026A310 /* syn-intel.c */; }; 18 | E8740988229B15820026A310 /* syn.c in Sources */ = {isa = PBXBuildFile; fileRef = E874097F229B15820026A310 /* syn.c */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXCopyFilesBuildPhase section */ 22 | E874095F229B15300026A310 /* CopyFiles */ = { 23 | isa = PBXCopyFilesBuildPhase; 24 | buildActionMask = 2147483647; 25 | dstPath = /usr/share/man/man1/; 26 | dstSubfolderSpec = 0; 27 | files = ( 28 | ); 29 | runOnlyForDeploymentPostprocessing = 1; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | E8740961229B15300026A310 /* SwiftMachOverride */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SwiftMachOverride; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | E8740964229B15300026A310 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 36 | E874096B229B15580026A310 /* SwiftMachOverride-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SwiftMachOverride-Bridging-Header.h"; sourceTree = ""; }; 37 | E874096C229B15580026A310 /* override.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = override.c; sourceTree = ""; }; 38 | E874096F229B15820026A310 /* mach_override.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mach_override.c; sourceTree = ""; }; 39 | E8740970229B15820026A310 /* mach_override.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_override.h; sourceTree = ""; }; 40 | E8740972229B15820026A310 /* input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = input.h; sourceTree = ""; }; 41 | E8740973229B15820026A310 /* itab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = itab.c; sourceTree = ""; }; 42 | E8740974229B15820026A310 /* udint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udint.h; sourceTree = ""; }; 43 | E8740975229B15820026A310 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; 44 | E8740976229B15820026A310 /* syn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syn.h; sourceTree = ""; }; 45 | E8740977229B15820026A310 /* udis86.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udis86.c; sourceTree = ""; }; 46 | E8740978229B15820026A310 /* decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decode.c; sourceTree = ""; }; 47 | E8740979229B15820026A310 /* syn-att.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "syn-att.c"; sourceTree = ""; }; 48 | E874097A229B15820026A310 /* itab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itab.h; sourceTree = ""; }; 49 | E874097B229B15820026A310 /* input.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = input.c; sourceTree = ""; }; 50 | E874097C229B15820026A310 /* syn-intel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "syn-intel.c"; sourceTree = ""; }; 51 | E874097D229B15820026A310 /* udis86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udis86.h; sourceTree = ""; }; 52 | E874097E229B15820026A310 /* extern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = extern.h; sourceTree = ""; }; 53 | E874097F229B15820026A310 /* syn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = syn.c; sourceTree = ""; }; 54 | E8740980229B15820026A310 /* decode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decode.h; sourceTree = ""; }; 55 | E8740989229B25450026A310 /* readme.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = readme.md; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | E874095E229B15300026A310 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | E8740958229B15300026A310 = { 70 | isa = PBXGroup; 71 | children = ( 72 | E8740989229B25450026A310 /* readme.md */, 73 | E8740963229B15300026A310 /* SwiftMachOverride */, 74 | E8740962229B15300026A310 /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | E8740962229B15300026A310 /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | E8740961229B15300026A310 /* SwiftMachOverride */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | E8740963229B15300026A310 /* SwiftMachOverride */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | E874096E229B15820026A310 /* mach */, 90 | E8740964229B15300026A310 /* main.swift */, 91 | E874096C229B15580026A310 /* override.c */, 92 | E874096B229B15580026A310 /* SwiftMachOverride-Bridging-Header.h */, 93 | ); 94 | path = SwiftMachOverride; 95 | sourceTree = ""; 96 | }; 97 | E874096E229B15820026A310 /* mach */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | E874096F229B15820026A310 /* mach_override.c */, 101 | E8740970229B15820026A310 /* mach_override.h */, 102 | E8740971229B15820026A310 /* libudis86 */, 103 | ); 104 | path = mach; 105 | sourceTree = ""; 106 | }; 107 | E8740971229B15820026A310 /* libudis86 */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | E8740972229B15820026A310 /* input.h */, 111 | E8740973229B15820026A310 /* itab.c */, 112 | E8740974229B15820026A310 /* udint.h */, 113 | E8740975229B15820026A310 /* types.h */, 114 | E8740976229B15820026A310 /* syn.h */, 115 | E8740977229B15820026A310 /* udis86.c */, 116 | E8740978229B15820026A310 /* decode.c */, 117 | E8740979229B15820026A310 /* syn-att.c */, 118 | E874097A229B15820026A310 /* itab.h */, 119 | E874097B229B15820026A310 /* input.c */, 120 | E874097C229B15820026A310 /* syn-intel.c */, 121 | E874097D229B15820026A310 /* udis86.h */, 122 | E874097E229B15820026A310 /* extern.h */, 123 | E874097F229B15820026A310 /* syn.c */, 124 | E8740980229B15820026A310 /* decode.h */, 125 | ); 126 | path = libudis86; 127 | sourceTree = ""; 128 | }; 129 | /* End PBXGroup section */ 130 | 131 | /* Begin PBXNativeTarget section */ 132 | E8740960229B15300026A310 /* SwiftMachOverride */ = { 133 | isa = PBXNativeTarget; 134 | buildConfigurationList = E8740968229B15300026A310 /* Build configuration list for PBXNativeTarget "SwiftMachOverride" */; 135 | buildPhases = ( 136 | E874095D229B15300026A310 /* Sources */, 137 | E874095E229B15300026A310 /* Frameworks */, 138 | E874095F229B15300026A310 /* CopyFiles */, 139 | ); 140 | buildRules = ( 141 | ); 142 | dependencies = ( 143 | ); 144 | name = SwiftMachOverride; 145 | productName = SwiftMachOverride; 146 | productReference = E8740961229B15300026A310 /* SwiftMachOverride */; 147 | productType = "com.apple.product-type.tool"; 148 | }; 149 | /* End PBXNativeTarget section */ 150 | 151 | /* Begin PBXProject section */ 152 | E8740959229B15300026A310 /* Project object */ = { 153 | isa = PBXProject; 154 | attributes = { 155 | LastSwiftUpdateCheck = 1020; 156 | LastUpgradeCheck = 1020; 157 | ORGANIZATIONNAME = "Fabio Lombardo"; 158 | TargetAttributes = { 159 | E8740960229B15300026A310 = { 160 | CreatedOnToolsVersion = 10.2.1; 161 | LastSwiftMigration = 1020; 162 | }; 163 | }; 164 | }; 165 | buildConfigurationList = E874095C229B15300026A310 /* Build configuration list for PBXProject "SwiftMachOverride" */; 166 | compatibilityVersion = "Xcode 9.3"; 167 | developmentRegion = en; 168 | hasScannedForEncodings = 0; 169 | knownRegions = ( 170 | en, 171 | ); 172 | mainGroup = E8740958229B15300026A310; 173 | productRefGroup = E8740962229B15300026A310 /* Products */; 174 | projectDirPath = ""; 175 | projectRoot = ""; 176 | targets = ( 177 | E8740960229B15300026A310 /* SwiftMachOverride */, 178 | ); 179 | }; 180 | /* End PBXProject section */ 181 | 182 | /* Begin PBXSourcesBuildPhase section */ 183 | E874095D229B15300026A310 /* Sources */ = { 184 | isa = PBXSourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | E8740986229B15820026A310 /* input.c in Sources */, 188 | E8740987229B15820026A310 /* syn-intel.c in Sources */, 189 | E8740988229B15820026A310 /* syn.c in Sources */, 190 | E8740981229B15820026A310 /* mach_override.c in Sources */, 191 | E8740984229B15820026A310 /* decode.c in Sources */, 192 | E8740985229B15820026A310 /* syn-att.c in Sources */, 193 | E8740965229B15300026A310 /* main.swift in Sources */, 194 | E8740983229B15820026A310 /* udis86.c in Sources */, 195 | E8740982229B15820026A310 /* itab.c in Sources */, 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | }; 199 | /* End PBXSourcesBuildPhase section */ 200 | 201 | /* Begin XCBuildConfiguration section */ 202 | E8740966229B15300026A310 /* Debug */ = { 203 | isa = XCBuildConfiguration; 204 | buildSettings = { 205 | ALWAYS_SEARCH_USER_PATHS = NO; 206 | CLANG_ANALYZER_NONNULL = YES; 207 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 208 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 209 | CLANG_CXX_LIBRARY = "libc++"; 210 | CLANG_ENABLE_MODULES = YES; 211 | CLANG_ENABLE_OBJC_ARC = YES; 212 | CLANG_ENABLE_OBJC_WEAK = YES; 213 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 214 | CLANG_WARN_BOOL_CONVERSION = YES; 215 | CLANG_WARN_COMMA = YES; 216 | CLANG_WARN_CONSTANT_CONVERSION = YES; 217 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 218 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 219 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 220 | CLANG_WARN_EMPTY_BODY = YES; 221 | CLANG_WARN_ENUM_CONVERSION = YES; 222 | CLANG_WARN_INFINITE_RECURSION = YES; 223 | CLANG_WARN_INT_CONVERSION = YES; 224 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 225 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 226 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 227 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 228 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 229 | CLANG_WARN_STRICT_PROTOTYPES = YES; 230 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 231 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 232 | CLANG_WARN_UNREACHABLE_CODE = YES; 233 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 234 | CODE_SIGN_IDENTITY = "-"; 235 | COPY_PHASE_STRIP = NO; 236 | DEBUG_INFORMATION_FORMAT = dwarf; 237 | ENABLE_STRICT_OBJC_MSGSEND = YES; 238 | ENABLE_TESTABILITY = YES; 239 | GCC_C_LANGUAGE_STANDARD = gnu11; 240 | GCC_DYNAMIC_NO_PIC = NO; 241 | GCC_NO_COMMON_BLOCKS = YES; 242 | GCC_OPTIMIZATION_LEVEL = 0; 243 | GCC_PREPROCESSOR_DEFINITIONS = ( 244 | "DEBUG=1", 245 | "$(inherited)", 246 | ); 247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 249 | GCC_WARN_UNDECLARED_SELECTOR = YES; 250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 251 | GCC_WARN_UNUSED_FUNCTION = YES; 252 | GCC_WARN_UNUSED_VARIABLE = YES; 253 | MACOSX_DEPLOYMENT_TARGET = 10.14; 254 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 255 | MTL_FAST_MATH = YES; 256 | ONLY_ACTIVE_ARCH = YES; 257 | SDKROOT = macosx; 258 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 259 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 260 | }; 261 | name = Debug; 262 | }; 263 | E8740967229B15300026A310 /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_ANALYZER_NONNULL = YES; 268 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 270 | CLANG_CXX_LIBRARY = "libc++"; 271 | CLANG_ENABLE_MODULES = YES; 272 | CLANG_ENABLE_OBJC_ARC = YES; 273 | CLANG_ENABLE_OBJC_WEAK = YES; 274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 275 | CLANG_WARN_BOOL_CONVERSION = YES; 276 | CLANG_WARN_COMMA = YES; 277 | CLANG_WARN_CONSTANT_CONVERSION = YES; 278 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 279 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 280 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 281 | CLANG_WARN_EMPTY_BODY = YES; 282 | CLANG_WARN_ENUM_CONVERSION = YES; 283 | CLANG_WARN_INFINITE_RECURSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 286 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 287 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 288 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 289 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 290 | CLANG_WARN_STRICT_PROTOTYPES = YES; 291 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 292 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 293 | CLANG_WARN_UNREACHABLE_CODE = YES; 294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 295 | CODE_SIGN_IDENTITY = "-"; 296 | COPY_PHASE_STRIP = NO; 297 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 298 | ENABLE_NS_ASSERTIONS = NO; 299 | ENABLE_STRICT_OBJC_MSGSEND = YES; 300 | GCC_C_LANGUAGE_STANDARD = gnu11; 301 | GCC_NO_COMMON_BLOCKS = YES; 302 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 303 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 304 | GCC_WARN_UNDECLARED_SELECTOR = YES; 305 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 306 | GCC_WARN_UNUSED_FUNCTION = YES; 307 | GCC_WARN_UNUSED_VARIABLE = YES; 308 | MACOSX_DEPLOYMENT_TARGET = 10.14; 309 | MTL_ENABLE_DEBUG_INFO = NO; 310 | MTL_FAST_MATH = YES; 311 | SDKROOT = macosx; 312 | SWIFT_COMPILATION_MODE = wholemodule; 313 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 314 | }; 315 | name = Release; 316 | }; 317 | E8740969229B15300026A310 /* Debug */ = { 318 | isa = XCBuildConfiguration; 319 | buildSettings = { 320 | CLANG_ENABLE_MODULES = YES; 321 | CODE_SIGN_STYLE = Automatic; 322 | LD_RUNPATH_SEARCH_PATHS = ( 323 | "$(inherited)", 324 | "@executable_path/../Frameworks", 325 | "@loader_path/../Frameworks", 326 | ); 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | SWIFT_OBJC_BRIDGING_HEADER = "SwiftMachOverride/SwiftMachOverride-Bridging-Header.h"; 329 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 330 | SWIFT_VERSION = 5.0; 331 | }; 332 | name = Debug; 333 | }; 334 | E874096A229B15300026A310 /* Release */ = { 335 | isa = XCBuildConfiguration; 336 | buildSettings = { 337 | CLANG_ENABLE_MODULES = YES; 338 | CODE_SIGN_STYLE = Automatic; 339 | LD_RUNPATH_SEARCH_PATHS = ( 340 | "$(inherited)", 341 | "@executable_path/../Frameworks", 342 | "@loader_path/../Frameworks", 343 | ); 344 | PRODUCT_NAME = "$(TARGET_NAME)"; 345 | SWIFT_OBJC_BRIDGING_HEADER = "SwiftMachOverride/SwiftMachOverride-Bridging-Header.h"; 346 | SWIFT_VERSION = 5.0; 347 | }; 348 | name = Release; 349 | }; 350 | /* End XCBuildConfiguration section */ 351 | 352 | /* Begin XCConfigurationList section */ 353 | E874095C229B15300026A310 /* Build configuration list for PBXProject "SwiftMachOverride" */ = { 354 | isa = XCConfigurationList; 355 | buildConfigurations = ( 356 | E8740966229B15300026A310 /* Debug */, 357 | E8740967229B15300026A310 /* Release */, 358 | ); 359 | defaultConfigurationIsVisible = 0; 360 | defaultConfigurationName = Release; 361 | }; 362 | E8740968229B15300026A310 /* Build configuration list for PBXNativeTarget "SwiftMachOverride" */ = { 363 | isa = XCConfigurationList; 364 | buildConfigurations = ( 365 | E8740969229B15300026A310 /* Debug */, 366 | E874096A229B15300026A310 /* Release */, 367 | ); 368 | defaultConfigurationIsVisible = 0; 369 | defaultConfigurationName = Release; 370 | }; 371 | /* End XCConfigurationList section */ 372 | }; 373 | rootObject = E8740959229B15300026A310 /* Project object */; 374 | } 375 | -------------------------------------------------------------------------------- /SwiftMachOverride.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftMachOverride.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftMachOverride.xcodeproj/xcshareddata/xcschemes/SwiftMachOverride.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SwiftMachOverride.xcodeproj/xcuserdata/lombardo.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftMachOverride.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E8740960229B15300026A310 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftMachOverride/SwiftMachOverride-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "override.c" 6 | #import "mach_override.h" 7 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/decode.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/decode.c 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "udint.h" 27 | #include "types.h" 28 | #include "input.h" 29 | #include "decode.h" 30 | 31 | #ifndef __UD_STANDALONE__ 32 | # include 33 | #endif /* __UD_STANDALONE__ */ 34 | 35 | /* The max number of prefixes to an instruction */ 36 | #define MAX_PREFIXES 15 37 | 38 | /* rex prefix bits */ 39 | #define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) 40 | #define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) 41 | #define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) 42 | #define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) 43 | #define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \ 44 | ( P_REXR(n) << 2 ) | \ 45 | ( P_REXX(n) << 1 ) | \ 46 | ( P_REXB(n) << 0 ) ) 47 | 48 | /* scable-index-base bits */ 49 | #define SIB_S(b) ( ( b ) >> 6 ) 50 | #define SIB_I(b) ( ( ( b ) >> 3 ) & 7 ) 51 | #define SIB_B(b) ( ( b ) & 7 ) 52 | 53 | /* modrm bits */ 54 | #define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 ) 55 | #define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 ) 56 | #define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 ) 57 | #define MODRM_RM(b) ( ( b ) & 7 ) 58 | 59 | static int decode_ext(struct ud *u, uint16_t ptr); 60 | 61 | enum reg_class { /* register classes */ 62 | REGCLASS_NONE, 63 | REGCLASS_GPR, 64 | REGCLASS_MMX, 65 | REGCLASS_CR, 66 | REGCLASS_DB, 67 | REGCLASS_SEG, 68 | REGCLASS_XMM 69 | }; 70 | 71 | 72 | /* 73 | * inp_uint8 74 | * int_uint16 75 | * int_uint32 76 | * int_uint64 77 | * Load little-endian values from input 78 | */ 79 | static uint8_t 80 | inp_uint8(struct ud* u) 81 | { 82 | return ud_inp_next(u); 83 | } 84 | 85 | static uint16_t 86 | inp_uint16(struct ud* u) 87 | { 88 | uint16_t r, ret; 89 | 90 | ret = ud_inp_next(u); 91 | r = ud_inp_next(u); 92 | return ret | (r << 8); 93 | } 94 | 95 | static uint32_t 96 | inp_uint32(struct ud* u) 97 | { 98 | uint32_t r, ret; 99 | 100 | ret = ud_inp_next(u); 101 | r = ud_inp_next(u); 102 | ret = ret | (r << 8); 103 | r = ud_inp_next(u); 104 | ret = ret | (r << 16); 105 | r = ud_inp_next(u); 106 | return ret | (r << 24); 107 | } 108 | 109 | static uint64_t 110 | inp_uint64(struct ud* u) 111 | { 112 | uint64_t r, ret; 113 | 114 | ret = ud_inp_next(u); 115 | r = ud_inp_next(u); 116 | ret = ret | (r << 8); 117 | r = ud_inp_next(u); 118 | ret = ret | (r << 16); 119 | r = ud_inp_next(u); 120 | ret = ret | (r << 24); 121 | r = ud_inp_next(u); 122 | ret = ret | (r << 32); 123 | r = ud_inp_next(u); 124 | ret = ret | (r << 40); 125 | r = ud_inp_next(u); 126 | ret = ret | (r << 48); 127 | r = ud_inp_next(u); 128 | return ret | (r << 56); 129 | } 130 | 131 | 132 | static inline int 133 | eff_opr_mode(int dis_mode, int rex_w, int pfx_opr) 134 | { 135 | if (dis_mode == 64) { 136 | return rex_w ? 64 : (pfx_opr ? 16 : 32); 137 | } else if (dis_mode == 32) { 138 | return pfx_opr ? 16 : 32; 139 | } else { 140 | UD_ASSERT(dis_mode == 16); 141 | return pfx_opr ? 32 : 16; 142 | } 143 | } 144 | 145 | 146 | static inline int 147 | eff_adr_mode(int dis_mode, int pfx_adr) 148 | { 149 | if (dis_mode == 64) { 150 | return pfx_adr ? 32 : 64; 151 | } else if (dis_mode == 32) { 152 | return pfx_adr ? 16 : 32; 153 | } else { 154 | UD_ASSERT(dis_mode == 16); 155 | return pfx_adr ? 32 : 16; 156 | } 157 | } 158 | 159 | 160 | /* Looks up mnemonic code in the mnemonic string table 161 | * Returns NULL if the mnemonic code is invalid 162 | */ 163 | const char* 164 | ud_lookup_mnemonic(enum ud_mnemonic_code c) 165 | { 166 | if (c < UD_MAX_MNEMONIC_CODE) { 167 | return ud_mnemonics_str[c]; 168 | } else { 169 | return NULL; 170 | } 171 | } 172 | 173 | 174 | /* 175 | * decode_prefixes 176 | * 177 | * Extracts instruction prefixes. 178 | */ 179 | static int 180 | decode_prefixes(struct ud *u) 181 | { 182 | int done = 0; 183 | uint8_t curr; 184 | UD_RETURN_ON_ERROR(u); 185 | 186 | do { 187 | ud_inp_next(u); 188 | UD_RETURN_ON_ERROR(u); 189 | if (inp_len(u) == MAX_INSN_LENGTH) { 190 | UD_RETURN_WITH_ERROR(u, "max instruction length"); 191 | } 192 | curr = inp_curr(u); 193 | 194 | switch (curr) 195 | { 196 | case 0x2E : 197 | u->pfx_seg = UD_R_CS; 198 | break; 199 | case 0x36 : 200 | u->pfx_seg = UD_R_SS; 201 | break; 202 | case 0x3E : 203 | u->pfx_seg = UD_R_DS; 204 | break; 205 | case 0x26 : 206 | u->pfx_seg = UD_R_ES; 207 | break; 208 | case 0x64 : 209 | u->pfx_seg = UD_R_FS; 210 | break; 211 | case 0x65 : 212 | u->pfx_seg = UD_R_GS; 213 | break; 214 | case 0x67 : /* adress-size override prefix */ 215 | u->pfx_adr = 0x67; 216 | break; 217 | case 0xF0 : 218 | u->pfx_lock = 0xF0; 219 | break; 220 | case 0x66: 221 | u->pfx_opr = 0x66; 222 | break; 223 | case 0xF2: 224 | u->pfx_str = 0xf2; 225 | break; 226 | case 0xF3: 227 | u->pfx_str = 0xf3; 228 | break; 229 | default: 230 | done = 1; 231 | break; 232 | } 233 | } while (!done); 234 | 235 | if (u->dis_mode == 64 && (curr & 0xF0) == 0x40) { 236 | /* rex prefixes in 64bit mode, must be the last prefix 237 | */ 238 | u->pfx_rex = curr; 239 | } else { 240 | /* rewind back one byte in stream, since the above loop 241 | * stops with a non-prefix byte. 242 | */ 243 | inp_back(u); 244 | } 245 | return 0; 246 | } 247 | 248 | 249 | static inline unsigned int modrm( struct ud * u ) 250 | { 251 | if ( !u->have_modrm ) { 252 | u->modrm = ud_inp_next( u ); 253 | u->have_modrm = 1; 254 | } 255 | return u->modrm; 256 | } 257 | 258 | 259 | static unsigned int 260 | resolve_operand_size( const struct ud * u, unsigned int s ) 261 | { 262 | switch ( s ) 263 | { 264 | case SZ_V: 265 | return ( u->opr_mode ); 266 | case SZ_Z: 267 | return ( u->opr_mode == 16 ) ? 16 : 32; 268 | case SZ_Y: 269 | return ( u->opr_mode == 16 ) ? 32 : u->opr_mode; 270 | case SZ_RDQ: 271 | return ( u->dis_mode == 64 ) ? 64 : 32; 272 | default: 273 | return s; 274 | } 275 | } 276 | 277 | 278 | static int resolve_mnemonic( struct ud* u ) 279 | { 280 | /* resolve 3dnow weirdness. */ 281 | if ( u->mnemonic == UD_I3dnow ) { 282 | u->mnemonic = ud_itab[ u->le->table[ inp_curr( u ) ] ].mnemonic; 283 | } 284 | /* SWAPGS is only valid in 64bits mode */ 285 | if ( u->mnemonic == UD_Iswapgs && u->dis_mode != 64 ) { 286 | UDERR(u, "swapgs invalid in 64bits mode"); 287 | return -1; 288 | } 289 | 290 | if (u->mnemonic == UD_Ixchg) { 291 | if ((u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_AX && 292 | u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_AX) || 293 | (u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_EAX && 294 | u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_EAX)) { 295 | u->operand[0].type = UD_NONE; 296 | u->operand[1].type = UD_NONE; 297 | u->mnemonic = UD_Inop; 298 | } 299 | } 300 | 301 | if (u->mnemonic == UD_Inop && u->pfx_repe) { 302 | u->pfx_repe = 0; 303 | u->mnemonic = UD_Ipause; 304 | } 305 | return 0; 306 | } 307 | 308 | 309 | /* ----------------------------------------------------------------------------- 310 | * decode_a()- Decodes operands of the type seg:offset 311 | * ----------------------------------------------------------------------------- 312 | */ 313 | static void 314 | decode_a(struct ud* u, struct ud_operand *op) 315 | { 316 | if (u->opr_mode == 16) { 317 | /* seg16:off16 */ 318 | op->type = UD_OP_PTR; 319 | op->size = 32; 320 | op->lval.ptr.off = inp_uint16(u); 321 | op->lval.ptr.seg = inp_uint16(u); 322 | } else { 323 | /* seg16:off32 */ 324 | op->type = UD_OP_PTR; 325 | op->size = 48; 326 | op->lval.ptr.off = inp_uint32(u); 327 | op->lval.ptr.seg = inp_uint16(u); 328 | } 329 | } 330 | 331 | /* ----------------------------------------------------------------------------- 332 | * decode_gpr() - Returns decoded General Purpose Register 333 | * ----------------------------------------------------------------------------- 334 | */ 335 | static enum ud_type 336 | decode_gpr(register struct ud* u, unsigned int s, unsigned char rm) 337 | { 338 | switch (s) { 339 | case 64: 340 | return UD_R_RAX + rm; 341 | case 32: 342 | return UD_R_EAX + rm; 343 | case 16: 344 | return UD_R_AX + rm; 345 | case 8: 346 | if (u->dis_mode == 64 && u->pfx_rex) { 347 | if (rm >= 4) 348 | return UD_R_SPL + (rm-4); 349 | return UD_R_AL + rm; 350 | } else return UD_R_AL + rm; 351 | default: 352 | UD_ASSERT(!"invalid operand size"); 353 | return 0; 354 | } 355 | } 356 | 357 | static void 358 | decode_reg(struct ud *u, 359 | struct ud_operand *opr, 360 | int type, 361 | int num, 362 | int size) 363 | { 364 | int reg; 365 | size = resolve_operand_size(u, size); 366 | switch (type) { 367 | case REGCLASS_GPR : reg = decode_gpr(u, size, num); break; 368 | case REGCLASS_MMX : reg = UD_R_MM0 + (num & 7); break; 369 | case REGCLASS_XMM : reg = UD_R_XMM0 + num; break; 370 | case REGCLASS_CR : reg = UD_R_CR0 + num; break; 371 | case REGCLASS_DB : reg = UD_R_DR0 + num; break; 372 | case REGCLASS_SEG : { 373 | /* 374 | * Only 6 segment registers, anything else is an error. 375 | */ 376 | if ((num & 7) > 5) { 377 | UDERR(u, "invalid segment register value"); 378 | return; 379 | } else { 380 | reg = UD_R_ES + (num & 7); 381 | } 382 | break; 383 | } 384 | default: 385 | UD_ASSERT(!"invalid register type"); 386 | break; 387 | } 388 | opr->type = UD_OP_REG; 389 | opr->base = reg; 390 | opr->size = size; 391 | } 392 | 393 | 394 | /* 395 | * decode_imm 396 | * 397 | * Decode Immediate values. 398 | */ 399 | static void 400 | decode_imm(struct ud* u, unsigned int size, struct ud_operand *op) 401 | { 402 | op->size = resolve_operand_size(u, size); 403 | op->type = UD_OP_IMM; 404 | 405 | switch (op->size) { 406 | case 8: op->lval.sbyte = inp_uint8(u); break; 407 | case 16: op->lval.uword = inp_uint16(u); break; 408 | case 32: op->lval.udword = inp_uint32(u); break; 409 | case 64: op->lval.uqword = inp_uint64(u); break; 410 | default: return; 411 | } 412 | } 413 | 414 | 415 | /* 416 | * decode_mem_disp 417 | * 418 | * Decode mem address displacement. 419 | */ 420 | static void 421 | decode_mem_disp(struct ud* u, unsigned int size, struct ud_operand *op) 422 | { 423 | switch (size) { 424 | case 8: 425 | op->offset = 8; 426 | op->lval.ubyte = inp_uint8(u); 427 | break; 428 | case 16: 429 | op->offset = 16; 430 | op->lval.uword = inp_uint16(u); 431 | break; 432 | case 32: 433 | op->offset = 32; 434 | op->lval.udword = inp_uint32(u); 435 | break; 436 | case 64: 437 | op->offset = 64; 438 | op->lval.uqword = inp_uint64(u); 439 | break; 440 | default: 441 | return; 442 | } 443 | } 444 | 445 | 446 | /* 447 | * decode_modrm_reg 448 | * 449 | * Decodes reg field of mod/rm byte 450 | * 451 | */ 452 | static inline void 453 | decode_modrm_reg(struct ud *u, 454 | struct ud_operand *operand, 455 | unsigned int type, 456 | unsigned int size) 457 | { 458 | uint8_t reg = (REX_R(u->pfx_rex) << 3) | MODRM_REG(modrm(u)); 459 | decode_reg(u, operand, type, reg, size); 460 | } 461 | 462 | 463 | /* 464 | * decode_modrm_rm 465 | * 466 | * Decodes rm field of mod/rm byte 467 | * 468 | */ 469 | static void 470 | decode_modrm_rm(struct ud *u, 471 | struct ud_operand *op, 472 | unsigned char type, /* register type */ 473 | unsigned int size) /* operand size */ 474 | 475 | { 476 | size_t offset = 0; 477 | unsigned char mod, rm; 478 | 479 | /* get mod, r/m and reg fields */ 480 | mod = MODRM_MOD(modrm(u)); 481 | rm = (REX_B(u->pfx_rex) << 3) | MODRM_RM(modrm(u)); 482 | 483 | /* 484 | * If mod is 11b, then the modrm.rm specifies a register. 485 | * 486 | */ 487 | if (mod == 3) { 488 | decode_reg(u, op, type, rm, size); 489 | return; 490 | } 491 | 492 | /* 493 | * !11b => Memory Address 494 | */ 495 | op->type = UD_OP_MEM; 496 | op->size = resolve_operand_size(u, size); 497 | 498 | if (u->adr_mode == 64) { 499 | op->base = UD_R_RAX + rm; 500 | if (mod == 1) { 501 | offset = 8; 502 | } else if (mod == 2) { 503 | offset = 32; 504 | } else if (mod == 0 && (rm & 7) == 5) { 505 | op->base = UD_R_RIP; 506 | offset = 32; 507 | } else { 508 | offset = 0; 509 | } 510 | /* 511 | * Scale-Index-Base (SIB) 512 | */ 513 | if ((rm & 7) == 4) { 514 | ud_inp_next(u); 515 | 516 | op->scale = (1 << SIB_S(inp_curr(u))) & ~1; 517 | op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); 518 | op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); 519 | 520 | /* special conditions for base reference */ 521 | if (op->index == UD_R_RSP) { 522 | op->index = UD_NONE; 523 | op->scale = UD_NONE; 524 | } 525 | 526 | if (op->base == UD_R_RBP || op->base == UD_R_R13) { 527 | if (mod == 0) { 528 | op->base = UD_NONE; 529 | } 530 | if (mod == 1) { 531 | offset = 8; 532 | } else { 533 | offset = 32; 534 | } 535 | } 536 | } 537 | } else if (u->adr_mode == 32) { 538 | op->base = UD_R_EAX + rm; 539 | if (mod == 1) { 540 | offset = 8; 541 | } else if (mod == 2) { 542 | offset = 32; 543 | } else if (mod == 0 && rm == 5) { 544 | op->base = UD_NONE; 545 | offset = 32; 546 | } else { 547 | offset = 0; 548 | } 549 | 550 | /* Scale-Index-Base (SIB) */ 551 | if ((rm & 7) == 4) { 552 | ud_inp_next(u); 553 | 554 | op->scale = (1 << SIB_S(inp_curr(u))) & ~1; 555 | op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); 556 | op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); 557 | 558 | if (op->index == UD_R_ESP) { 559 | op->index = UD_NONE; 560 | op->scale = UD_NONE; 561 | } 562 | 563 | /* special condition for base reference */ 564 | if (op->base == UD_R_EBP) { 565 | if (mod == 0) { 566 | op->base = UD_NONE; 567 | } 568 | if (mod == 1) { 569 | offset = 8; 570 | } else { 571 | offset = 32; 572 | } 573 | } 574 | } 575 | } else { 576 | const unsigned int bases[] = { UD_R_BX, UD_R_BX, UD_R_BP, UD_R_BP, 577 | UD_R_SI, UD_R_DI, UD_R_BP, UD_R_BX }; 578 | const unsigned int indices[] = { UD_R_SI, UD_R_DI, UD_R_SI, UD_R_DI, 579 | UD_NONE, UD_NONE, UD_NONE, UD_NONE }; 580 | op->base = bases[rm & 7]; 581 | op->index = indices[rm & 7]; 582 | if (mod == 0 && rm == 6) { 583 | offset = 16; 584 | op->base = UD_NONE; 585 | } else if (mod == 1) { 586 | offset = 8; 587 | } else if (mod == 2) { 588 | offset = 16; 589 | } 590 | } 591 | 592 | if (offset) { 593 | decode_mem_disp(u, offset, op); 594 | } 595 | } 596 | 597 | 598 | /* 599 | * decode_moffset 600 | * Decode offset-only memory operand 601 | */ 602 | static void 603 | decode_moffset(struct ud *u, unsigned int size, struct ud_operand *opr) 604 | { 605 | opr->type = UD_OP_MEM; 606 | opr->size = resolve_operand_size(u, size); 607 | decode_mem_disp(u, u->adr_mode, opr); 608 | } 609 | 610 | 611 | /* ----------------------------------------------------------------------------- 612 | * decode_operands() - Disassembles Operands. 613 | * ----------------------------------------------------------------------------- 614 | */ 615 | static int 616 | decode_operand(struct ud *u, 617 | struct ud_operand *operand, 618 | enum ud_operand_code type, 619 | unsigned int size) 620 | { 621 | operand->_oprcode = type; 622 | 623 | switch (type) { 624 | case OP_A : 625 | decode_a(u, operand); 626 | break; 627 | case OP_MR: 628 | decode_modrm_rm(u, operand, REGCLASS_GPR, 629 | MODRM_MOD(modrm(u)) == 3 ? 630 | Mx_reg_size(size) : Mx_mem_size(size)); 631 | break; 632 | case OP_F: 633 | u->br_far = 1; 634 | /* intended fall through */ 635 | case OP_M: 636 | if (MODRM_MOD(modrm(u)) == 3) { 637 | UDERR(u, "expected modrm.mod != 3"); 638 | } 639 | /* intended fall through */ 640 | case OP_E: 641 | decode_modrm_rm(u, operand, REGCLASS_GPR, size); 642 | break; 643 | case OP_G: 644 | decode_modrm_reg(u, operand, REGCLASS_GPR, size); 645 | break; 646 | case OP_sI: 647 | case OP_I: 648 | decode_imm(u, size, operand); 649 | break; 650 | case OP_I1: 651 | operand->type = UD_OP_CONST; 652 | operand->lval.udword = 1; 653 | break; 654 | case OP_N: 655 | if (MODRM_MOD(modrm(u)) != 3) { 656 | UDERR(u, "expected modrm.mod == 3"); 657 | } 658 | /* intended fall through */ 659 | case OP_Q: 660 | decode_modrm_rm(u, operand, REGCLASS_MMX, size); 661 | break; 662 | case OP_P: 663 | decode_modrm_reg(u, operand, REGCLASS_MMX, size); 664 | break; 665 | case OP_U: 666 | if (MODRM_MOD(modrm(u)) != 3) { 667 | UDERR(u, "expected modrm.mod == 3"); 668 | } 669 | /* intended fall through */ 670 | case OP_W: 671 | decode_modrm_rm(u, operand, REGCLASS_XMM, size); 672 | break; 673 | case OP_V: 674 | decode_modrm_reg(u, operand, REGCLASS_XMM, size); 675 | break; 676 | case OP_MU: 677 | decode_modrm_rm(u, operand, REGCLASS_XMM, 678 | MODRM_MOD(modrm(u)) == 3 ? 679 | Mx_reg_size(size) : Mx_mem_size(size)); 680 | break; 681 | case OP_S: 682 | decode_modrm_reg(u, operand, REGCLASS_SEG, size); 683 | break; 684 | case OP_O: 685 | decode_moffset(u, size, operand); 686 | break; 687 | case OP_R0: 688 | case OP_R1: 689 | case OP_R2: 690 | case OP_R3: 691 | case OP_R4: 692 | case OP_R5: 693 | case OP_R6: 694 | case OP_R7: 695 | decode_reg(u, operand, REGCLASS_GPR, 696 | (REX_B(u->pfx_rex) << 3) | (type - OP_R0), size); 697 | break; 698 | case OP_AL: 699 | case OP_AX: 700 | case OP_eAX: 701 | case OP_rAX: 702 | decode_reg(u, operand, REGCLASS_GPR, 0, size); 703 | break; 704 | case OP_CL: 705 | case OP_CX: 706 | case OP_eCX: 707 | decode_reg(u, operand, REGCLASS_GPR, 1, size); 708 | break; 709 | case OP_DL: 710 | case OP_DX: 711 | case OP_eDX: 712 | decode_reg(u, operand, REGCLASS_GPR, 2, size); 713 | break; 714 | case OP_ES: 715 | case OP_CS: 716 | case OP_DS: 717 | case OP_SS: 718 | case OP_FS: 719 | case OP_GS: 720 | /* in 64bits mode, only fs and gs are allowed */ 721 | if (u->dis_mode == 64) { 722 | if (type != OP_FS && type != OP_GS) { 723 | UDERR(u, "invalid segment register in 64bits"); 724 | } 725 | } 726 | operand->type = UD_OP_REG; 727 | operand->base = (type - OP_ES) + UD_R_ES; 728 | operand->size = 16; 729 | break; 730 | case OP_J : 731 | decode_imm(u, size, operand); 732 | operand->type = UD_OP_JIMM; 733 | break ; 734 | case OP_R : 735 | if (MODRM_MOD(modrm(u)) != 3) { 736 | UDERR(u, "expected modrm.mod == 3"); 737 | } 738 | decode_modrm_rm(u, operand, REGCLASS_GPR, size); 739 | break; 740 | case OP_C: 741 | decode_modrm_reg(u, operand, REGCLASS_CR, size); 742 | break; 743 | case OP_D: 744 | decode_modrm_reg(u, operand, REGCLASS_DB, size); 745 | break; 746 | case OP_I3 : 747 | operand->type = UD_OP_CONST; 748 | operand->lval.sbyte = 3; 749 | break; 750 | case OP_ST0: 751 | case OP_ST1: 752 | case OP_ST2: 753 | case OP_ST3: 754 | case OP_ST4: 755 | case OP_ST5: 756 | case OP_ST6: 757 | case OP_ST7: 758 | operand->type = UD_OP_REG; 759 | operand->base = (type - OP_ST0) + UD_R_ST0; 760 | operand->size = 80; 761 | break; 762 | default : 763 | break; 764 | } 765 | return 0; 766 | } 767 | 768 | 769 | /* 770 | * decode_operands 771 | * 772 | * Disassemble upto 3 operands of the current instruction being 773 | * disassembled. By the end of the function, the operand fields 774 | * of the ud structure will have been filled. 775 | */ 776 | static int 777 | decode_operands(struct ud* u) 778 | { 779 | decode_operand(u, &u->operand[0], 780 | u->itab_entry->operand1.type, 781 | u->itab_entry->operand1.size); 782 | decode_operand(u, &u->operand[1], 783 | u->itab_entry->operand2.type, 784 | u->itab_entry->operand2.size); 785 | decode_operand(u, &u->operand[2], 786 | u->itab_entry->operand3.type, 787 | u->itab_entry->operand3.size); 788 | return 0; 789 | } 790 | 791 | /* ----------------------------------------------------------------------------- 792 | * clear_insn() - clear instruction structure 793 | * ----------------------------------------------------------------------------- 794 | */ 795 | static void 796 | clear_insn(register struct ud* u) 797 | { 798 | u->error = 0; 799 | u->pfx_seg = 0; 800 | u->pfx_opr = 0; 801 | u->pfx_adr = 0; 802 | u->pfx_lock = 0; 803 | u->pfx_repne = 0; 804 | u->pfx_rep = 0; 805 | u->pfx_repe = 0; 806 | u->pfx_rex = 0; 807 | u->pfx_str = 0; 808 | u->mnemonic = UD_Inone; 809 | u->itab_entry = NULL; 810 | u->have_modrm = 0; 811 | u->br_far = 0; 812 | 813 | memset( &u->operand[ 0 ], 0, sizeof( struct ud_operand ) ); 814 | memset( &u->operand[ 1 ], 0, sizeof( struct ud_operand ) ); 815 | memset( &u->operand[ 2 ], 0, sizeof( struct ud_operand ) ); 816 | } 817 | 818 | 819 | static inline int 820 | resolve_pfx_str(struct ud* u) 821 | { 822 | if (u->pfx_str == 0xf3) { 823 | if (P_STR(u->itab_entry->prefix)) { 824 | u->pfx_rep = 0xf3; 825 | } else { 826 | u->pfx_repe = 0xf3; 827 | } 828 | } else if (u->pfx_str == 0xf2) { 829 | u->pfx_repne = 0xf3; 830 | } 831 | return 0; 832 | } 833 | 834 | 835 | static int 836 | resolve_mode( struct ud* u ) 837 | { 838 | /* if in error state, bail out */ 839 | if ( u->error ) return -1; 840 | 841 | /* propagate prefix effects */ 842 | if ( u->dis_mode == 64 ) { /* set 64bit-mode flags */ 843 | 844 | /* Check validity of instruction m64 */ 845 | if ( P_INV64( u->itab_entry->prefix ) ) { 846 | UDERR(u, "instruction invalid in 64bits"); 847 | return -1; 848 | } 849 | 850 | /* effective rex prefix is the effective mask for the 851 | * instruction hard-coded in the opcode map. 852 | */ 853 | u->pfx_rex = ( u->pfx_rex & 0x40 ) | 854 | ( u->pfx_rex & REX_PFX_MASK( u->itab_entry->prefix ) ); 855 | 856 | /* whether this instruction has a default operand size of 857 | * 64bit, also hardcoded into the opcode map. 858 | */ 859 | u->default64 = P_DEF64( u->itab_entry->prefix ); 860 | /* calculate effective operand size */ 861 | if ( REX_W( u->pfx_rex ) ) { 862 | u->opr_mode = 64; 863 | } else if ( u->pfx_opr ) { 864 | u->opr_mode = 16; 865 | } else { 866 | /* unless the default opr size of instruction is 64, 867 | * the effective operand size in the absence of rex.w 868 | * prefix is 32. 869 | */ 870 | u->opr_mode = ( u->default64 ) ? 64 : 32; 871 | } 872 | 873 | /* calculate effective address size */ 874 | u->adr_mode = (u->pfx_adr) ? 32 : 64; 875 | } else if ( u->dis_mode == 32 ) { /* set 32bit-mode flags */ 876 | u->opr_mode = ( u->pfx_opr ) ? 16 : 32; 877 | u->adr_mode = ( u->pfx_adr ) ? 16 : 32; 878 | } else if ( u->dis_mode == 16 ) { /* set 16bit-mode flags */ 879 | u->opr_mode = ( u->pfx_opr ) ? 32 : 16; 880 | u->adr_mode = ( u->pfx_adr ) ? 32 : 16; 881 | } 882 | 883 | /* set flags for implicit addressing */ 884 | u->implicit_addr = P_IMPADDR( u->itab_entry->prefix ); 885 | 886 | return 0; 887 | } 888 | 889 | 890 | static inline int 891 | decode_insn(struct ud *u, uint16_t ptr) 892 | { 893 | UD_ASSERT((ptr & 0x8000) == 0); 894 | u->itab_entry = &ud_itab[ ptr ]; 895 | u->mnemonic = u->itab_entry->mnemonic; 896 | return (resolve_pfx_str(u) == 0 && 897 | resolve_mode(u) == 0 && 898 | decode_operands(u) == 0 && 899 | resolve_mnemonic(u) == 0) ? 0 : -1; 900 | } 901 | 902 | 903 | /* 904 | * decode_3dnow() 905 | * 906 | * Decoding 3dnow is a little tricky because of its strange opcode 907 | * structure. The final opcode disambiguation depends on the last 908 | * byte that comes after the operands have been decoded. Fortunately, 909 | * all 3dnow instructions have the same set of operand types. So we 910 | * go ahead and decode the instruction by picking an arbitrarily chosen 911 | * valid entry in the table, decode the operands, and read the final 912 | * byte to resolve the menmonic. 913 | */ 914 | static inline int 915 | decode_3dnow(struct ud* u) 916 | { 917 | uint16_t ptr; 918 | UD_ASSERT(u->le->type == UD_TAB__OPC_3DNOW); 919 | UD_ASSERT(u->le->table[0xc] != 0); 920 | decode_insn(u, u->le->table[0xc]); 921 | ud_inp_next(u); 922 | if (u->error) { 923 | return -1; 924 | } 925 | ptr = u->le->table[inp_curr(u)]; 926 | UD_ASSERT((ptr & 0x8000) == 0); 927 | u->mnemonic = ud_itab[ptr].mnemonic; 928 | return 0; 929 | } 930 | 931 | 932 | static int 933 | decode_ssepfx(struct ud *u) 934 | { 935 | uint8_t idx; 936 | uint8_t pfx; 937 | 938 | /* 939 | * String prefixes (f2, f3) take precedence over operand 940 | * size prefix (66). 941 | */ 942 | pfx = u->pfx_str; 943 | if (pfx == 0) { 944 | pfx = u->pfx_opr; 945 | } 946 | idx = ((pfx & 0xf) + 1) / 2; 947 | if (u->le->table[idx] == 0) { 948 | idx = 0; 949 | } 950 | if (idx && u->le->table[idx] != 0) { 951 | /* 952 | * "Consume" the prefix as a part of the opcode, so it is no 953 | * longer exported as an instruction prefix. 954 | */ 955 | u->pfx_str = 0; 956 | if (pfx == 0x66) { 957 | /* 958 | * consume "66" only if it was used for decoding, leaving 959 | * it to be used as an operands size override for some 960 | * simd instructions. 961 | */ 962 | u->pfx_opr = 0; 963 | } 964 | } 965 | return decode_ext(u, u->le->table[idx]); 966 | } 967 | 968 | 969 | /* 970 | * decode_ext() 971 | * 972 | * Decode opcode extensions (if any) 973 | */ 974 | static int 975 | decode_ext(struct ud *u, uint16_t ptr) 976 | { 977 | uint8_t idx = 0; 978 | if ((ptr & 0x8000) == 0) { 979 | return decode_insn(u, ptr); 980 | } 981 | u->le = &ud_lookup_table_list[(~0x8000 & ptr)]; 982 | if (u->le->type == UD_TAB__OPC_3DNOW) { 983 | return decode_3dnow(u); 984 | } 985 | 986 | switch (u->le->type) { 987 | case UD_TAB__OPC_MOD: 988 | /* !11 = 0, 11 = 1 */ 989 | idx = (MODRM_MOD(modrm(u)) + 1) / 4; 990 | break; 991 | /* disassembly mode/operand size/address size based tables. 992 | * 16 = 0,, 32 = 1, 64 = 2 993 | */ 994 | case UD_TAB__OPC_MODE: 995 | idx = u->dis_mode != 64 ? 0 : 1; 996 | break; 997 | case UD_TAB__OPC_OSIZE: 998 | idx = eff_opr_mode(u->dis_mode, REX_W(u->pfx_rex), u->pfx_opr) / 32; 999 | break; 1000 | case UD_TAB__OPC_ASIZE: 1001 | idx = eff_adr_mode(u->dis_mode, u->pfx_adr) / 32; 1002 | break; 1003 | case UD_TAB__OPC_X87: 1004 | idx = modrm(u) - 0xC0; 1005 | break; 1006 | case UD_TAB__OPC_VENDOR: 1007 | if (u->vendor == UD_VENDOR_ANY) { 1008 | /* choose a valid entry */ 1009 | idx = (u->le->table[idx] != 0) ? 0 : 1; 1010 | } else if (u->vendor == UD_VENDOR_AMD) { 1011 | idx = 0; 1012 | } else { 1013 | idx = 1; 1014 | } 1015 | break; 1016 | case UD_TAB__OPC_RM: 1017 | idx = MODRM_RM(modrm(u)); 1018 | break; 1019 | case UD_TAB__OPC_REG: 1020 | idx = MODRM_REG(modrm(u)); 1021 | break; 1022 | case UD_TAB__OPC_SSE: 1023 | return decode_ssepfx(u); 1024 | default: 1025 | UD_ASSERT(!"not reached"); 1026 | break; 1027 | } 1028 | 1029 | return decode_ext(u, u->le->table[idx]); 1030 | } 1031 | 1032 | 1033 | static int 1034 | decode_opcode(struct ud *u) 1035 | { 1036 | uint16_t ptr; 1037 | UD_ASSERT(u->le->type == UD_TAB__OPC_TABLE); 1038 | ud_inp_next(u); 1039 | if (u->error) { 1040 | return -1; 1041 | } 1042 | u->primary_opcode = inp_curr(u); 1043 | ptr = u->le->table[inp_curr(u)]; 1044 | if (ptr & 0x8000) { 1045 | u->le = &ud_lookup_table_list[ptr & ~0x8000]; 1046 | if (u->le->type == UD_TAB__OPC_TABLE) { 1047 | return decode_opcode(u); 1048 | } 1049 | } 1050 | return decode_ext(u, ptr); 1051 | } 1052 | 1053 | 1054 | /* ============================================================================= 1055 | * ud_decode() - Instruction decoder. Returns the number of bytes decoded. 1056 | * ============================================================================= 1057 | */ 1058 | unsigned int 1059 | ud_decode(struct ud *u) 1060 | { 1061 | inp_start(u); 1062 | clear_insn(u); 1063 | u->le = &ud_lookup_table_list[0]; 1064 | u->error = decode_prefixes(u) == -1 || 1065 | decode_opcode(u) == -1 || 1066 | u->error; 1067 | /* Handle decode error. */ 1068 | if (u->error) { 1069 | /* clear out the decode data. */ 1070 | clear_insn(u); 1071 | /* mark the sequence of bytes as invalid. */ 1072 | u->itab_entry = &ud_itab[0]; /* entry 0 is invalid */ 1073 | u->mnemonic = u->itab_entry->mnemonic; 1074 | } 1075 | 1076 | /* maybe this stray segment override byte 1077 | * should be spewed out? 1078 | */ 1079 | if ( !P_SEG( u->itab_entry->prefix ) && 1080 | u->operand[0].type != UD_OP_MEM && 1081 | u->operand[1].type != UD_OP_MEM ) 1082 | u->pfx_seg = 0; 1083 | 1084 | u->insn_offset = u->pc; /* set offset of instruction */ 1085 | u->asm_buf_fill = 0; /* set translation buffer index to 0 */ 1086 | u->pc += u->inp_ctr; /* move program counter by bytes decoded */ 1087 | 1088 | /* return number of bytes disassembled. */ 1089 | return u->inp_ctr; 1090 | } 1091 | 1092 | /* 1093 | vim: set ts=2 sw=2 expandtab 1094 | */ 1095 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/decode.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/decode.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_DECODE_H 27 | #define UD_DECODE_H 28 | 29 | #include "types.h" 30 | #include "itab.h" 31 | 32 | #define MAX_INSN_LENGTH 15 33 | 34 | /* itab prefix bits */ 35 | #define P_none ( 0 ) 36 | #define P_cast ( 1 << 0 ) 37 | #define P_CAST(n) ( ( n >> 0 ) & 1 ) 38 | #define P_rexb ( 1 << 1 ) 39 | #define P_REXB(n) ( ( n >> 1 ) & 1 ) 40 | #define P_inv64 ( 1 << 4 ) 41 | #define P_INV64(n) ( ( n >> 4 ) & 1 ) 42 | #define P_rexw ( 1 << 5 ) 43 | #define P_REXW(n) ( ( n >> 5 ) & 1 ) 44 | #define P_def64 ( 1 << 7 ) 45 | #define P_DEF64(n) ( ( n >> 7 ) & 1 ) 46 | #define P_rexr ( 1 << 8 ) 47 | #define P_REXR(n) ( ( n >> 8 ) & 1 ) 48 | #define P_oso ( 1 << 9 ) 49 | #define P_OSO(n) ( ( n >> 9 ) & 1 ) 50 | #define P_aso ( 1 << 10 ) 51 | #define P_ASO(n) ( ( n >> 10 ) & 1 ) 52 | #define P_rexx ( 1 << 11 ) 53 | #define P_REXX(n) ( ( n >> 11 ) & 1 ) 54 | #define P_ImpAddr ( 1 << 12 ) 55 | #define P_IMPADDR(n) ( ( n >> 12 ) & 1 ) 56 | #define P_seg ( 1 << 13 ) 57 | #define P_SEG(n) ( ( n >> 13 ) & 1 ) 58 | #define P_str ( 1 << 14 ) 59 | #define P_STR(n) ( ( n >> 14 ) & 1 ) 60 | #define P_strz ( 1 << 15 ) 61 | #define P_STR_ZF(n) ( ( n >> 15 ) & 1 ) 62 | 63 | /* operand type constants -- order is important! */ 64 | 65 | enum ud_operand_code { 66 | OP_NONE, 67 | 68 | OP_A, OP_E, OP_M, OP_G, 69 | OP_I, OP_F, 70 | 71 | OP_R0, OP_R1, OP_R2, OP_R3, 72 | OP_R4, OP_R5, OP_R6, OP_R7, 73 | 74 | OP_AL, OP_CL, OP_DL, 75 | OP_AX, OP_CX, OP_DX, 76 | OP_eAX, OP_eCX, OP_eDX, 77 | OP_rAX, OP_rCX, OP_rDX, 78 | 79 | OP_ES, OP_CS, OP_SS, OP_DS, 80 | OP_FS, OP_GS, 81 | 82 | OP_ST0, OP_ST1, OP_ST2, OP_ST3, 83 | OP_ST4, OP_ST5, OP_ST6, OP_ST7, 84 | 85 | OP_J, OP_S, OP_O, 86 | OP_I1, OP_I3, OP_sI, 87 | 88 | OP_V, OP_W, OP_Q, OP_P, 89 | OP_U, OP_N, OP_MU, 90 | 91 | OP_R, OP_C, OP_D, 92 | 93 | OP_MR 94 | } UD_ATTR_PACKED; 95 | 96 | 97 | /* operand size constants */ 98 | 99 | enum ud_operand_size { 100 | SZ_NA = 0, 101 | SZ_Z = 1, 102 | SZ_V = 2, 103 | SZ_RDQ = 7, 104 | 105 | /* the following values are used as is, 106 | * and thus hard-coded. changing them 107 | * will break internals 108 | */ 109 | SZ_B = 8, 110 | SZ_W = 16, 111 | SZ_D = 32, 112 | SZ_Q = 64, 113 | SZ_T = 80, 114 | SZ_O = 128, 115 | 116 | SZ_Y = 17, 117 | 118 | /* 119 | * complex size types, that encode sizes for operands 120 | * of type MR (memory or register), for internal use 121 | * only. Id space 256 and above. 122 | */ 123 | SZ_BD = (SZ_B << 8) | SZ_D, 124 | SZ_BV = (SZ_B << 8) | SZ_V, 125 | SZ_WD = (SZ_W << 8) | SZ_D, 126 | SZ_WV = (SZ_W << 8) | SZ_V, 127 | SZ_WY = (SZ_W << 8) | SZ_Y, 128 | SZ_DY = (SZ_D << 8) | SZ_Y, 129 | SZ_WO = (SZ_W << 8) | SZ_O, 130 | SZ_DO = (SZ_D << 8) | SZ_O, 131 | SZ_QO = (SZ_Q << 8) | SZ_O, 132 | 133 | } UD_ATTR_PACKED; 134 | 135 | 136 | /* resolve complex size type. 137 | */ 138 | static inline enum ud_operand_size 139 | Mx_mem_size(enum ud_operand_size size) 140 | { 141 | return (size >> 8) & 0xff; 142 | } 143 | 144 | static inline enum ud_operand_size 145 | Mx_reg_size(enum ud_operand_size size) 146 | { 147 | return size & 0xff; 148 | } 149 | 150 | /* A single operand of an entry in the instruction table. 151 | * (internal use only) 152 | */ 153 | struct ud_itab_entry_operand 154 | { 155 | enum ud_operand_code type; 156 | enum ud_operand_size size; 157 | }; 158 | 159 | 160 | /* A single entry in an instruction table. 161 | *(internal use only) 162 | */ 163 | struct ud_itab_entry 164 | { 165 | enum ud_mnemonic_code mnemonic; 166 | struct ud_itab_entry_operand operand1; 167 | struct ud_itab_entry_operand operand2; 168 | struct ud_itab_entry_operand operand3; 169 | uint32_t prefix; 170 | }; 171 | 172 | struct ud_lookup_table_list_entry { 173 | const uint16_t *table; 174 | enum ud_table_type type; 175 | const char *meta; 176 | }; 177 | 178 | 179 | 180 | static inline int 181 | ud_opcode_field_sext(uint8_t primary_opcode) 182 | { 183 | return (primary_opcode & 0x02) != 0; 184 | } 185 | 186 | extern struct ud_itab_entry ud_itab[]; 187 | extern struct ud_lookup_table_list_entry ud_lookup_table_list[]; 188 | 189 | #endif /* UD_DECODE_H */ 190 | 191 | /* vim:cindent 192 | * vim:expandtab 193 | * vim:ts=4 194 | * vim:sw=4 195 | */ 196 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/extern.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/extern.h 2 | * 3 | * Copyright (c) 2002-2009, 2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_EXTERN_H 27 | #define UD_EXTERN_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #include "types.h" 34 | 35 | /* ============================= PUBLIC API ================================= */ 36 | 37 | extern void ud_init(struct ud*); 38 | 39 | extern void ud_set_mode(struct ud*, uint8_t); 40 | 41 | extern void ud_set_pc(struct ud*, uint64_t); 42 | 43 | extern void ud_set_input_hook(struct ud*, int (*)(struct ud*)); 44 | 45 | extern void ud_set_input_buffer(struct ud*, const uint8_t*, size_t); 46 | 47 | #ifndef __UD_STANDALONE__ 48 | extern void ud_set_input_file(struct ud*, FILE*); 49 | #endif /* __UD_STANDALONE__ */ 50 | 51 | extern void ud_set_vendor(struct ud*, unsigned); 52 | 53 | extern void ud_set_syntax(struct ud*, void (*)(struct ud*)); 54 | 55 | extern void ud_input_skip(struct ud*, size_t); 56 | 57 | extern int ud_input_end(const struct ud*); 58 | 59 | extern unsigned int ud_decode(struct ud*); 60 | 61 | extern unsigned int ud_disassemble(struct ud*); 62 | 63 | extern void ud_translate_intel(struct ud*); 64 | 65 | extern void ud_translate_att(struct ud*); 66 | 67 | extern const char* ud_insn_asm(const struct ud* u); 68 | 69 | extern const uint8_t* ud_insn_ptr(const struct ud* u); 70 | 71 | extern uint64_t ud_insn_off(const struct ud*); 72 | 73 | extern const char* ud_insn_hex(struct ud*); 74 | 75 | extern unsigned int ud_insn_len(const struct ud* u); 76 | 77 | extern const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n); 78 | 79 | extern int ud_opr_is_sreg(const struct ud_operand *opr); 80 | 81 | extern int ud_opr_isgpr(const struct ud_operand *opr); 82 | 83 | extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); 84 | 85 | extern void ud_set_user_opaque_data(struct ud*, void*); 86 | 87 | extern void* ud_get_user_opaque_data(const struct ud*); 88 | 89 | extern uint64_t ud_insn_sext_imm(const struct ud*, const struct ud_operand*); 90 | 91 | extern void ud_set_asm_buffer(struct ud *u, char *buf, size_t size); 92 | 93 | extern void ud_set_sym_resolver(struct ud *u, 94 | const char* (*resolver)(struct ud*, 95 | uint64_t addr, 96 | int64_t *offset)); 97 | 98 | /* ========================================================================== */ 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | #endif /* UD_EXTERN_H */ 104 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/input.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/input.c 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "extern.h" 27 | #include "types.h" 28 | #include "input.h" 29 | #include "udint.h" 30 | 31 | /* 32 | * inp_init 33 | * Initializes the input system. 34 | */ 35 | static void 36 | inp_init(struct ud *u) 37 | { 38 | u->inp_curr = 0; 39 | u->inp_fill = 0; 40 | u->inp_ctr = 0; 41 | u->inp_end = 0; 42 | } 43 | 44 | 45 | /* ----------------------------------------------------------------------------- 46 | * inp_buff_hook() - Hook for buffered inputs. 47 | * ----------------------------------------------------------------------------- 48 | */ 49 | static int 50 | inp_buff_hook(struct ud* u) 51 | { 52 | if (u->inp_buff < u->inp_buff_end) 53 | return *u->inp_buff++; 54 | else return -1; 55 | } 56 | 57 | #ifndef __UD_STANDALONE__ 58 | /* ----------------------------------------------------------------------------- 59 | * inp_file_hook() - Hook for FILE inputs. 60 | * ----------------------------------------------------------------------------- 61 | */ 62 | static int 63 | inp_file_hook(struct ud* u) 64 | { 65 | return fgetc(u->inp_file); 66 | } 67 | #endif /* __UD_STANDALONE__*/ 68 | 69 | /* ============================================================================= 70 | * ud_inp_set_hook() - Sets input hook. 71 | * ============================================================================= 72 | */ 73 | void 74 | ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) 75 | { 76 | u->inp_hook = hook; 77 | inp_init(u); 78 | } 79 | 80 | /* ============================================================================= 81 | * ud_inp_set_buffer() - Set buffer as input. 82 | * ============================================================================= 83 | */ 84 | void 85 | ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len) 86 | { 87 | u->inp_hook = inp_buff_hook; 88 | u->inp_buff = buf; 89 | u->inp_buff_end = buf + len; 90 | inp_init(u); 91 | } 92 | 93 | #ifndef __UD_STANDALONE__ 94 | /* ============================================================================= 95 | * ud_input_set_file() - Set buffer as input. 96 | * ============================================================================= 97 | */ 98 | void 99 | ud_set_input_file(register struct ud* u, FILE* f) 100 | { 101 | u->inp_hook = inp_file_hook; 102 | u->inp_file = f; 103 | inp_init(u); 104 | } 105 | #endif /* __UD_STANDALONE__ */ 106 | 107 | /* ============================================================================= 108 | * ud_input_skip() - Skip n input bytes. 109 | * ============================================================================= 110 | */ 111 | void 112 | ud_input_skip(struct ud* u, size_t n) 113 | { 114 | while (n--) { 115 | u->inp_hook(u); 116 | } 117 | } 118 | 119 | /* ============================================================================= 120 | * ud_input_end() - Test for end of input. 121 | * ============================================================================= 122 | */ 123 | int 124 | ud_input_end(const struct ud* u) 125 | { 126 | return (u->inp_curr == u->inp_fill) && u->inp_end; 127 | } 128 | 129 | 130 | /* 131 | * ud_inp_next 132 | * Loads and returns the next byte from input. 133 | * 134 | * inp_curr and inp_fill are pointers to the cache. The program is 135 | * written based on the property that they are 8-bits in size, and 136 | * will eventually wrap around forming a circular buffer. So, the 137 | * size of the cache is 256 in size, kind of unnecessary yet 138 | * optimal. 139 | * 140 | * A buffer inp_sess stores the bytes disassembled for a single 141 | * session. 142 | */ 143 | uint8_t 144 | ud_inp_next(struct ud* u) 145 | { 146 | int c = -1; 147 | /* if current pointer is not upto the fill point in the 148 | * input cache. 149 | */ 150 | if (u->inp_curr != u->inp_fill) { 151 | c = u->inp_cache[ ++u->inp_curr ]; 152 | /* if !end-of-input, call the input hook and get a byte */ 153 | } else if (u->inp_end || (c = u->inp_hook(u)) == -1) { 154 | /* end-of-input, mark it as an error, since the decoder, 155 | * expected a byte more. 156 | */ 157 | UDERR(u, "byte expected, eoi received"); 158 | /* flag end of input */ 159 | u->inp_end = 1; 160 | return 0; 161 | } else { 162 | /* increment pointers, we have a new byte. */ 163 | u->inp_curr = ++u->inp_fill; 164 | /* add the byte to the cache */ 165 | u->inp_cache[u->inp_fill] = c; 166 | } 167 | /* record bytes input per decode-session. */ 168 | u->inp_sess[u->inp_ctr++] = c; 169 | /* return byte */ 170 | return (uint8_t) c; 171 | } 172 | 173 | /* 174 | vim: set ts=2 sw=2 expandtab 175 | */ 176 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/input.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/input.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_INPUT_H 27 | #define UD_INPUT_H 28 | 29 | #include "types.h" 30 | #include "udint.h" 31 | 32 | uint8_t ud_inp_next(struct ud* u); 33 | 34 | /* 35 | * inp_start 36 | * Should be called before each de-code operation. 37 | */ 38 | static inline void 39 | inp_start(struct ud *u) 40 | { 41 | u->inp_ctr = 0; 42 | } 43 | 44 | /* inp_reset 45 | * Resets the current pointer to its position before the current 46 | * instruction disassembly was started. 47 | */ 48 | static inline void 49 | inp_reset(struct ud *u) 50 | { 51 | u->inp_curr -= u->inp_ctr; 52 | u->inp_ctr = 0; 53 | } 54 | 55 | /* inp_sess 56 | * Returns the pointer to current session. 57 | */ 58 | static inline uint8_t* 59 | inp_sess(struct ud *u) 60 | { 61 | return u->inp_sess; 62 | } 63 | 64 | /* 65 | * inp_curr 66 | * Returns the current input byte. 67 | */ 68 | static inline uint8_t 69 | inp_curr(const struct ud *u) 70 | { 71 | return u->inp_cache[u->inp_curr]; 72 | } 73 | 74 | /* 75 | * inp_back 76 | * Move back a single byte in the stream. 77 | */ 78 | static inline void 79 | inp_back(struct ud* u) 80 | { 81 | if (u->inp_ctr > 0) { 82 | --u->inp_curr; 83 | --u->inp_ctr; 84 | } 85 | } 86 | 87 | /* 88 | * inp_peek 89 | * Peek next byte in input. 90 | */ 91 | static inline uint8_t 92 | inp_peek(struct ud* u) 93 | { 94 | uint8_t r = ud_inp_next(u); 95 | if (!u->error) { 96 | inp_back(u); /* Don't backup if there was an error */ 97 | } 98 | return r; 99 | } 100 | 101 | 102 | /* 103 | * inp_len 104 | * Returns the number of bytes input in the current 105 | * session. 106 | */ 107 | static inline size_t 108 | inp_len(const struct ud *u) 109 | { 110 | return u->inp_ctr; 111 | } 112 | 113 | #endif /* UD_INPUT_H */ 114 | /* 115 | vim: set ts=2 sw=2 expandtab 116 | */ 117 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/itab.h: -------------------------------------------------------------------------------- 1 | #ifndef UD_ITAB_H 2 | #define UD_ITAB_H 3 | 4 | /* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */ 5 | 6 | /* ud_table_type -- lookup table types (see decode.c) */ 7 | enum ud_table_type { 8 | UD_TAB__OPC_TABLE, 9 | UD_TAB__OPC_X87, 10 | UD_TAB__OPC_MOD, 11 | UD_TAB__OPC_VEX_M, 12 | UD_TAB__OPC_VEX_P, 13 | UD_TAB__OPC_RM, 14 | UD_TAB__OPC_VENDOR, 15 | UD_TAB__OPC_OSIZE, 16 | UD_TAB__OPC_MODE, 17 | UD_TAB__OPC_3DNOW, 18 | UD_TAB__OPC_REG, 19 | UD_TAB__OPC_ASIZE, 20 | UD_TAB__OPC_SSE 21 | }; 22 | 23 | /* ud_mnemonic -- mnemonic constants */ 24 | enum ud_mnemonic_code { 25 | UD_Iinvalid, 26 | UD_I3dnow, 27 | UD_Inone, 28 | UD_Idb, 29 | UD_Ipause, 30 | UD_Iaaa, 31 | UD_Iaad, 32 | UD_Iaam, 33 | UD_Iaas, 34 | UD_Iadc, 35 | UD_Iadd, 36 | UD_Iaddpd, 37 | UD_Iaddps, 38 | UD_Iaddsd, 39 | UD_Iaddss, 40 | UD_Iand, 41 | UD_Iandpd, 42 | UD_Iandps, 43 | UD_Iandnpd, 44 | UD_Iandnps, 45 | UD_Iarpl, 46 | UD_Imovsxd, 47 | UD_Ibound, 48 | UD_Ibsf, 49 | UD_Ibsr, 50 | UD_Ibswap, 51 | UD_Ibt, 52 | UD_Ibtc, 53 | UD_Ibtr, 54 | UD_Ibts, 55 | UD_Icall, 56 | UD_Icbw, 57 | UD_Icwde, 58 | UD_Icdqe, 59 | UD_Iclc, 60 | UD_Icld, 61 | UD_Iclflush, 62 | UD_Iclgi, 63 | UD_Icli, 64 | UD_Iclts, 65 | UD_Icmc, 66 | UD_Icmovo, 67 | UD_Icmovno, 68 | UD_Icmovb, 69 | UD_Icmovae, 70 | UD_Icmovz, 71 | UD_Icmovnz, 72 | UD_Icmovbe, 73 | UD_Icmova, 74 | UD_Icmovs, 75 | UD_Icmovns, 76 | UD_Icmovp, 77 | UD_Icmovnp, 78 | UD_Icmovl, 79 | UD_Icmovge, 80 | UD_Icmovle, 81 | UD_Icmovg, 82 | UD_Icmp, 83 | UD_Icmppd, 84 | UD_Icmpps, 85 | UD_Icmpsb, 86 | UD_Icmpsw, 87 | UD_Icmpsd, 88 | UD_Icmpsq, 89 | UD_Icmpss, 90 | UD_Icmpxchg, 91 | UD_Icmpxchg8b, 92 | UD_Icmpxchg16b, 93 | UD_Icomisd, 94 | UD_Icomiss, 95 | UD_Icpuid, 96 | UD_Icvtdq2pd, 97 | UD_Icvtdq2ps, 98 | UD_Icvtpd2dq, 99 | UD_Icvtpd2pi, 100 | UD_Icvtpd2ps, 101 | UD_Icvtpi2ps, 102 | UD_Icvtpi2pd, 103 | UD_Icvtps2dq, 104 | UD_Icvtps2pi, 105 | UD_Icvtps2pd, 106 | UD_Icvtsd2si, 107 | UD_Icvtsd2ss, 108 | UD_Icvtsi2ss, 109 | UD_Icvtss2si, 110 | UD_Icvtss2sd, 111 | UD_Icvttpd2pi, 112 | UD_Icvttpd2dq, 113 | UD_Icvttps2dq, 114 | UD_Icvttps2pi, 115 | UD_Icvttsd2si, 116 | UD_Icvtsi2sd, 117 | UD_Icvttss2si, 118 | UD_Icwd, 119 | UD_Icdq, 120 | UD_Icqo, 121 | UD_Idaa, 122 | UD_Idas, 123 | UD_Idec, 124 | UD_Idiv, 125 | UD_Idivpd, 126 | UD_Idivps, 127 | UD_Idivsd, 128 | UD_Idivss, 129 | UD_Iemms, 130 | UD_Ienter, 131 | UD_If2xm1, 132 | UD_Ifabs, 133 | UD_Ifadd, 134 | UD_Ifaddp, 135 | UD_Ifbld, 136 | UD_Ifbstp, 137 | UD_Ifchs, 138 | UD_Ifclex, 139 | UD_Ifcmovb, 140 | UD_Ifcmove, 141 | UD_Ifcmovbe, 142 | UD_Ifcmovu, 143 | UD_Ifcmovnb, 144 | UD_Ifcmovne, 145 | UD_Ifcmovnbe, 146 | UD_Ifcmovnu, 147 | UD_Ifucomi, 148 | UD_Ifcom, 149 | UD_Ifcom2, 150 | UD_Ifcomp3, 151 | UD_Ifcomi, 152 | UD_Ifucomip, 153 | UD_Ifcomip, 154 | UD_Ifcomp, 155 | UD_Ifcomp5, 156 | UD_Ifcompp, 157 | UD_Ifcos, 158 | UD_Ifdecstp, 159 | UD_Ifdiv, 160 | UD_Ifdivp, 161 | UD_Ifdivr, 162 | UD_Ifdivrp, 163 | UD_Ifemms, 164 | UD_Iffree, 165 | UD_Iffreep, 166 | UD_Ificom, 167 | UD_Ificomp, 168 | UD_Ifild, 169 | UD_Ifincstp, 170 | UD_Ifninit, 171 | UD_Ifiadd, 172 | UD_Ifidivr, 173 | UD_Ifidiv, 174 | UD_Ifisub, 175 | UD_Ifisubr, 176 | UD_Ifist, 177 | UD_Ifistp, 178 | UD_Ifisttp, 179 | UD_Ifld, 180 | UD_Ifld1, 181 | UD_Ifldl2t, 182 | UD_Ifldl2e, 183 | UD_Ifldpi, 184 | UD_Ifldlg2, 185 | UD_Ifldln2, 186 | UD_Ifldz, 187 | UD_Ifldcw, 188 | UD_Ifldenv, 189 | UD_Ifmul, 190 | UD_Ifmulp, 191 | UD_Ifimul, 192 | UD_Ifnop, 193 | UD_Ifpatan, 194 | UD_Ifprem, 195 | UD_Ifprem1, 196 | UD_Ifptan, 197 | UD_Ifrndint, 198 | UD_Ifrstor, 199 | UD_Ifnsave, 200 | UD_Ifscale, 201 | UD_Ifsin, 202 | UD_Ifsincos, 203 | UD_Ifsqrt, 204 | UD_Ifstp, 205 | UD_Ifstp1, 206 | UD_Ifstp8, 207 | UD_Ifstp9, 208 | UD_Ifst, 209 | UD_Ifnstcw, 210 | UD_Ifnstenv, 211 | UD_Ifnstsw, 212 | UD_Ifsub, 213 | UD_Ifsubp, 214 | UD_Ifsubr, 215 | UD_Ifsubrp, 216 | UD_Iftst, 217 | UD_Ifucom, 218 | UD_Ifucomp, 219 | UD_Ifucompp, 220 | UD_Ifxam, 221 | UD_Ifxch, 222 | UD_Ifxch4, 223 | UD_Ifxch7, 224 | UD_Ifxrstor, 225 | UD_Ifxsave, 226 | UD_Ifxtract, 227 | UD_Ifyl2x, 228 | UD_Ifyl2xp1, 229 | UD_Ihlt, 230 | UD_Iidiv, 231 | UD_Iin, 232 | UD_Iimul, 233 | UD_Iinc, 234 | UD_Iinsb, 235 | UD_Iinsw, 236 | UD_Iinsd, 237 | UD_Iint1, 238 | UD_Iint3, 239 | UD_Iint, 240 | UD_Iinto, 241 | UD_Iinvd, 242 | UD_Iinvept, 243 | UD_Iinvlpg, 244 | UD_Iinvlpga, 245 | UD_Iinvvpid, 246 | UD_Iiretw, 247 | UD_Iiretd, 248 | UD_Iiretq, 249 | UD_Ijo, 250 | UD_Ijno, 251 | UD_Ijb, 252 | UD_Ijae, 253 | UD_Ijz, 254 | UD_Ijnz, 255 | UD_Ijbe, 256 | UD_Ija, 257 | UD_Ijs, 258 | UD_Ijns, 259 | UD_Ijp, 260 | UD_Ijnp, 261 | UD_Ijl, 262 | UD_Ijge, 263 | UD_Ijle, 264 | UD_Ijg, 265 | UD_Ijcxz, 266 | UD_Ijecxz, 267 | UD_Ijrcxz, 268 | UD_Ijmp, 269 | UD_Ilahf, 270 | UD_Ilar, 271 | UD_Ilddqu, 272 | UD_Ildmxcsr, 273 | UD_Ilds, 274 | UD_Ilea, 275 | UD_Iles, 276 | UD_Ilfs, 277 | UD_Ilgs, 278 | UD_Ilidt, 279 | UD_Ilss, 280 | UD_Ileave, 281 | UD_Ilfence, 282 | UD_Ilgdt, 283 | UD_Illdt, 284 | UD_Ilmsw, 285 | UD_Ilock, 286 | UD_Ilodsb, 287 | UD_Ilodsw, 288 | UD_Ilodsd, 289 | UD_Ilodsq, 290 | UD_Iloopne, 291 | UD_Iloope, 292 | UD_Iloop, 293 | UD_Ilsl, 294 | UD_Iltr, 295 | UD_Imaskmovq, 296 | UD_Imaxpd, 297 | UD_Imaxps, 298 | UD_Imaxsd, 299 | UD_Imaxss, 300 | UD_Imfence, 301 | UD_Iminpd, 302 | UD_Iminps, 303 | UD_Iminsd, 304 | UD_Iminss, 305 | UD_Imonitor, 306 | UD_Imontmul, 307 | UD_Imov, 308 | UD_Imovapd, 309 | UD_Imovaps, 310 | UD_Imovd, 311 | UD_Imovhpd, 312 | UD_Imovhps, 313 | UD_Imovlhps, 314 | UD_Imovlpd, 315 | UD_Imovlps, 316 | UD_Imovhlps, 317 | UD_Imovmskpd, 318 | UD_Imovmskps, 319 | UD_Imovntdq, 320 | UD_Imovnti, 321 | UD_Imovntpd, 322 | UD_Imovntps, 323 | UD_Imovntq, 324 | UD_Imovq, 325 | UD_Imovsb, 326 | UD_Imovsw, 327 | UD_Imovsd, 328 | UD_Imovsq, 329 | UD_Imovss, 330 | UD_Imovsx, 331 | UD_Imovupd, 332 | UD_Imovups, 333 | UD_Imovzx, 334 | UD_Imul, 335 | UD_Imulpd, 336 | UD_Imulps, 337 | UD_Imulsd, 338 | UD_Imulss, 339 | UD_Imwait, 340 | UD_Ineg, 341 | UD_Inop, 342 | UD_Inot, 343 | UD_Ior, 344 | UD_Iorpd, 345 | UD_Iorps, 346 | UD_Iout, 347 | UD_Ioutsb, 348 | UD_Ioutsw, 349 | UD_Ioutsd, 350 | UD_Ipacksswb, 351 | UD_Ipackssdw, 352 | UD_Ipackuswb, 353 | UD_Ipaddb, 354 | UD_Ipaddw, 355 | UD_Ipaddd, 356 | UD_Ipaddsb, 357 | UD_Ipaddsw, 358 | UD_Ipaddusb, 359 | UD_Ipaddusw, 360 | UD_Ipand, 361 | UD_Ipandn, 362 | UD_Ipavgb, 363 | UD_Ipavgw, 364 | UD_Ipcmpeqb, 365 | UD_Ipcmpeqw, 366 | UD_Ipcmpeqd, 367 | UD_Ipcmpgtb, 368 | UD_Ipcmpgtw, 369 | UD_Ipcmpgtd, 370 | UD_Ipextrb, 371 | UD_Ipextrd, 372 | UD_Ipextrq, 373 | UD_Ipextrw, 374 | UD_Ipinsrb, 375 | UD_Ipinsrw, 376 | UD_Ipinsrd, 377 | UD_Ipinsrq, 378 | UD_Ipmaddwd, 379 | UD_Ipmaxsw, 380 | UD_Ipmaxub, 381 | UD_Ipminsw, 382 | UD_Ipminub, 383 | UD_Ipmovmskb, 384 | UD_Ipmulhuw, 385 | UD_Ipmulhw, 386 | UD_Ipmullw, 387 | UD_Ipop, 388 | UD_Ipopa, 389 | UD_Ipopad, 390 | UD_Ipopfw, 391 | UD_Ipopfd, 392 | UD_Ipopfq, 393 | UD_Ipor, 394 | UD_Iprefetch, 395 | UD_Iprefetchnta, 396 | UD_Iprefetcht0, 397 | UD_Iprefetcht1, 398 | UD_Iprefetcht2, 399 | UD_Ipsadbw, 400 | UD_Ipshufw, 401 | UD_Ipsllw, 402 | UD_Ipslld, 403 | UD_Ipsllq, 404 | UD_Ipsraw, 405 | UD_Ipsrad, 406 | UD_Ipsrlw, 407 | UD_Ipsrld, 408 | UD_Ipsrlq, 409 | UD_Ipsubb, 410 | UD_Ipsubw, 411 | UD_Ipsubd, 412 | UD_Ipsubsb, 413 | UD_Ipsubsw, 414 | UD_Ipsubusb, 415 | UD_Ipsubusw, 416 | UD_Ipunpckhbw, 417 | UD_Ipunpckhwd, 418 | UD_Ipunpckhdq, 419 | UD_Ipunpcklbw, 420 | UD_Ipunpcklwd, 421 | UD_Ipunpckldq, 422 | UD_Ipi2fw, 423 | UD_Ipi2fd, 424 | UD_Ipf2iw, 425 | UD_Ipf2id, 426 | UD_Ipfnacc, 427 | UD_Ipfpnacc, 428 | UD_Ipfcmpge, 429 | UD_Ipfmin, 430 | UD_Ipfrcp, 431 | UD_Ipfrsqrt, 432 | UD_Ipfsub, 433 | UD_Ipfadd, 434 | UD_Ipfcmpgt, 435 | UD_Ipfmax, 436 | UD_Ipfrcpit1, 437 | UD_Ipfrsqit1, 438 | UD_Ipfsubr, 439 | UD_Ipfacc, 440 | UD_Ipfcmpeq, 441 | UD_Ipfmul, 442 | UD_Ipfrcpit2, 443 | UD_Ipmulhrw, 444 | UD_Ipswapd, 445 | UD_Ipavgusb, 446 | UD_Ipush, 447 | UD_Ipusha, 448 | UD_Ipushad, 449 | UD_Ipushfw, 450 | UD_Ipushfd, 451 | UD_Ipushfq, 452 | UD_Ipxor, 453 | UD_Ircl, 454 | UD_Ircr, 455 | UD_Irol, 456 | UD_Iror, 457 | UD_Ircpps, 458 | UD_Ircpss, 459 | UD_Irdmsr, 460 | UD_Irdpmc, 461 | UD_Irdtsc, 462 | UD_Irdtscp, 463 | UD_Irepne, 464 | UD_Irep, 465 | UD_Iret, 466 | UD_Iretf, 467 | UD_Irsm, 468 | UD_Irsqrtps, 469 | UD_Irsqrtss, 470 | UD_Isahf, 471 | UD_Isalc, 472 | UD_Isar, 473 | UD_Ishl, 474 | UD_Ishr, 475 | UD_Isbb, 476 | UD_Iscasb, 477 | UD_Iscasw, 478 | UD_Iscasd, 479 | UD_Iscasq, 480 | UD_Iseto, 481 | UD_Isetno, 482 | UD_Isetb, 483 | UD_Isetae, 484 | UD_Isetz, 485 | UD_Isetnz, 486 | UD_Isetbe, 487 | UD_Iseta, 488 | UD_Isets, 489 | UD_Isetns, 490 | UD_Isetp, 491 | UD_Isetnp, 492 | UD_Isetl, 493 | UD_Isetge, 494 | UD_Isetle, 495 | UD_Isetg, 496 | UD_Isfence, 497 | UD_Isgdt, 498 | UD_Ishld, 499 | UD_Ishrd, 500 | UD_Ishufpd, 501 | UD_Ishufps, 502 | UD_Isidt, 503 | UD_Isldt, 504 | UD_Ismsw, 505 | UD_Isqrtps, 506 | UD_Isqrtpd, 507 | UD_Isqrtsd, 508 | UD_Isqrtss, 509 | UD_Istc, 510 | UD_Istd, 511 | UD_Istgi, 512 | UD_Isti, 513 | UD_Iskinit, 514 | UD_Istmxcsr, 515 | UD_Istosb, 516 | UD_Istosw, 517 | UD_Istosd, 518 | UD_Istosq, 519 | UD_Istr, 520 | UD_Isub, 521 | UD_Isubpd, 522 | UD_Isubps, 523 | UD_Isubsd, 524 | UD_Isubss, 525 | UD_Iswapgs, 526 | UD_Isyscall, 527 | UD_Isysenter, 528 | UD_Isysexit, 529 | UD_Isysret, 530 | UD_Itest, 531 | UD_Iucomisd, 532 | UD_Iucomiss, 533 | UD_Iud2, 534 | UD_Iunpckhpd, 535 | UD_Iunpckhps, 536 | UD_Iunpcklps, 537 | UD_Iunpcklpd, 538 | UD_Iverr, 539 | UD_Iverw, 540 | UD_Ivmcall, 541 | UD_Ivmclear, 542 | UD_Ivmxon, 543 | UD_Ivmptrld, 544 | UD_Ivmptrst, 545 | UD_Ivmlaunch, 546 | UD_Ivmresume, 547 | UD_Ivmxoff, 548 | UD_Ivmread, 549 | UD_Ivmwrite, 550 | UD_Ivmrun, 551 | UD_Ivmmcall, 552 | UD_Ivmload, 553 | UD_Ivmsave, 554 | UD_Iwait, 555 | UD_Iwbinvd, 556 | UD_Iwrmsr, 557 | UD_Ixadd, 558 | UD_Ixchg, 559 | UD_Ixgetbv, 560 | UD_Ixlatb, 561 | UD_Ixor, 562 | UD_Ixorpd, 563 | UD_Ixorps, 564 | UD_Ixcryptecb, 565 | UD_Ixcryptcbc, 566 | UD_Ixcryptctr, 567 | UD_Ixcryptcfb, 568 | UD_Ixcryptofb, 569 | UD_Ixrstor, 570 | UD_Ixsave, 571 | UD_Ixsetbv, 572 | UD_Ixsha1, 573 | UD_Ixsha256, 574 | UD_Ixstore, 575 | UD_Iaesdec, 576 | UD_Iaesdeclast, 577 | UD_Iaesenc, 578 | UD_Iaesenclast, 579 | UD_Iaesimc, 580 | UD_Iaeskeygenassist, 581 | UD_Ipclmulqdq, 582 | UD_Igetsec, 583 | UD_Imovdqa, 584 | UD_Imaskmovdqu, 585 | UD_Imovdq2q, 586 | UD_Imovdqu, 587 | UD_Imovq2dq, 588 | UD_Ipaddq, 589 | UD_Ipsubq, 590 | UD_Ipmuludq, 591 | UD_Ipshufhw, 592 | UD_Ipshuflw, 593 | UD_Ipshufd, 594 | UD_Ipslldq, 595 | UD_Ipsrldq, 596 | UD_Ipunpckhqdq, 597 | UD_Ipunpcklqdq, 598 | UD_Iaddsubpd, 599 | UD_Iaddsubps, 600 | UD_Ihaddpd, 601 | UD_Ihaddps, 602 | UD_Ihsubpd, 603 | UD_Ihsubps, 604 | UD_Imovddup, 605 | UD_Imovshdup, 606 | UD_Imovsldup, 607 | UD_Ipabsb, 608 | UD_Ipabsw, 609 | UD_Ipabsd, 610 | UD_Ipshufb, 611 | UD_Iphaddw, 612 | UD_Iphaddd, 613 | UD_Iphaddsw, 614 | UD_Ipmaddubsw, 615 | UD_Iphsubw, 616 | UD_Iphsubd, 617 | UD_Iphsubsw, 618 | UD_Ipsignb, 619 | UD_Ipsignd, 620 | UD_Ipsignw, 621 | UD_Ipmulhrsw, 622 | UD_Ipalignr, 623 | UD_Ipblendvb, 624 | UD_Ipmuldq, 625 | UD_Ipminsb, 626 | UD_Ipminsd, 627 | UD_Ipminuw, 628 | UD_Ipminud, 629 | UD_Ipmaxsb, 630 | UD_Ipmaxsd, 631 | UD_Ipmaxud, 632 | UD_Ipmaxuw, 633 | UD_Ipmulld, 634 | UD_Iphminposuw, 635 | UD_Iroundps, 636 | UD_Iroundpd, 637 | UD_Iroundss, 638 | UD_Iroundsd, 639 | UD_Iblendpd, 640 | UD_Ipblendw, 641 | UD_Iblendps, 642 | UD_Iblendvpd, 643 | UD_Iblendvps, 644 | UD_Idpps, 645 | UD_Idppd, 646 | UD_Impsadbw, 647 | UD_Iextractps, 648 | UD_Iinsertps, 649 | UD_Imovntdqa, 650 | UD_Ipackusdw, 651 | UD_Ipmovsxbw, 652 | UD_Ipmovsxbd, 653 | UD_Ipmovsxbq, 654 | UD_Ipmovsxwd, 655 | UD_Ipmovsxwq, 656 | UD_Ipmovsxdq, 657 | UD_Ipmovzxbw, 658 | UD_Ipmovzxbd, 659 | UD_Ipmovzxbq, 660 | UD_Ipmovzxwd, 661 | UD_Ipmovzxwq, 662 | UD_Ipmovzxdq, 663 | UD_Ipcmpeqq, 664 | UD_Ipopcnt, 665 | UD_Iptest, 666 | UD_Ipcmpestri, 667 | UD_Ipcmpestrm, 668 | UD_Ipcmpgtq, 669 | UD_Ipcmpistri, 670 | UD_Ipcmpistrm, 671 | UD_Imovbe, 672 | UD_Icrc32, 673 | UD_MAX_MNEMONIC_CODE 674 | } UD_ATTR_PACKED; 675 | 676 | extern const char * ud_mnemonics_str[]; 677 | 678 | #endif /* UD_ITAB_H */ 679 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/syn-att.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn-att.c 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "types.h" 27 | #include "extern.h" 28 | #include "decode.h" 29 | #include "itab.h" 30 | #include "syn.h" 31 | #include "udint.h" 32 | 33 | /* ----------------------------------------------------------------------------- 34 | * opr_cast() - Prints an operand cast. 35 | * ----------------------------------------------------------------------------- 36 | */ 37 | static void 38 | opr_cast(struct ud* u, struct ud_operand* op) 39 | { 40 | switch(op->size) { 41 | case 16 : case 32 : 42 | ud_asmprintf(u, "*"); break; 43 | default: break; 44 | } 45 | } 46 | 47 | /* ----------------------------------------------------------------------------- 48 | * gen_operand() - Generates assembly output for each operand. 49 | * ----------------------------------------------------------------------------- 50 | */ 51 | static void 52 | gen_operand(struct ud* u, struct ud_operand* op) 53 | { 54 | switch(op->type) { 55 | case UD_OP_CONST: 56 | ud_asmprintf(u, "$0x%x", op->lval.udword); 57 | break; 58 | 59 | case UD_OP_REG: 60 | ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); 61 | break; 62 | 63 | case UD_OP_MEM: 64 | if (u->br_far) { 65 | opr_cast(u, op); 66 | } 67 | if (u->pfx_seg) { 68 | ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); 69 | } 70 | if (op->offset != 0) { 71 | ud_syn_print_mem_disp(u, op, 0); 72 | } 73 | if (op->base) { 74 | ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); 75 | } 76 | if (op->index) { 77 | if (op->base) { 78 | ud_asmprintf(u, ","); 79 | } else { 80 | ud_asmprintf(u, "("); 81 | } 82 | ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); 83 | } 84 | if (op->scale) { 85 | ud_asmprintf(u, ",%d", op->scale); 86 | } 87 | if (op->base || op->index) { 88 | ud_asmprintf(u, ")"); 89 | } 90 | break; 91 | 92 | case UD_OP_IMM: 93 | ud_syn_print_imm(u, op); 94 | break; 95 | 96 | case UD_OP_JIMM: 97 | ud_syn_print_addr(u, ud_syn_rel_target(u, op)); 98 | break; 99 | 100 | case UD_OP_PTR: 101 | switch (op->size) { 102 | case 32: 103 | ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, 104 | op->lval.ptr.off & 0xFFFF); 105 | break; 106 | case 48: 107 | ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, 108 | op->lval.ptr.off); 109 | break; 110 | } 111 | break; 112 | 113 | default: return; 114 | } 115 | } 116 | 117 | /* ============================================================================= 118 | * translates to AT&T syntax 119 | * ============================================================================= 120 | */ 121 | extern void 122 | ud_translate_att(struct ud *u) 123 | { 124 | int size = 0; 125 | int star = 0; 126 | 127 | /* check if P_OSO prefix is used */ 128 | if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { 129 | switch (u->dis_mode) { 130 | case 16: 131 | ud_asmprintf(u, "o32 "); 132 | break; 133 | case 32: 134 | case 64: 135 | ud_asmprintf(u, "o16 "); 136 | break; 137 | } 138 | } 139 | 140 | /* check if P_ASO prefix was used */ 141 | if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { 142 | switch (u->dis_mode) { 143 | case 16: 144 | ud_asmprintf(u, "a32 "); 145 | break; 146 | case 32: 147 | ud_asmprintf(u, "a16 "); 148 | break; 149 | case 64: 150 | ud_asmprintf(u, "a32 "); 151 | break; 152 | } 153 | } 154 | 155 | if (u->pfx_lock) 156 | ud_asmprintf(u, "lock "); 157 | if (u->pfx_rep) { 158 | ud_asmprintf(u, "rep "); 159 | } else if (u->pfx_rep) { 160 | ud_asmprintf(u, "repe "); 161 | } else if (u->pfx_repne) { 162 | ud_asmprintf(u, "repne "); 163 | } 164 | 165 | /* special instructions */ 166 | switch (u->mnemonic) { 167 | case UD_Iretf: 168 | ud_asmprintf(u, "lret "); 169 | break; 170 | case UD_Idb: 171 | ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte); 172 | return; 173 | case UD_Ijmp: 174 | case UD_Icall: 175 | if (u->br_far) ud_asmprintf(u, "l"); 176 | if (u->operand[0].type == UD_OP_REG) { 177 | star = 1; 178 | } 179 | ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 180 | break; 181 | case UD_Ibound: 182 | case UD_Ienter: 183 | if (u->operand[0].type != UD_NONE) 184 | gen_operand(u, &u->operand[0]); 185 | if (u->operand[1].type != UD_NONE) { 186 | ud_asmprintf(u, ","); 187 | gen_operand(u, &u->operand[1]); 188 | } 189 | return; 190 | default: 191 | ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 192 | } 193 | 194 | if (size == 8) 195 | ud_asmprintf(u, "b"); 196 | else if (size == 16) 197 | ud_asmprintf(u, "w"); 198 | else if (size == 64) 199 | ud_asmprintf(u, "q"); 200 | 201 | if (star) { 202 | ud_asmprintf(u, " *"); 203 | } else { 204 | ud_asmprintf(u, " "); 205 | } 206 | 207 | if (u->operand[2].type != UD_NONE) { 208 | gen_operand(u, &u->operand[2]); 209 | ud_asmprintf(u, ", "); 210 | } 211 | 212 | if (u->operand[1].type != UD_NONE) { 213 | gen_operand(u, &u->operand[1]); 214 | ud_asmprintf(u, ", "); 215 | } 216 | 217 | if (u->operand[0].type != UD_NONE) 218 | gen_operand(u, &u->operand[0]); 219 | } 220 | 221 | /* 222 | vim: set ts=2 sw=2 expandtab 223 | */ 224 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/syn-intel.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn-intel.c 2 | * 3 | * Copyright (c) 2002-2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "types.h" 27 | #include "extern.h" 28 | #include "decode.h" 29 | #include "itab.h" 30 | #include "syn.h" 31 | #include "udint.h" 32 | 33 | /* ----------------------------------------------------------------------------- 34 | * opr_cast() - Prints an operand cast. 35 | * ----------------------------------------------------------------------------- 36 | */ 37 | static void 38 | opr_cast(struct ud* u, struct ud_operand* op) 39 | { 40 | if (u->br_far) { 41 | ud_asmprintf(u, "far "); 42 | } 43 | switch(op->size) { 44 | case 8: ud_asmprintf(u, "byte " ); break; 45 | case 16: ud_asmprintf(u, "word " ); break; 46 | case 32: ud_asmprintf(u, "dword "); break; 47 | case 64: ud_asmprintf(u, "qword "); break; 48 | case 80: ud_asmprintf(u, "tword "); break; 49 | default: break; 50 | } 51 | } 52 | 53 | /* ----------------------------------------------------------------------------- 54 | * gen_operand() - Generates assembly output for each operand. 55 | * ----------------------------------------------------------------------------- 56 | */ 57 | static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast) 58 | { 59 | switch(op->type) { 60 | case UD_OP_REG: 61 | ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]); 62 | break; 63 | 64 | case UD_OP_MEM: 65 | if (syn_cast) { 66 | opr_cast(u, op); 67 | } 68 | ud_asmprintf(u, "["); 69 | if (u->pfx_seg) { 70 | ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); 71 | } 72 | if (op->base) { 73 | ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]); 74 | } 75 | if (op->index) { 76 | ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "", 77 | ud_reg_tab[op->index - UD_R_AL]); 78 | if (op->scale) { 79 | ud_asmprintf(u, "*%d", op->scale); 80 | } 81 | } 82 | if (op->offset != 0) { 83 | ud_syn_print_mem_disp(u, op, (op->base != UD_NONE || 84 | op->index != UD_NONE) ? 1 : 0); 85 | } 86 | ud_asmprintf(u, "]"); 87 | break; 88 | 89 | case UD_OP_IMM: 90 | ud_syn_print_imm(u, op); 91 | break; 92 | 93 | 94 | case UD_OP_JIMM: 95 | ud_syn_print_addr(u, ud_syn_rel_target(u, op)); 96 | break; 97 | 98 | case UD_OP_PTR: 99 | switch (op->size) { 100 | case 32: 101 | ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg, 102 | op->lval.ptr.off & 0xFFFF); 103 | break; 104 | case 48: 105 | ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg, 106 | op->lval.ptr.off); 107 | break; 108 | } 109 | break; 110 | 111 | case UD_OP_CONST: 112 | if (syn_cast) opr_cast(u, op); 113 | ud_asmprintf(u, "%d", op->lval.udword); 114 | break; 115 | 116 | default: return; 117 | } 118 | } 119 | 120 | /* ============================================================================= 121 | * translates to intel syntax 122 | * ============================================================================= 123 | */ 124 | extern void 125 | ud_translate_intel(struct ud* u) 126 | { 127 | /* check if P_OSO prefix is used */ 128 | if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) { 129 | switch (u->dis_mode) { 130 | case 16: ud_asmprintf(u, "o32 "); break; 131 | case 32: 132 | case 64: ud_asmprintf(u, "o16 "); break; 133 | } 134 | } 135 | 136 | /* check if P_ASO prefix was used */ 137 | if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) { 138 | switch (u->dis_mode) { 139 | case 16: ud_asmprintf(u, "a32 "); break; 140 | case 32: ud_asmprintf(u, "a16 "); break; 141 | case 64: ud_asmprintf(u, "a32 "); break; 142 | } 143 | } 144 | 145 | if (u->pfx_seg && 146 | u->operand[0].type != UD_OP_MEM && 147 | u->operand[1].type != UD_OP_MEM ) { 148 | ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]); 149 | } 150 | 151 | if (u->pfx_lock) { 152 | ud_asmprintf(u, "lock "); 153 | } 154 | if (u->pfx_rep) { 155 | ud_asmprintf(u, "rep "); 156 | } else if (u->pfx_repe) { 157 | ud_asmprintf(u, "repe "); 158 | } else if (u->pfx_repne) { 159 | ud_asmprintf(u, "repne "); 160 | } 161 | 162 | /* print the instruction mnemonic */ 163 | ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 164 | 165 | if (u->operand[0].type != UD_NONE) { 166 | int cast = 0; 167 | ud_asmprintf(u, " "); 168 | if (u->operand[0].type == UD_OP_MEM) { 169 | if (u->operand[1].type == UD_OP_IMM || 170 | u->operand[1].type == UD_OP_CONST || 171 | u->operand[1].type == UD_NONE || 172 | (u->operand[0].size != u->operand[1].size && 173 | u->operand[1].type != UD_OP_REG)) { 174 | cast = 1; 175 | } else if (u->operand[1].type == UD_OP_REG && 176 | u->operand[1].base == UD_R_CL) { 177 | switch (u->mnemonic) { 178 | case UD_Ircl: 179 | case UD_Irol: 180 | case UD_Iror: 181 | case UD_Ircr: 182 | case UD_Ishl: 183 | case UD_Ishr: 184 | case UD_Isar: 185 | cast = 1; 186 | break; 187 | default: break; 188 | } 189 | } 190 | } 191 | gen_operand(u, &u->operand[0], cast); 192 | } 193 | 194 | if (u->operand[1].type != UD_NONE) { 195 | int cast = 0; 196 | ud_asmprintf(u, ", "); 197 | if (u->operand[1].type == UD_OP_MEM && 198 | u->operand[0].size != u->operand[1].size && 199 | !ud_opr_is_sreg(&u->operand[0])) { 200 | cast = 1; 201 | } 202 | gen_operand(u, &u->operand[1], cast); 203 | } 204 | 205 | if (u->operand[2].type != UD_NONE) { 206 | ud_asmprintf(u, ", "); 207 | gen_operand(u, &u->operand[2], 0); 208 | } 209 | } 210 | 211 | /* 212 | vim: set ts=2 sw=2 expandtab 213 | */ 214 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/syn.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn.c 2 | * 3 | * Copyright (c) 2002-2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "types.h" 27 | #include "decode.h" 28 | #include "syn.h" 29 | #include "udint.h" 30 | 31 | /* ----------------------------------------------------------------------------- 32 | * Intel Register Table - Order Matters (types.h)! 33 | * ----------------------------------------------------------------------------- 34 | */ 35 | const char* ud_reg_tab[] = 36 | { 37 | "al", "cl", "dl", "bl", 38 | "ah", "ch", "dh", "bh", 39 | "spl", "bpl", "sil", "dil", 40 | "r8b", "r9b", "r10b", "r11b", 41 | "r12b", "r13b", "r14b", "r15b", 42 | 43 | "ax", "cx", "dx", "bx", 44 | "sp", "bp", "si", "di", 45 | "r8w", "r9w", "r10w", "r11w", 46 | "r12w", "r13w" , "r14w", "r15w", 47 | 48 | "eax", "ecx", "edx", "ebx", 49 | "esp", "ebp", "esi", "edi", 50 | "r8d", "r9d", "r10d", "r11d", 51 | "r12d", "r13d", "r14d", "r15d", 52 | 53 | "rax", "rcx", "rdx", "rbx", 54 | "rsp", "rbp", "rsi", "rdi", 55 | "r8", "r9", "r10", "r11", 56 | "r12", "r13", "r14", "r15", 57 | 58 | "es", "cs", "ss", "ds", 59 | "fs", "gs", 60 | 61 | "cr0", "cr1", "cr2", "cr3", 62 | "cr4", "cr5", "cr6", "cr7", 63 | "cr8", "cr9", "cr10", "cr11", 64 | "cr12", "cr13", "cr14", "cr15", 65 | 66 | "dr0", "dr1", "dr2", "dr3", 67 | "dr4", "dr5", "dr6", "dr7", 68 | "dr8", "dr9", "dr10", "dr11", 69 | "dr12", "dr13", "dr14", "dr15", 70 | 71 | "mm0", "mm1", "mm2", "mm3", 72 | "mm4", "mm5", "mm6", "mm7", 73 | 74 | "st0", "st1", "st2", "st3", 75 | "st4", "st5", "st6", "st7", 76 | 77 | "xmm0", "xmm1", "xmm2", "xmm3", 78 | "xmm4", "xmm5", "xmm6", "xmm7", 79 | "xmm8", "xmm9", "xmm10", "xmm11", 80 | "xmm12", "xmm13", "xmm14", "xmm15", 81 | 82 | "rip" 83 | }; 84 | 85 | 86 | uint64_t 87 | ud_syn_rel_target(struct ud *u, struct ud_operand *opr) 88 | { 89 | const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode); 90 | switch (opr->size) { 91 | case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask; 92 | case 16: return (u->pc + opr->lval.sword) & trunc_mask; 93 | case 32: return (u->pc + opr->lval.sdword) & trunc_mask; 94 | default: UD_ASSERT(!"invalid relative offset size."); 95 | } 96 | return NULL; 97 | } 98 | 99 | 100 | /* 101 | * asmprintf 102 | * Printf style function for printing translated assembly 103 | * output. Returns the number of characters written and 104 | * moves the buffer pointer forward. On an overflow, 105 | * returns a negative number and truncates the output. 106 | */ 107 | int 108 | ud_asmprintf(struct ud *u, char *fmt, ...) 109 | { 110 | int ret; 111 | int avail; 112 | va_list ap; 113 | va_start(ap, fmt); 114 | avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */; 115 | ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap); 116 | if (ret < 0 || ret > avail) { 117 | u->asm_buf_fill = u->asm_buf_size - 1; 118 | } else { 119 | u->asm_buf_fill += ret; 120 | } 121 | va_end(ap); 122 | return ret; 123 | } 124 | 125 | 126 | void 127 | ud_syn_print_addr(struct ud *u, uint64_t addr) 128 | { 129 | const char *name = NULL; 130 | if (u->sym_resolver) { 131 | int64_t offset = 0; 132 | name = u->sym_resolver(u, addr, &offset); 133 | if (name) { 134 | if (offset) { 135 | ud_asmprintf(u, "%s%+" FMT64 "d", name, offset); 136 | } else { 137 | ud_asmprintf(u, "%s", name); 138 | } 139 | return; 140 | } 141 | } 142 | ud_asmprintf(u, "0x%" FMT64 "x", addr); 143 | } 144 | 145 | 146 | void 147 | ud_syn_print_imm(struct ud* u, const struct ud_operand *op) 148 | { 149 | uint64_t v; 150 | if (op->_oprcode == OP_sI && op->size != u->opr_mode) { 151 | if (op->size == 8) { 152 | v = (int64_t)op->lval.sbyte; 153 | } else { 154 | UD_ASSERT(op->size == 32); 155 | v = (int64_t)op->lval.sdword; 156 | } 157 | if (u->opr_mode < 64) { 158 | v = v & ((1ull << u->opr_mode) - 1ull); 159 | } 160 | } else { 161 | switch (op->size) { 162 | case 8 : v = op->lval.ubyte; break; 163 | case 16: v = op->lval.uword; break; 164 | case 32: v = op->lval.udword; break; 165 | case 64: v = op->lval.uqword; break; 166 | default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ 167 | } 168 | } 169 | ud_asmprintf(u, "0x%" FMT64 "x", v); 170 | } 171 | 172 | 173 | void 174 | ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign) 175 | { 176 | UD_ASSERT(op->offset != 0); 177 | if (op->base == UD_NONE && op->index == UD_NONE) { 178 | uint64_t v; 179 | UD_ASSERT(op->scale == UD_NONE && op->offset != 8); 180 | /* unsigned mem-offset */ 181 | switch (op->offset) { 182 | case 16: v = op->lval.uword; break; 183 | case 32: v = op->lval.udword; break; 184 | case 64: v = op->lval.uqword; break; 185 | default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ 186 | } 187 | ud_asmprintf(u, "0x%" FMT64 "x", v); 188 | } else { 189 | int64_t v; 190 | UD_ASSERT(op->offset != 64); 191 | switch (op->offset) { 192 | case 8 : v = op->lval.sbyte; break; 193 | case 16: v = op->lval.sword; break; 194 | case 32: v = op->lval.sdword; break; 195 | default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ 196 | } 197 | if (v < 0) { 198 | ud_asmprintf(u, "-0x%" FMT64 "x", -v); 199 | } else if (v > 0) { 200 | ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v); 201 | } 202 | } 203 | } 204 | 205 | /* 206 | vim: set ts=2 sw=2 expandtab 207 | */ 208 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/syn.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn.h 2 | * 3 | * Copyright (c) 2002-2009 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_SYN_H 27 | #define UD_SYN_H 28 | 29 | #include "types.h" 30 | #ifndef __UD_STANDALONE__ 31 | # include 32 | #endif /* __UD_STANDALONE__ */ 33 | 34 | extern const char* ud_reg_tab[]; 35 | 36 | uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*); 37 | 38 | #ifdef __GNUC__ 39 | int ud_asmprintf(struct ud *u, char *fmt, ...) 40 | __attribute__ ((format (printf, 2, 3))); 41 | #else 42 | int ud_asmprintf(struct ud *u, char *fmt, ...); 43 | #endif 44 | 45 | void ud_syn_print_addr(struct ud *u, uint64_t addr); 46 | void ud_syn_print_imm(struct ud* u, const struct ud_operand *op); 47 | void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign); 48 | 49 | #endif /* UD_SYN_H */ 50 | 51 | /* 52 | vim: set ts=2 sw=2 expandtab 53 | */ 54 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/types.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/types.h 2 | * 3 | * Copyright (c) 2002-2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_TYPES_H 27 | #define UD_TYPES_H 28 | 29 | #ifdef __KERNEL__ 30 | /* -D__KERNEL__ is automatically passed on the command line when 31 | building something as part of the Linux kernel */ 32 | # include 33 | # include 34 | # ifndef __UD_STANDALONE__ 35 | # define __UD_STANDALONE__ 1 36 | #endif 37 | #endif /* __KERNEL__ */ 38 | 39 | #if defined(_MSC_VER) || defined(__BORLANDC__) 40 | # include 41 | # include 42 | # define inline __inline /* MS Visual Studio requires __inline 43 | instead of inline for C code */ 44 | #elif !defined(__UD_STANDALONE__) 45 | # include 46 | # include 47 | #endif /* !__UD_STANDALONE__ */ 48 | 49 | /* gcc specific extensions */ 50 | #ifdef __GNUC__ 51 | # define UD_ATTR_PACKED __attribute__((packed)) 52 | #else 53 | # define UD_ATTR_PACKED 54 | #endif /* UD_ATTR_PACKED */ 55 | 56 | 57 | /* ----------------------------------------------------------------------------- 58 | * All possible "types" of objects in udis86. Order is Important! 59 | * ----------------------------------------------------------------------------- 60 | */ 61 | enum ud_type 62 | { 63 | UD_NONE, 64 | 65 | /* 8 bit GPRs */ 66 | UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, 67 | UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, 68 | UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, 69 | UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, 70 | UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, 71 | 72 | /* 16 bit GPRs */ 73 | UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, 74 | UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, 75 | UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, 76 | UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, 77 | 78 | /* 32 bit GPRs */ 79 | UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, 80 | UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, 81 | UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, 82 | UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, 83 | 84 | /* 64 bit GPRs */ 85 | UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, 86 | UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, 87 | UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, 88 | UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, 89 | 90 | /* segment registers */ 91 | UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, 92 | UD_R_FS, UD_R_GS, 93 | 94 | /* control registers*/ 95 | UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, 96 | UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, 97 | UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, 98 | UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, 99 | 100 | /* debug registers */ 101 | UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, 102 | UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, 103 | UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, 104 | UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, 105 | 106 | /* mmx registers */ 107 | UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, 108 | UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, 109 | 110 | /* x87 registers */ 111 | UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, 112 | UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, 113 | 114 | /* extended multimedia registers */ 115 | UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, 116 | UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, 117 | UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, 118 | UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, 119 | 120 | UD_R_RIP, 121 | 122 | /* Operand Types */ 123 | UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM, 124 | UD_OP_JIMM, UD_OP_CONST 125 | }; 126 | 127 | #include "itab.h" 128 | 129 | union ud_lval { 130 | int8_t sbyte; 131 | uint8_t ubyte; 132 | int16_t sword; 133 | uint16_t uword; 134 | int32_t sdword; 135 | uint32_t udword; 136 | int64_t sqword; 137 | uint64_t uqword; 138 | struct { 139 | uint16_t seg; 140 | uint32_t off; 141 | } ptr; 142 | }; 143 | 144 | /* ----------------------------------------------------------------------------- 145 | * struct ud_operand - Disassembled instruction Operand. 146 | * ----------------------------------------------------------------------------- 147 | */ 148 | struct ud_operand { 149 | enum ud_type type; 150 | uint8_t size; 151 | enum ud_type base; 152 | enum ud_type index; 153 | uint8_t scale; 154 | uint8_t offset; 155 | union ud_lval lval; 156 | uint64_t disp; 157 | /* 158 | * internal use only 159 | */ 160 | uint8_t _oprcode; 161 | }; 162 | 163 | /* ----------------------------------------------------------------------------- 164 | * struct ud - The udis86 object. 165 | * ----------------------------------------------------------------------------- 166 | */ 167 | struct ud 168 | { 169 | /* 170 | * input buffering 171 | */ 172 | int (*inp_hook) (struct ud*); 173 | #ifndef __UD_STANDALONE__ 174 | FILE* inp_file; 175 | #endif 176 | uint8_t inp_curr; 177 | uint8_t inp_fill; 178 | uint8_t inp_ctr; 179 | const uint8_t* inp_buff; 180 | const uint8_t* inp_buff_end; 181 | uint8_t inp_end; 182 | uint8_t inp_cache[256]; 183 | uint8_t inp_sess[64]; 184 | 185 | void (*translator)(struct ud*); 186 | uint64_t insn_offset; 187 | char insn_hexcode[64]; 188 | 189 | /* 190 | * Assembly output buffer 191 | */ 192 | char *asm_buf; 193 | size_t asm_buf_size; 194 | size_t asm_buf_fill; 195 | char asm_buf_int[128]; 196 | 197 | /* 198 | * Symbol resolver for use in the translation phase. 199 | */ 200 | const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset); 201 | 202 | uint8_t dis_mode; 203 | uint64_t pc; 204 | uint8_t vendor; 205 | enum ud_mnemonic_code mnemonic; 206 | struct ud_operand operand[3]; 207 | uint8_t error; 208 | uint8_t pfx_rex; 209 | uint8_t pfx_seg; 210 | uint8_t pfx_opr; 211 | uint8_t pfx_adr; 212 | uint8_t pfx_lock; 213 | uint8_t pfx_str; 214 | uint8_t pfx_rep; 215 | uint8_t pfx_repe; 216 | uint8_t pfx_repne; 217 | uint8_t default64; 218 | uint8_t opr_mode; 219 | uint8_t adr_mode; 220 | uint8_t br_far; 221 | uint8_t br_near; 222 | uint8_t implicit_addr; 223 | uint8_t have_modrm; 224 | uint8_t modrm; 225 | uint8_t primary_opcode; 226 | void * user_opaque_data; 227 | struct ud_itab_entry * itab_entry; 228 | struct ud_lookup_table_list_entry *le; 229 | }; 230 | 231 | /* ----------------------------------------------------------------------------- 232 | * Type-definitions 233 | * ----------------------------------------------------------------------------- 234 | */ 235 | typedef enum ud_type ud_type_t; 236 | typedef enum ud_mnemonic_code ud_mnemonic_code_t; 237 | 238 | typedef struct ud ud_t; 239 | typedef struct ud_operand ud_operand_t; 240 | 241 | #define UD_SYN_INTEL ud_translate_intel 242 | #define UD_SYN_ATT ud_translate_att 243 | #define UD_EOI (-1) 244 | #define UD_INP_CACHE_SZ 32 245 | #define UD_VENDOR_AMD 0 246 | #define UD_VENDOR_INTEL 1 247 | #define UD_VENDOR_ANY 2 248 | 249 | #endif 250 | 251 | /* 252 | vim: set ts=2 sw=2 expandtab 253 | */ 254 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/udint.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/udint.h -- definitions for internal use only 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef _UDINT_H_ 27 | #define _UDINT_H_ 28 | 29 | #ifdef HAVE_CONFIG_H 30 | # include 31 | #endif /* HAVE_CONFIG_H */ 32 | 33 | #ifdef HAVE_ASSERT_H 34 | # include 35 | # define UD_ASSERT(_x) assert(_x) 36 | #else 37 | # define UD_ASSERT(_x) 38 | #endif /* !HAVE_ASSERT_H */ 39 | 40 | #ifdef LOGERR 41 | #define UDERR(u, msg) \ 42 | do { \ 43 | (u)->error = 1; \ 44 | fprintf(stderr, "decode-error: %s:%d: %s", \ 45 | __FILE__, __LINE__, (msg)); \ 46 | } while (0) 47 | #else 48 | #define UDERR(u, m) \ 49 | do { \ 50 | (u)->error = 1; \ 51 | } while (0) 52 | #endif /* !LOGERR */ 53 | 54 | #define UD_RETURN_ON_ERROR(u) \ 55 | do { \ 56 | if ((u)->error != 0) { \ 57 | return (u)->error; \ 58 | } \ 59 | } while (0) 60 | 61 | #define UD_RETURN_WITH_ERROR(u, m) \ 62 | do { \ 63 | UDERR(u, m); \ 64 | return (u)->error; \ 65 | } while (0) 66 | 67 | /* printf formatting int64 specifier */ 68 | #ifdef FMT64 69 | # undef FMT64 70 | #endif 71 | #if defined(_MSC_VER) || defined(__BORLANDC__) 72 | # define FMT64 "I64" 73 | #else 74 | # if defined(__APPLE__) 75 | # define FMT64 "ll" 76 | # elif defined(__amd64__) || defined(__x86_64__) 77 | # define FMT64 "l" 78 | # else 79 | # define FMT64 "ll" 80 | # endif /* !x64 */ 81 | #endif 82 | 83 | #endif /* _UDINT_H_ */ 84 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/udis86.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/udis86.c 2 | * 3 | * Copyright (c) 2002-2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "input.h" 28 | #include "extern.h" 29 | #include "decode.h" 30 | 31 | #if !defined(__UD_STANDALONE__) 32 | # if HAVE_STRING_H 33 | # include 34 | # endif 35 | #endif /* !__UD_STANDALONE__ */ 36 | 37 | /* ============================================================================= 38 | * ud_init() - Initializes ud_t object. 39 | * ============================================================================= 40 | */ 41 | extern void 42 | ud_init(struct ud* u) 43 | { 44 | memset((void*)u, 0, sizeof(struct ud)); 45 | ud_set_mode(u, 16); 46 | u->mnemonic = UD_Iinvalid; 47 | ud_set_pc(u, 0); 48 | #ifndef __UD_STANDALONE__ 49 | ud_set_input_file(u, stdin); 50 | #endif /* __UD_STANDALONE__ */ 51 | 52 | ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); 53 | } 54 | 55 | /* ============================================================================= 56 | * ud_disassemble() - disassembles one instruction and returns the number of 57 | * bytes disassembled. A zero means end of disassembly. 58 | * ============================================================================= 59 | */ 60 | extern unsigned int 61 | ud_disassemble(struct ud* u) 62 | { 63 | if (ud_input_end(u)) 64 | return 0; 65 | 66 | u->asm_buf[0] = 0; 67 | 68 | if (ud_decode(u) == 0) 69 | return 0; 70 | if (u->translator) 71 | u->translator(u); 72 | return ud_insn_len(u); 73 | } 74 | 75 | /* ============================================================================= 76 | * ud_set_mode() - Set Disassemly Mode. 77 | * ============================================================================= 78 | */ 79 | extern void 80 | ud_set_mode(struct ud* u, uint8_t m) 81 | { 82 | switch(m) { 83 | case 16: 84 | case 32: 85 | case 64: u->dis_mode = m ; return; 86 | default: u->dis_mode = 16; return; 87 | } 88 | } 89 | 90 | /* ============================================================================= 91 | * ud_set_vendor() - Set vendor. 92 | * ============================================================================= 93 | */ 94 | extern void 95 | ud_set_vendor(struct ud* u, unsigned v) 96 | { 97 | switch(v) { 98 | case UD_VENDOR_INTEL: 99 | u->vendor = v; 100 | break; 101 | case UD_VENDOR_ANY: 102 | u->vendor = v; 103 | break; 104 | default: 105 | u->vendor = UD_VENDOR_AMD; 106 | } 107 | } 108 | 109 | /* ============================================================================= 110 | * ud_set_pc() - Sets code origin. 111 | * ============================================================================= 112 | */ 113 | extern void 114 | ud_set_pc(struct ud* u, uint64_t o) 115 | { 116 | u->pc = o; 117 | } 118 | 119 | /* ============================================================================= 120 | * ud_set_syntax() - Sets the output syntax. 121 | * ============================================================================= 122 | */ 123 | extern void 124 | ud_set_syntax(struct ud* u, void (*t)(struct ud*)) 125 | { 126 | u->translator = t; 127 | } 128 | 129 | /* ============================================================================= 130 | * ud_insn() - returns the disassembled instruction 131 | * ============================================================================= 132 | */ 133 | const char* 134 | ud_insn_asm(const struct ud* u) 135 | { 136 | return u->asm_buf; 137 | } 138 | 139 | /* ============================================================================= 140 | * ud_insn_offset() - Returns the offset. 141 | * ============================================================================= 142 | */ 143 | uint64_t 144 | ud_insn_off(const struct ud* u) 145 | { 146 | return u->insn_offset; 147 | } 148 | 149 | 150 | /* ============================================================================= 151 | * ud_insn_hex() - Returns hex form of disassembled instruction. 152 | * ============================================================================= 153 | */ 154 | const char* 155 | ud_insn_hex(struct ud* u) 156 | { 157 | u->insn_hexcode[0] = 0; 158 | if (!u->error) { 159 | unsigned int i; 160 | unsigned char *src_ptr = inp_sess(u); 161 | char* src_hex; 162 | src_hex = (char*) u->insn_hexcode; 163 | /* for each byte used to decode instruction */ 164 | for (i = 0; i < u->inp_ctr && i < sizeof(u->insn_hexcode) / 2; 165 | ++i, ++src_ptr) { 166 | sprintf(src_hex, "%02x", *src_ptr & 0xFF); 167 | src_hex += 2; 168 | } 169 | } 170 | return u->insn_hexcode; 171 | } 172 | 173 | 174 | /* ============================================================================= 175 | * ud_insn_ptr() - Returns code disassembled. 176 | * ============================================================================= 177 | */ 178 | extern const uint8_t* 179 | ud_insn_ptr(const struct ud* u) 180 | { 181 | return u->inp_sess; 182 | } 183 | 184 | /* ============================================================================= 185 | * ud_insn_len() - Returns the count of bytes disassembled. 186 | * ============================================================================= 187 | */ 188 | extern unsigned int 189 | ud_insn_len(const struct ud* u) 190 | { 191 | return u->inp_ctr; 192 | } 193 | 194 | 195 | /* ============================================================================= 196 | * ud_insn_get_opr 197 | * Return the operand struct representing the nth operand of 198 | * the currently disassembled instruction. Returns NULL if 199 | * there's no such operand. 200 | * ============================================================================= 201 | */ 202 | const struct ud_operand* 203 | ud_insn_opr(const struct ud *u, unsigned int n) 204 | { 205 | if (n > 2 || u->operand[n].type == UD_NONE) { 206 | return NULL; 207 | } else { 208 | return &u->operand[n]; 209 | } 210 | } 211 | 212 | 213 | /* ============================================================================= 214 | * ud_opr_is_sreg 215 | * Returns non-zero if the given operand is of a segment register type. 216 | * ============================================================================= 217 | */ 218 | int 219 | ud_opr_is_sreg(const struct ud_operand *opr) 220 | { 221 | return opr->type == UD_OP_REG && 222 | opr->base >= UD_R_ES && 223 | opr->base <= UD_R_GS; 224 | } 225 | 226 | 227 | /* ============================================================================= 228 | * ud_opr_is_sreg 229 | * Returns non-zero if the given operand is of a general purpose 230 | * register type. 231 | * ============================================================================= 232 | */ 233 | int 234 | ud_opr_is_gpr(const struct ud_operand *opr) 235 | { 236 | return opr->type == UD_OP_REG && 237 | opr->base >= UD_R_AL && 238 | opr->base <= UD_R_R15; 239 | } 240 | 241 | 242 | /* ============================================================================= 243 | * ud_set_user_opaque_data 244 | * ud_get_user_opaque_data 245 | * Get/set user opaqute data pointer 246 | * ============================================================================= 247 | */ 248 | void 249 | ud_set_user_opaque_data(struct ud * u, void* opaque) 250 | { 251 | u->user_opaque_data = opaque; 252 | } 253 | 254 | void* 255 | ud_get_user_opaque_data(const struct ud *u) 256 | { 257 | return u->user_opaque_data; 258 | } 259 | 260 | 261 | /* ============================================================================= 262 | * ud_set_asm_buffer 263 | * Allow the user to set an assembler output buffer. If `buf` is NULL, 264 | * we switch back to the internal buffer. 265 | * ============================================================================= 266 | */ 267 | void 268 | ud_set_asm_buffer(struct ud *u, char *buf, size_t size) 269 | { 270 | if (buf == NULL) { 271 | ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); 272 | } else { 273 | u->asm_buf = buf; 274 | u->asm_buf_size = size; 275 | } 276 | } 277 | 278 | 279 | /* ============================================================================= 280 | * ud_set_sym_resolver 281 | * Set symbol resolver for relative targets used in the translation 282 | * phase. 283 | * 284 | * The resolver is a function that takes a uint64_t address and returns a 285 | * symbolic name for the that address. The function also takes a second 286 | * argument pointing to an integer that the client can optionally set to a 287 | * non-zero value for offsetted targets. (symbol+offset) The function may 288 | * also return NULL, in which case the translator only prints the target 289 | * address. 290 | * 291 | * The function pointer maybe NULL which resets symbol resolution. 292 | * ============================================================================= 293 | */ 294 | void 295 | ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*, 296 | uint64_t addr, 297 | int64_t *offset)) 298 | { 299 | u->sym_resolver = resolver; 300 | } 301 | 302 | /* 303 | vim:set ts=2 sw=2 expandtab 304 | */ 305 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/libudis86/udis86.h: -------------------------------------------------------------------------------- 1 | /* udis86 - udis86.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UDIS86_H 27 | #define UDIS86_H 28 | 29 | #include "types.h" 30 | #include "extern.h" 31 | #include "itab.h" 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/mach_override.c: -------------------------------------------------------------------------------- 1 | // mach_override.c semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_override 5 | 6 | #include "mach_override.h" 7 | #if defined(__i386__) || defined(__x86_64__) 8 | #include "udis86.h" 9 | #endif 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | /************************** 20 | * 21 | * Constants 22 | * 23 | **************************/ 24 | #pragma mark - 25 | #pragma mark (Constants) 26 | 27 | #if defined(__ppc__) || defined(__POWERPC__) 28 | 29 | long kIslandTemplate[] = { 30 | 0x9001FFFC, // stw r0,-4(SP) 31 | 0x3C00DEAD, // lis r0,0xDEAD 32 | 0x6000BEEF, // ori r0,r0,0xBEEF 33 | 0x7C0903A6, // mtctr r0 34 | 0x8001FFFC, // lwz r0,-4(SP) 35 | 0x60000000, // nop ; optionally replaced 36 | 0x4E800420 // bctr 37 | }; 38 | 39 | #define kAddressHi 3 40 | #define kAddressLo 5 41 | #define kInstructionHi 10 42 | #define kInstructionLo 11 43 | 44 | #elif defined(__i386__) 45 | 46 | #define kOriginalInstructionsSize 16 47 | 48 | char kIslandTemplate[] = { 49 | // kOriginalInstructionsSize nop instructions so that we 50 | // should have enough space to host original instructions 51 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 52 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 53 | // Now the real jump instruction 54 | 0xE9, 0xEF, 0xBE, 0xAD, 0xDE 55 | }; 56 | 57 | #define kInstructions 0 58 | #define kJumpAddress kInstructions + kOriginalInstructionsSize + 1 59 | #elif defined(__x86_64__) 60 | 61 | #define kOriginalInstructionsSize 32 62 | 63 | #define kJumpAddress kOriginalInstructionsSize + 6 64 | 65 | char kIslandTemplate[] = { 66 | // kOriginalInstructionsSize nop instructions so that we 67 | // should have enough space to host original instructions 68 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 69 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 70 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 71 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 72 | // Now the real jump instruction 73 | 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00 76 | }; 77 | 78 | #endif 79 | 80 | #define kAllocateHigh 1 81 | #define kAllocateNormal 0 82 | 83 | /************************** 84 | * 85 | * Data Types 86 | * 87 | **************************/ 88 | #pragma mark - 89 | #pragma mark (Data Types) 90 | 91 | typedef struct { 92 | char instructions[sizeof(kIslandTemplate)]; 93 | int allocatedHigh; 94 | } BranchIsland; 95 | 96 | /************************** 97 | * 98 | * Funky Protos 99 | * 100 | **************************/ 101 | #pragma mark - 102 | #pragma mark (Funky Protos) 103 | 104 | mach_error_t 105 | allocateBranchIsland( 106 | BranchIsland **island, 107 | int allocateHigh, 108 | void *originalFunctionAddress); 109 | 110 | mach_error_t 111 | freeBranchIsland( 112 | BranchIsland *island ); 113 | 114 | #if defined(__ppc__) || defined(__POWERPC__) 115 | mach_error_t 116 | setBranchIslandTarget( 117 | BranchIsland *island, 118 | const void *branchTo, 119 | long instruction ); 120 | #endif 121 | 122 | #if defined(__i386__) || defined(__x86_64__) 123 | mach_error_t 124 | setBranchIslandTarget_i386( 125 | BranchIsland *island, 126 | const void *branchTo, 127 | char* instructions ); 128 | void 129 | atomic_mov64( 130 | uint64_t *targetAddress, 131 | uint64_t value ); 132 | 133 | static Boolean 134 | eatKnownInstructions( 135 | unsigned char *code, 136 | uint64_t *newInstruction, 137 | int *howManyEaten, 138 | char *originalInstructions, 139 | int *originalInstructionCount, 140 | uint8_t *originalInstructionSizes ); 141 | 142 | static void 143 | fixupInstructions( 144 | void *originalFunction, 145 | void *escapeIsland, 146 | void *instructionsToFix, 147 | int instructionCount, 148 | uint8_t *instructionSizes ); 149 | #endif 150 | 151 | /******************************************************************************* 152 | * 153 | * Interface 154 | * 155 | *******************************************************************************/ 156 | #pragma mark - 157 | #pragma mark (Interface) 158 | 159 | #if defined(__i386__) || defined(__x86_64__) 160 | mach_error_t makeIslandExecutable(void *address) { 161 | mach_error_t err = err_none; 162 | uintptr_t page = (uintptr_t)address & ~(uintptr_t)(PAGE_SIZE - 1); 163 | int e = err_none; 164 | e |= mprotect((void *)page, PAGE_SIZE, PROT_EXEC | PROT_READ); 165 | e |= msync((void *)page, PAGE_SIZE, MS_INVALIDATE ); 166 | if (e) { 167 | err = err_cannot_override; 168 | } 169 | return err; 170 | } 171 | #endif 172 | 173 | mach_error_t 174 | mach_override_ptr( 175 | void *originalFunctionAddress, 176 | const void *overrideFunctionAddress, 177 | void **originalFunctionReentryIsland ) 178 | { 179 | assert( originalFunctionAddress ); 180 | assert( overrideFunctionAddress ); 181 | 182 | // this addresses overriding such functions as AudioOutputUnitStart() 183 | // test with modified DefaultOutputUnit project 184 | #if defined(__x86_64__) 185 | for(;;){ 186 | if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp qword near [rip+0x????????] 187 | originalFunctionAddress=*(void**)((char*)originalFunctionAddress+6+*(int32_t *)((uint16_t*)originalFunctionAddress+1)); 188 | else break; 189 | } 190 | #elif defined(__i386__) 191 | for(;;){ 192 | if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp *0x???????? 193 | originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1); 194 | else break; 195 | } 196 | #endif 197 | 198 | long *originalFunctionPtr = (long*) originalFunctionAddress; 199 | mach_error_t err = err_none; 200 | 201 | #if defined(__ppc__) || defined(__POWERPC__) 202 | // Ensure first instruction isn't 'mfctr'. 203 | #define kMFCTRMask 0xfc1fffff 204 | #define kMFCTRInstruction 0x7c0903a6 205 | 206 | long originalInstruction = *originalFunctionPtr; 207 | if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) ) 208 | err = err_cannot_override; 209 | #elif defined(__i386__) || defined(__x86_64__) 210 | int eatenCount = 0; 211 | int originalInstructionCount = 0; 212 | char originalInstructions[kOriginalInstructionsSize]; 213 | uint8_t originalInstructionSizes[kOriginalInstructionsSize]; 214 | uint64_t jumpRelativeInstruction = 0; // JMP 215 | 216 | Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, 217 | &jumpRelativeInstruction, &eatenCount, 218 | originalInstructions, &originalInstructionCount, 219 | originalInstructionSizes ); 220 | if (eatenCount > kOriginalInstructionsSize) { 221 | //printf ("Too many instructions eaten\n"); 222 | overridePossible = false; 223 | } 224 | if (!overridePossible) err = err_cannot_override; 225 | if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); 226 | #endif 227 | 228 | // Make the original function implementation writable. 229 | if( !err ) { 230 | err = vm_protect( mach_task_self(), 231 | (vm_address_t) originalFunctionPtr, 8, false, 232 | (VM_PROT_ALL | VM_PROT_COPY) ); 233 | if( err ) 234 | err = vm_protect( mach_task_self(), 235 | (vm_address_t) originalFunctionPtr, 8, false, 236 | (VM_PROT_DEFAULT | VM_PROT_COPY) ); 237 | } 238 | if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); 239 | 240 | // Allocate and target the escape island to the overriding function. 241 | BranchIsland *escapeIsland = NULL; 242 | if( !err ) 243 | err = allocateBranchIsland( &escapeIsland, kAllocateHigh, originalFunctionAddress ); 244 | if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); 245 | 246 | 247 | #if defined(__ppc__) || defined(__POWERPC__) 248 | if( !err ) 249 | err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 ); 250 | 251 | // Build the branch absolute instruction to the escape island. 252 | long branchAbsoluteInstruction = 0; // Set to 0 just to silence warning. 253 | if( !err ) { 254 | long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF; 255 | branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress; 256 | } 257 | #elif defined(__i386__) || defined(__x86_64__) 258 | if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); 259 | 260 | if( !err ) 261 | err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 ); 262 | 263 | if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); 264 | // Build the jump relative instruction to the escape island 265 | #endif 266 | 267 | 268 | #if defined(__i386__) || defined(__x86_64__) 269 | if (!err) { 270 | uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5); 271 | addressOffset = OSSwapInt32(addressOffset); 272 | 273 | jumpRelativeInstruction |= 0xE900000000000000LL; 274 | jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24; 275 | jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction); 276 | } 277 | #endif 278 | 279 | // Optionally allocate & return the reentry island. This may contain relocated 280 | // jmp instructions and so has all the same addressing reachability requirements 281 | // the escape island has to the original function, except the escape island is 282 | // technically our original function. 283 | BranchIsland *reentryIsland = NULL; 284 | if( !err && originalFunctionReentryIsland ) { 285 | err = allocateBranchIsland( &reentryIsland, kAllocateHigh, escapeIsland); 286 | if( !err ) 287 | *originalFunctionReentryIsland = reentryIsland; 288 | } 289 | 290 | #if defined(__ppc__) || defined(__POWERPC__) 291 | // Atomically: 292 | // o If the reentry island was allocated: 293 | // o Insert the original instruction into the reentry island. 294 | // o Target the reentry island at the 2nd instruction of the 295 | // original function. 296 | // o Replace the original instruction with the branch absolute. 297 | if( !err ) { 298 | int escapeIslandEngaged = false; 299 | do { 300 | if( reentryIsland ) 301 | err = setBranchIslandTarget( reentryIsland, 302 | (void*) (originalFunctionPtr+1), originalInstruction ); 303 | if( !err ) { 304 | escapeIslandEngaged = CompareAndSwap( originalInstruction, 305 | branchAbsoluteInstruction, 306 | (UInt32*)originalFunctionPtr ); 307 | if( !escapeIslandEngaged ) { 308 | // Someone replaced the instruction out from under us, 309 | // re-read the instruction, make sure it's still not 310 | // 'mfctr' and try again. 311 | originalInstruction = *originalFunctionPtr; 312 | if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction) 313 | err = err_cannot_override; 314 | } 315 | } 316 | } while( !err && !escapeIslandEngaged ); 317 | } 318 | #elif defined(__i386__) || defined(__x86_64__) 319 | // Atomically: 320 | // o If the reentry island was allocated: 321 | // o Insert the original instructions into the reentry island. 322 | // o Target the reentry island at the first non-replaced 323 | // instruction of the original function. 324 | // o Replace the original first instructions with the jump relative. 325 | // 326 | // Note that on i386, we do not support someone else changing the code under our feet 327 | if ( !err ) { 328 | fixupInstructions(originalFunctionPtr, reentryIsland, originalInstructions, 329 | originalInstructionCount, originalInstructionSizes ); 330 | 331 | if( reentryIsland ) 332 | err = setBranchIslandTarget_i386( reentryIsland, 333 | (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions ); 334 | // try making islands executable before planting the jmp 335 | #if defined(__x86_64__) || defined(__i386__) 336 | if( !err ) 337 | err = makeIslandExecutable(escapeIsland); 338 | if( !err && reentryIsland ) 339 | err = makeIslandExecutable(reentryIsland); 340 | #endif 341 | if ( !err ) 342 | atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction); 343 | mach_error_t prot_err = err_none; 344 | prot_err = vm_protect( mach_task_self(), 345 | (vm_address_t) originalFunctionPtr, 8, false, 346 | (VM_PROT_READ | VM_PROT_EXECUTE) ); 347 | if(prot_err) fprintf(stderr, "err = %x %s:%d\n", prot_err, __FILE__, __LINE__); 348 | } 349 | #endif 350 | 351 | // Clean up on error. 352 | if( err ) { 353 | if( reentryIsland ) 354 | freeBranchIsland( reentryIsland ); 355 | if( escapeIsland ) 356 | freeBranchIsland( escapeIsland ); 357 | } 358 | 359 | return err; 360 | } 361 | 362 | /******************************************************************************* 363 | * 364 | * Implementation 365 | * 366 | *******************************************************************************/ 367 | #pragma mark - 368 | #pragma mark (Implementation) 369 | 370 | /******************************************************************************* 371 | Implementation: Allocates memory for a branch island. 372 | 373 | @param island <- The allocated island. 374 | @param allocateHigh -> Whether to allocate the island at the end of the 375 | address space (for use with the branch absolute 376 | instruction). 377 | @result <- mach_error_t 378 | 379 | ***************************************************************************/ 380 | 381 | mach_error_t 382 | allocateBranchIsland( 383 | BranchIsland **island, 384 | int allocateHigh, 385 | void *originalFunctionAddress) 386 | { 387 | assert( island ); 388 | 389 | mach_error_t err = err_none; 390 | 391 | if( allocateHigh ) { 392 | assert( sizeof( BranchIsland ) <= PAGE_SIZE ); 393 | vm_address_t page = 0; 394 | #if defined(__i386__) 395 | err = vm_allocate( mach_task_self(), &page, PAGE_SIZE, VM_FLAGS_ANYWHERE ); 396 | if( err == err_none ) 397 | *island = (BranchIsland*) page; 398 | #else 399 | 400 | #if defined(__ppc__) || defined(__POWERPC__) 401 | vm_address_t first = 0xfeffffff; 402 | vm_address_t last = 0xfe000000 + PAGE_SIZE; 403 | #elif defined(__x86_64__) 404 | // 64-bit ASLR is in bits 13-28 405 | vm_address_t first = ((uint64_t)originalFunctionAddress & ~( (0xFUL << 28) | (PAGE_SIZE - 1) ) ) | (0x1UL << 31); 406 | vm_address_t last = (uint64_t)originalFunctionAddress & ~((0x1UL << 32) - 1); 407 | #endif 408 | 409 | page = first; 410 | int allocated = 0; 411 | vm_map_t task_self = mach_task_self(); 412 | 413 | while( !err && !allocated && page != last ) { 414 | 415 | err = vm_allocate( task_self, &page, PAGE_SIZE, 0 ); 416 | if( err == err_none ) 417 | allocated = 1; 418 | else if( err == KERN_NO_SPACE ) { 419 | #if defined(__x86_64__) 420 | page -= PAGE_SIZE; 421 | #else 422 | page += PAGE_SIZE; 423 | #endif 424 | err = err_none; 425 | } 426 | } 427 | if( allocated ) 428 | *island = (BranchIsland*) page; 429 | else if( !allocated && !err ) 430 | err = KERN_NO_SPACE; 431 | #endif 432 | } else { 433 | void *block = malloc( sizeof( BranchIsland ) ); 434 | if( block ) 435 | *island = block; 436 | else 437 | err = KERN_NO_SPACE; 438 | } 439 | if( !err ) 440 | (**island).allocatedHigh = allocateHigh; 441 | 442 | return err; 443 | } 444 | 445 | /******************************************************************************* 446 | Implementation: Deallocates memory for a branch island. 447 | 448 | @param island -> The island to deallocate. 449 | @result <- mach_error_t 450 | 451 | ***************************************************************************/ 452 | 453 | mach_error_t 454 | freeBranchIsland( 455 | BranchIsland *island ) 456 | { 457 | assert( island ); 458 | assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] ); 459 | assert( island->allocatedHigh ); 460 | 461 | mach_error_t err = err_none; 462 | 463 | if( island->allocatedHigh ) { 464 | assert( sizeof( BranchIsland ) <= PAGE_SIZE ); 465 | err = vm_deallocate(mach_task_self(), (vm_address_t) island, PAGE_SIZE ); 466 | } else { 467 | free( island ); 468 | } 469 | 470 | return err; 471 | } 472 | 473 | /******************************************************************************* 474 | Implementation: Sets the branch island's target, with an optional 475 | instruction. 476 | 477 | @param island -> The branch island to insert target into. 478 | @param branchTo -> The address of the target. 479 | @param instruction -> Optional instruction to execute prior to branch. Set 480 | to zero for nop. 481 | @result <- mach_error_t 482 | 483 | ***************************************************************************/ 484 | #if defined(__ppc__) || defined(__POWERPC__) 485 | mach_error_t 486 | setBranchIslandTarget( 487 | BranchIsland *island, 488 | const void *branchTo, 489 | long instruction ) 490 | { 491 | // Copy over the template code. 492 | bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); 493 | 494 | // Fill in the address. 495 | ((short*)island->instructions)[kAddressLo] = ((long) branchTo) & 0x0000FFFF; 496 | ((short*)island->instructions)[kAddressHi] 497 | = (((long) branchTo) >> 16) & 0x0000FFFF; 498 | 499 | // Fill in the (optional) instuction. 500 | if( instruction != 0 ) { 501 | ((short*)island->instructions)[kInstructionLo] 502 | = instruction & 0x0000FFFF; 503 | ((short*)island->instructions)[kInstructionHi] 504 | = (instruction >> 16) & 0x0000FFFF; 505 | } 506 | 507 | //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) ); 508 | msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); 509 | 510 | return err_none; 511 | } 512 | #endif 513 | 514 | #if defined(__i386__) 515 | mach_error_t 516 | setBranchIslandTarget_i386( 517 | BranchIsland *island, 518 | const void *branchTo, 519 | char* instructions ) 520 | { 521 | 522 | // Copy over the template code. 523 | bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); 524 | 525 | // copy original instructions 526 | if (instructions) { 527 | bcopy (instructions, island->instructions + kInstructions, kOriginalInstructionsSize); 528 | } 529 | 530 | // Fill in the address. 531 | int32_t addressOffset = (char *)branchTo - (island->instructions + kJumpAddress + 4); 532 | *((int32_t *)(island->instructions + kJumpAddress)) = addressOffset; 533 | 534 | msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); 535 | return err_none; 536 | } 537 | 538 | #elif defined(__x86_64__) 539 | mach_error_t 540 | setBranchIslandTarget_i386( 541 | BranchIsland *island, 542 | const void *branchTo, 543 | char* instructions ) 544 | { 545 | // Copy over the template code. 546 | bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); 547 | 548 | // Copy original instructions. 549 | if (instructions) { 550 | bcopy (instructions, island->instructions, kOriginalInstructionsSize); 551 | } 552 | 553 | // Fill in the address. 554 | *((uint64_t *)(island->instructions + kJumpAddress)) = (uint64_t)branchTo; 555 | msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); 556 | 557 | return err_none; 558 | } 559 | #endif 560 | 561 | 562 | #if defined(__i386__) || defined(__x86_64__) 563 | static Boolean 564 | eatKnownInstructions( 565 | unsigned char *code, 566 | uint64_t *newInstruction, 567 | int *howManyEaten, 568 | char *originalInstructions, 569 | int *originalInstructionCount, 570 | uint8_t *originalInstructionSizes ) 571 | { 572 | Boolean allInstructionsKnown = true; 573 | int totalEaten = 0; 574 | int remainsToEat = 5; // a JMP instruction takes 5 bytes 575 | int instructionIndex = 0; 576 | ud_t ud_obj; 577 | 578 | if (howManyEaten) *howManyEaten = 0; 579 | if (originalInstructionCount) *originalInstructionCount = 0; 580 | ud_init(&ud_obj); 581 | #if defined(__i386__) 582 | ud_set_mode(&ud_obj, 32); 583 | #else 584 | ud_set_mode(&ud_obj, 64); 585 | #endif 586 | ud_set_input_buffer(&ud_obj, code, 64); // Assume that 'code' points to at least 64bytes of data. 587 | while (remainsToEat > 0) { 588 | if (!ud_disassemble(&ud_obj)) { 589 | allInstructionsKnown = false; 590 | fprintf(stderr, "mach_override: some instructions unknown! Need to update libudis86\n"); 591 | break; 592 | } 593 | 594 | // At this point, we've matched curInstr 595 | int eaten = ud_insn_len(&ud_obj); 596 | remainsToEat -= eaten; 597 | totalEaten += eaten; 598 | 599 | if (originalInstructionSizes) originalInstructionSizes[instructionIndex] = eaten; 600 | instructionIndex += 1; 601 | if (originalInstructionCount) *originalInstructionCount = instructionIndex; 602 | } 603 | 604 | 605 | if (howManyEaten) *howManyEaten = totalEaten; 606 | 607 | if (originalInstructions) { 608 | Boolean enoughSpaceForOriginalInstructions = (totalEaten < kOriginalInstructionsSize); 609 | 610 | if (enoughSpaceForOriginalInstructions) { 611 | memset(originalInstructions, 0x90 /* NOP */, kOriginalInstructionsSize); // fill instructions with NOP 612 | bcopy(code, originalInstructions, totalEaten); 613 | } else { 614 | // printf ("Not enough space in island to store original instructions. Adapt the island definition and kOriginalInstructionsSize\n"); 615 | return false; 616 | } 617 | } 618 | 619 | if (allInstructionsKnown) { 620 | // save last 3 bytes of first 64bits of codre we'll replace 621 | uint64_t currentFirst64BitsOfCode = *((uint64_t *)code); 622 | currentFirst64BitsOfCode = OSSwapInt64(currentFirst64BitsOfCode); // back to memory representation 623 | currentFirst64BitsOfCode &= 0x0000000000FFFFFFLL; 624 | 625 | // keep only last 3 instructions bytes, first 5 will be replaced by JMP instr 626 | *newInstruction &= 0xFFFFFFFFFF000000LL; // clear last 3 bytes 627 | *newInstruction |= (currentFirst64BitsOfCode & 0x0000000000FFFFFFLL); // set last 3 bytes 628 | } 629 | 630 | return allInstructionsKnown; 631 | } 632 | 633 | static void 634 | fixupInstructions( 635 | void *originalFunction, 636 | void *escapeIsland, 637 | void *instructionsToFix, 638 | int instructionCount, 639 | uint8_t *instructionSizes ) 640 | { 641 | int index; 642 | for (index = 0;index < instructionCount;index += 1) 643 | { 644 | if (*(uint8_t*)instructionsToFix == 0xE9) // 32-bit jump relative 645 | { 646 | uint32_t offset = (uintptr_t)originalFunction - (uintptr_t)escapeIsland; 647 | uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 1); 648 | *jumpOffsetPtr += offset; 649 | } 650 | 651 | originalFunction = (void*)((uintptr_t)originalFunction + instructionSizes[index]); 652 | escapeIsland = (void*)((uintptr_t)escapeIsland + instructionSizes[index]); 653 | instructionsToFix = (void*)((uintptr_t)instructionsToFix + instructionSizes[index]); 654 | } 655 | } 656 | 657 | #if defined(__i386__) 658 | __asm( 659 | ".text;" 660 | ".align 2, 0x90;" 661 | "_atomic_mov64:;" 662 | " pushl %ebp;" 663 | " movl %esp, %ebp;" 664 | " pushl %esi;" 665 | " pushl %ebx;" 666 | " pushl %ecx;" 667 | " pushl %eax;" 668 | " pushl %edx;" 669 | 670 | // atomic push of value to an address 671 | // we use cmpxchg8b, which compares content of an address with 672 | // edx:eax. If they are equal, it atomically puts 64bit value 673 | // ecx:ebx in address. 674 | // We thus put contents of address in edx:eax to force ecx:ebx 675 | // in address 676 | " mov 8(%ebp), %esi;" // esi contains target address 677 | " mov 12(%ebp), %ebx;" 678 | " mov 16(%ebp), %ecx;" // ecx:ebx now contains value to put in target address 679 | " mov (%esi), %eax;" 680 | " mov 4(%esi), %edx;" // edx:eax now contains value currently contained in target address 681 | " lock; cmpxchg8b (%esi);" // atomic move. 682 | 683 | // restore registers 684 | " popl %edx;" 685 | " popl %eax;" 686 | " popl %ecx;" 687 | " popl %ebx;" 688 | " popl %esi;" 689 | " popl %ebp;" 690 | " ret" 691 | ); 692 | #elif defined(__x86_64__) 693 | void atomic_mov64( 694 | uint64_t *targetAddress, 695 | uint64_t value ) 696 | { 697 | *targetAddress = value; 698 | } 699 | #endif 700 | #endif 701 | -------------------------------------------------------------------------------- /SwiftMachOverride/mach/mach_override.h: -------------------------------------------------------------------------------- 1 | // mach_override.h semver:1.2.0 2 | // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/mach_override 5 | 6 | #ifndef _mach_override_ 7 | #define _mach_override_ 8 | 9 | #include 10 | #include 11 | 12 | #define err_cannot_override (err_local|1) 13 | 14 | __BEGIN_DECLS 15 | 16 | /**************************************************************************************** 17 | Dynamically overrides the function implementation referenced by 18 | originalFunctionAddress with the implentation pointed to by overrideFunctionAddress. 19 | Optionally returns a pointer to a "reentry island" which, if jumped to, will resume 20 | the original implementation. 21 | 22 | @param originalFunctionAddress -> Required address of the function to 23 | override (with overrideFunctionAddress). 24 | @param overrideFunctionAddress -> Required address to the overriding 25 | function. 26 | @param originalFunctionReentryIsland <- Optional pointer to pointer to the 27 | reentry island. Can be NULL. 28 | @result <- err_cannot_override if the original 29 | function's implementation begins with 30 | the 'mfctr' instruction. 31 | 32 | ************************************************************************************/ 33 | 34 | mach_error_t 35 | mach_override_ptr( 36 | void *originalFunctionAddress, 37 | const void *overrideFunctionAddress, 38 | void **originalFunctionReentryIsland ); 39 | 40 | __END_DECLS 41 | 42 | /**************************************************************************************** 43 | If you're using C++ this macro will ease the tedium of typedef'ing, naming, keeping 44 | track of reentry islands and defining your override code. See test_mach_override.cp 45 | for example usage. 46 | 47 | ************************************************************************************/ 48 | 49 | #ifdef __cplusplus 50 | #define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR ) \ 51 | { \ 52 | static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS; \ 53 | static bool ORIGINAL_FUNCTION_NAME##_overriden = false; \ 54 | class mach_override_class__##ORIGINAL_FUNCTION_NAME { \ 55 | public: \ 56 | static kern_return_t override(void *originalFunctionPtr) { \ 57 | kern_return_t result = err_none; \ 58 | if (!ORIGINAL_FUNCTION_NAME##_overriden) { \ 59 | ORIGINAL_FUNCTION_NAME##_overriden = true; \ 60 | result = mach_override_ptr( (void*)originalFunctionPtr, \ 61 | (void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement, \ 62 | (void**)&ORIGINAL_FUNCTION_NAME##_reenter ); \ 63 | } \ 64 | return result; \ 65 | } \ 66 | static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS { 67 | 68 | #define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME ) \ 69 | } \ 70 | }; \ 71 | \ 72 | err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME); \ 73 | } 74 | #endif 75 | 76 | #endif // _mach_override_ 77 | -------------------------------------------------------------------------------- /SwiftMachOverride/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // SwiftMachOverride 4 | // 5 | // Created by Fabio Lombardo on 26/05/2019. 6 | // Copyright © 2019 Fabio Lombardo. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func original() { 12 | print("original function"); 13 | } 14 | 15 | func exchanged() { 16 | print("exchanged function"); 17 | } 18 | 19 | class TestClass { 20 | func original() { 21 | print("original class function"); 22 | } 23 | 24 | func exchanged() { 25 | print("exchanged class function"); 26 | } 27 | } 28 | 29 | 30 | // -- CODE 31 | override() 32 | override_instance_method() 33 | 34 | original() 35 | let a = TestClass() 36 | a.original() 37 | -------------------------------------------------------------------------------- /SwiftMachOverride/override.c: -------------------------------------------------------------------------------- 1 | // 2 | // override.c 3 | // SwiftMachOverride 4 | // 5 | // Created by Fabio Lombardo on 26/05/2019. 6 | // Copyright © 2019 Fabio Lombardo. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include "mach_override.h" 12 | 13 | void override() 14 | { 15 | void (*landing)(void * par); 16 | void (*originalFunctionAddress)(void * par); 17 | const void (*overrideFunctionAddress)(void * par); 18 | 19 | *(void **) (&originalFunctionAddress) = dlsym(RTLD_DEFAULT, "$s17SwiftMachOverride8originalyyF"); 20 | *(void **) (&overrideFunctionAddress) = dlsym(RTLD_DEFAULT, "$s17SwiftMachOverride9exchangedyyF"); 21 | 22 | mach_override_ptr(originalFunctionAddress, overrideFunctionAddress, (void**)&landing); 23 | } 24 | 25 | void override_instance_method() 26 | { 27 | void (*landing)(void * par); 28 | void (*originalFunctionAddress)(void * par); 29 | const void (*overrideFunctionAddress)(void * par); 30 | 31 | *(void **) (&originalFunctionAddress) = dlsym(RTLD_DEFAULT,"$s17SwiftMachOverride9TestClassC8originalyyF"); 32 | *(void **) (&overrideFunctionAddress) = dlsym(RTLD_DEFAULT,"$s17SwiftMachOverride9TestClassC9exchangedyyF"); 33 | 34 | mach_override_ptr(originalFunctionAddress, overrideFunctionAddress, (void**)&landing); 35 | } 36 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ### Note: this example has been updated for Swift 5 2 | 3 | #### This is an example on how to use mach_override in a Swift Application. 4 | More explanations at this post: http://www.lombax.it/?p=321 5 | 6 | For details, look inside `main.swift`, there are: 7 | 8 | 2 plain function 9 | a class called `TestClass` with 2 instance methods 10 | 11 | Before calling the two functions, I call 12 | 13 | override() 14 | override_instance_method() 15 | 16 | that are declared inside the `override.c` file. 17 | 18 | These functions replaces the implementation of: 19 | 20 | - the plain function `original()` with `exchanged()` 21 | - the instance method of `TestClass` : `original()` with `exchanged()` 22 | 23 | to see in action, simply execute the app. 24 | 25 | Comment 26 | 27 | //override() 28 | //override_instance_method() 29 | 30 | to come back to the original implementation 31 | --------------------------------------------------------------------------------