├── MemoryPatcher.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── jiangnan.xcuserdatad │ └── xcschemes │ ├── xcschememanagement(1).plist │ └── xcschememanagement.plist ├── MemoryPatcher ├── Info.plist ├── MemoryPatcher.h └── MemoryPatcher.m ├── MemoryPatcherTests ├── Info.plist ├── MemoryPatcherTests(1).m └── MemoryPatcherTests.m └── README.md /MemoryPatcher.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9C655962236D971300F326FF /* MemoryPatcher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C655958236D971300F326FF /* MemoryPatcher.framework */; }; 11 | 9C655967236D971300F326FF /* MemoryPatcherTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C655966236D971300F326FF /* MemoryPatcherTests.m */; }; 12 | 9C655974236D973700F326FF /* MemoryPatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C655972236D973700F326FF /* MemoryPatcher.h */; }; 13 | 9C655975236D973700F326FF /* MemoryPatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C655973236D973700F326FF /* MemoryPatcher.m */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXContainerItemProxy section */ 17 | 9C655963236D971300F326FF /* PBXContainerItemProxy */ = { 18 | isa = PBXContainerItemProxy; 19 | containerPortal = 9C65594F236D971300F326FF /* Project object */; 20 | proxyType = 1; 21 | remoteGlobalIDString = 9C655957236D971300F326FF; 22 | remoteInfo = MemoryPatcher; 23 | }; 24 | /* End PBXContainerItemProxy section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 9C655958236D971300F326FF /* MemoryPatcher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MemoryPatcher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 9C65595C236D971300F326FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | 9C655961236D971300F326FF /* MemoryPatcherTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MemoryPatcherTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 9C655966236D971300F326FF /* MemoryPatcherTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MemoryPatcherTests.m; sourceTree = ""; }; 31 | 9C655968236D971300F326FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 9C655972236D973700F326FF /* MemoryPatcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MemoryPatcher.h; sourceTree = SOURCE_ROOT; }; 33 | 9C655973236D973700F326FF /* MemoryPatcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MemoryPatcher.m; sourceTree = ""; }; 34 | /* End PBXFileReference section */ 35 | 36 | /* Begin PBXFrameworksBuildPhase section */ 37 | 9C655955236D971300F326FF /* Frameworks */ = { 38 | isa = PBXFrameworksBuildPhase; 39 | buildActionMask = 2147483647; 40 | files = ( 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | 9C65595E236D971300F326FF /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 9C655962236D971300F326FF /* MemoryPatcher.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 9C65594E236D971300F326FF = { 56 | isa = PBXGroup; 57 | children = ( 58 | 9C65595A236D971300F326FF /* MemoryPatcher */, 59 | 9C655965236D971300F326FF /* MemoryPatcherTests */, 60 | 9C655959236D971300F326FF /* Products */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | 9C655959236D971300F326FF /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 9C655958236D971300F326FF /* MemoryPatcher.framework */, 68 | 9C655961236D971300F326FF /* MemoryPatcherTests.xctest */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | 9C65595A236D971300F326FF /* MemoryPatcher */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 9C655972236D973700F326FF /* MemoryPatcher.h */, 77 | 9C655973236D973700F326FF /* MemoryPatcher.m */, 78 | 9C65595C236D971300F326FF /* Info.plist */, 79 | ); 80 | path = MemoryPatcher; 81 | sourceTree = ""; 82 | }; 83 | 9C655965236D971300F326FF /* MemoryPatcherTests */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 9C655966236D971300F326FF /* MemoryPatcherTests.m */, 87 | 9C655968236D971300F326FF /* Info.plist */, 88 | ); 89 | path = MemoryPatcherTests; 90 | sourceTree = ""; 91 | }; 92 | /* End PBXGroup section */ 93 | 94 | /* Begin PBXHeadersBuildPhase section */ 95 | 9C655953236D971300F326FF /* Headers */ = { 96 | isa = PBXHeadersBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | 9C655974236D973700F326FF /* MemoryPatcher.h in Headers */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | /* End PBXHeadersBuildPhase section */ 104 | 105 | /* Begin PBXNativeTarget section */ 106 | 9C655957236D971300F326FF /* MemoryPatcher */ = { 107 | isa = PBXNativeTarget; 108 | buildConfigurationList = 9C65596C236D971300F326FF /* Build configuration list for PBXNativeTarget "MemoryPatcher" */; 109 | buildPhases = ( 110 | 9C655953236D971300F326FF /* Headers */, 111 | 9C655954236D971300F326FF /* Sources */, 112 | 9C655955236D971300F326FF /* Frameworks */, 113 | 9C655956236D971300F326FF /* Resources */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = MemoryPatcher; 120 | productName = MemoryPatcher; 121 | productReference = 9C655958236D971300F326FF /* MemoryPatcher.framework */; 122 | productType = "com.apple.product-type.framework"; 123 | }; 124 | 9C655960236D971300F326FF /* MemoryPatcherTests */ = { 125 | isa = PBXNativeTarget; 126 | buildConfigurationList = 9C65596F236D971300F326FF /* Build configuration list for PBXNativeTarget "MemoryPatcherTests" */; 127 | buildPhases = ( 128 | 9C65595D236D971300F326FF /* Sources */, 129 | 9C65595E236D971300F326FF /* Frameworks */, 130 | 9C65595F236D971300F326FF /* Resources */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | 9C655964236D971300F326FF /* PBXTargetDependency */, 136 | ); 137 | name = MemoryPatcherTests; 138 | productName = MemoryPatcherTests; 139 | productReference = 9C655961236D971300F326FF /* MemoryPatcherTests.xctest */; 140 | productType = "com.apple.product-type.bundle.unit-test"; 141 | }; 142 | /* End PBXNativeTarget section */ 143 | 144 | /* Begin PBXProject section */ 145 | 9C65594F236D971300F326FF /* Project object */ = { 146 | isa = PBXProject; 147 | attributes = { 148 | LastUpgradeCheck = 1030; 149 | ORGANIZATIONNAME = "江南"; 150 | TargetAttributes = { 151 | 9C655957236D971300F326FF = { 152 | CreatedOnToolsVersion = 10.3; 153 | }; 154 | 9C655960236D971300F326FF = { 155 | CreatedOnToolsVersion = 10.3; 156 | }; 157 | }; 158 | }; 159 | buildConfigurationList = 9C655952236D971300F326FF /* Build configuration list for PBXProject "MemoryPatcher" */; 160 | compatibilityVersion = "Xcode 9.3"; 161 | developmentRegion = en; 162 | hasScannedForEncodings = 0; 163 | knownRegions = ( 164 | en, 165 | ); 166 | mainGroup = 9C65594E236D971300F326FF; 167 | productRefGroup = 9C655959236D971300F326FF /* Products */; 168 | projectDirPath = ""; 169 | projectRoot = ""; 170 | targets = ( 171 | 9C655957236D971300F326FF /* MemoryPatcher */, 172 | 9C655960236D971300F326FF /* MemoryPatcherTests */, 173 | ); 174 | }; 175 | /* End PBXProject section */ 176 | 177 | /* Begin PBXResourcesBuildPhase section */ 178 | 9C655956236D971300F326FF /* Resources */ = { 179 | isa = PBXResourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | ); 183 | runOnlyForDeploymentPostprocessing = 0; 184 | }; 185 | 9C65595F236D971300F326FF /* Resources */ = { 186 | isa = PBXResourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXResourcesBuildPhase section */ 193 | 194 | /* Begin PBXSourcesBuildPhase section */ 195 | 9C655954236D971300F326FF /* Sources */ = { 196 | isa = PBXSourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 9C655975236D973700F326FF /* MemoryPatcher.m in Sources */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | 9C65595D236D971300F326FF /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 9C655967236D971300F326FF /* MemoryPatcherTests.m in Sources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXSourcesBuildPhase section */ 212 | 213 | /* Begin PBXTargetDependency section */ 214 | 9C655964236D971300F326FF /* PBXTargetDependency */ = { 215 | isa = PBXTargetDependency; 216 | target = 9C655957236D971300F326FF /* MemoryPatcher */; 217 | targetProxy = 9C655963236D971300F326FF /* PBXContainerItemProxy */; 218 | }; 219 | /* End PBXTargetDependency section */ 220 | 221 | /* Begin XCBuildConfiguration section */ 222 | 9C65596A236D971300F326FF /* Debug */ = { 223 | isa = XCBuildConfiguration; 224 | buildSettings = { 225 | ALWAYS_SEARCH_USER_PATHS = NO; 226 | CLANG_ANALYZER_NONNULL = YES; 227 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 229 | CLANG_CXX_LIBRARY = "libc++"; 230 | CLANG_ENABLE_MODULES = YES; 231 | CLANG_ENABLE_OBJC_ARC = YES; 232 | CLANG_ENABLE_OBJC_WEAK = YES; 233 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 234 | CLANG_WARN_BOOL_CONVERSION = YES; 235 | CLANG_WARN_COMMA = YES; 236 | CLANG_WARN_CONSTANT_CONVERSION = YES; 237 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 238 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 239 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 240 | CLANG_WARN_EMPTY_BODY = YES; 241 | CLANG_WARN_ENUM_CONVERSION = YES; 242 | CLANG_WARN_INFINITE_RECURSION = YES; 243 | CLANG_WARN_INT_CONVERSION = YES; 244 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 245 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 246 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 247 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 248 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 249 | CLANG_WARN_STRICT_PROTOTYPES = YES; 250 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 251 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 252 | CLANG_WARN_UNREACHABLE_CODE = YES; 253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 254 | CODE_SIGN_IDENTITY = "iPhone Developer"; 255 | COPY_PHASE_STRIP = NO; 256 | CURRENT_PROJECT_VERSION = 1; 257 | DEBUG_INFORMATION_FORMAT = dwarf; 258 | ENABLE_STRICT_OBJC_MSGSEND = YES; 259 | ENABLE_TESTABILITY = YES; 260 | GCC_C_LANGUAGE_STANDARD = gnu11; 261 | GCC_DYNAMIC_NO_PIC = NO; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_OPTIMIZATION_LEVEL = 0; 264 | GCC_PREPROCESSOR_DEFINITIONS = ( 265 | "DEBUG=1", 266 | "$(inherited)", 267 | ); 268 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 269 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 270 | GCC_WARN_UNDECLARED_SELECTOR = YES; 271 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 272 | GCC_WARN_UNUSED_FUNCTION = YES; 273 | GCC_WARN_UNUSED_VARIABLE = YES; 274 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 275 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 276 | MTL_FAST_MATH = YES; 277 | ONLY_ACTIVE_ARCH = YES; 278 | SDKROOT = iphoneos; 279 | VERSIONING_SYSTEM = "apple-generic"; 280 | VERSION_INFO_PREFIX = ""; 281 | }; 282 | name = Debug; 283 | }; 284 | 9C65596B236D971300F326FF /* Release */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ALWAYS_SEARCH_USER_PATHS = NO; 288 | CLANG_ANALYZER_NONNULL = YES; 289 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_ENABLE_OBJC_WEAK = YES; 295 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 296 | CLANG_WARN_BOOL_CONVERSION = YES; 297 | CLANG_WARN_COMMA = YES; 298 | CLANG_WARN_CONSTANT_CONVERSION = YES; 299 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 301 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 302 | CLANG_WARN_EMPTY_BODY = YES; 303 | CLANG_WARN_ENUM_CONVERSION = YES; 304 | CLANG_WARN_INFINITE_RECURSION = YES; 305 | CLANG_WARN_INT_CONVERSION = YES; 306 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 307 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 308 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 310 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 311 | CLANG_WARN_STRICT_PROTOTYPES = YES; 312 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 313 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 314 | CLANG_WARN_UNREACHABLE_CODE = YES; 315 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 316 | CODE_SIGN_IDENTITY = "iPhone Developer"; 317 | COPY_PHASE_STRIP = NO; 318 | CURRENT_PROJECT_VERSION = 1; 319 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 320 | ENABLE_NS_ASSERTIONS = NO; 321 | ENABLE_STRICT_OBJC_MSGSEND = YES; 322 | GCC_C_LANGUAGE_STANDARD = gnu11; 323 | GCC_NO_COMMON_BLOCKS = YES; 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 331 | MTL_ENABLE_DEBUG_INFO = NO; 332 | MTL_FAST_MATH = YES; 333 | SDKROOT = iphoneos; 334 | VALIDATE_PRODUCT = YES; 335 | VERSIONING_SYSTEM = "apple-generic"; 336 | VERSION_INFO_PREFIX = ""; 337 | }; 338 | name = Release; 339 | }; 340 | 9C65596D236D971300F326FF /* Debug */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | CODE_SIGN_IDENTITY = ""; 344 | CODE_SIGN_STYLE = Automatic; 345 | DEFINES_MODULE = YES; 346 | DYLIB_COMPATIBILITY_VERSION = 1; 347 | DYLIB_CURRENT_VERSION = 1; 348 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 349 | INFOPLIST_FILE = MemoryPatcher/Info.plist; 350 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 351 | LD_RUNPATH_SEARCH_PATHS = ( 352 | "$(inherited)", 353 | "@executable_path/Frameworks", 354 | "@loader_path/Frameworks", 355 | ); 356 | PRODUCT_BUNDLE_IDENTIFIER = com.jn.cc.MemoryPatcher; 357 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 358 | SKIP_INSTALL = YES; 359 | TARGETED_DEVICE_FAMILY = "1,2"; 360 | }; 361 | name = Debug; 362 | }; 363 | 9C65596E236D971300F326FF /* Release */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | CODE_SIGN_IDENTITY = ""; 367 | CODE_SIGN_STYLE = Automatic; 368 | DEFINES_MODULE = YES; 369 | DYLIB_COMPATIBILITY_VERSION = 1; 370 | DYLIB_CURRENT_VERSION = 1; 371 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 372 | INFOPLIST_FILE = MemoryPatcher/Info.plist; 373 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 374 | LD_RUNPATH_SEARCH_PATHS = ( 375 | "$(inherited)", 376 | "@executable_path/Frameworks", 377 | "@loader_path/Frameworks", 378 | ); 379 | PRODUCT_BUNDLE_IDENTIFIER = com.jn.cc.MemoryPatcher; 380 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 381 | SKIP_INSTALL = YES; 382 | TARGETED_DEVICE_FAMILY = "1,2"; 383 | }; 384 | name = Release; 385 | }; 386 | 9C655970236D971300F326FF /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | CODE_SIGN_STYLE = Automatic; 390 | INFOPLIST_FILE = MemoryPatcherTests/Info.plist; 391 | LD_RUNPATH_SEARCH_PATHS = ( 392 | "$(inherited)", 393 | "@executable_path/Frameworks", 394 | "@loader_path/Frameworks", 395 | ); 396 | PRODUCT_BUNDLE_IDENTIFIER = com.jn.cc.MemoryPatcherTests; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | TARGETED_DEVICE_FAMILY = "1,2"; 399 | }; 400 | name = Debug; 401 | }; 402 | 9C655971236D971300F326FF /* Release */ = { 403 | isa = XCBuildConfiguration; 404 | buildSettings = { 405 | CODE_SIGN_STYLE = Automatic; 406 | INFOPLIST_FILE = MemoryPatcherTests/Info.plist; 407 | LD_RUNPATH_SEARCH_PATHS = ( 408 | "$(inherited)", 409 | "@executable_path/Frameworks", 410 | "@loader_path/Frameworks", 411 | ); 412 | PRODUCT_BUNDLE_IDENTIFIER = com.jn.cc.MemoryPatcherTests; 413 | PRODUCT_NAME = "$(TARGET_NAME)"; 414 | TARGETED_DEVICE_FAMILY = "1,2"; 415 | }; 416 | name = Release; 417 | }; 418 | /* End XCBuildConfiguration section */ 419 | 420 | /* Begin XCConfigurationList section */ 421 | 9C655952236D971300F326FF /* Build configuration list for PBXProject "MemoryPatcher" */ = { 422 | isa = XCConfigurationList; 423 | buildConfigurations = ( 424 | 9C65596A236D971300F326FF /* Debug */, 425 | 9C65596B236D971300F326FF /* Release */, 426 | ); 427 | defaultConfigurationIsVisible = 0; 428 | defaultConfigurationName = Release; 429 | }; 430 | 9C65596C236D971300F326FF /* Build configuration list for PBXNativeTarget "MemoryPatcher" */ = { 431 | isa = XCConfigurationList; 432 | buildConfigurations = ( 433 | 9C65596D236D971300F326FF /* Debug */, 434 | 9C65596E236D971300F326FF /* Release */, 435 | ); 436 | defaultConfigurationIsVisible = 0; 437 | defaultConfigurationName = Release; 438 | }; 439 | 9C65596F236D971300F326FF /* Build configuration list for PBXNativeTarget "MemoryPatcherTests" */ = { 440 | isa = XCConfigurationList; 441 | buildConfigurations = ( 442 | 9C655970236D971300F326FF /* Debug */, 443 | 9C655971236D971300F326FF /* Release */, 444 | ); 445 | defaultConfigurationIsVisible = 0; 446 | defaultConfigurationName = Release; 447 | }; 448 | /* End XCConfigurationList section */ 449 | }; 450 | rootObject = 9C65594F236D971300F326FF /* Project object */; 451 | } 452 | -------------------------------------------------------------------------------- /MemoryPatcher.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MemoryPatcher.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MemoryPatcher.xcodeproj/xcuserdata/jiangnan.xcuserdatad/xcschemes/xcschememanagement(1).plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MemoryPatcher.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MemoryPatcher.xcodeproj/xcuserdata/jiangnan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MemoryPatcher.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MemoryPatcher/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /MemoryPatcher/MemoryPatcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // MemoryPatcher.h 3 | // MemoryPatcher 4 | // 5 | // Created by 江南 on 2019/11/2. 6 | // Copyright © 2019 江南. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MemoryPatcher. 12 | FOUNDATION_EXPORT double MemoryPatcherVersionNumber; 13 | 14 | //! Project version string for MemoryPatcher. 15 | FOUNDATION_EXPORT const unsigned char MemoryPatcherVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /MemoryPatcher/MemoryPatcher.m: -------------------------------------------------------------------------------- 1 | // 2 | // MemoryPatcher.m 3 | // MemoryPatcher 4 | // 5 | // Created by 江南 on 2019/11/2. 6 | // Copyright © 2019 江南. All rights reserved. 7 | // 8 | 9 | #import "MemoryPatcher.h" 10 | #include 11 | #include 12 | #import 13 | typedef struct{ 14 | uint64_t address; 15 | size_t size; 16 | uint64_t value; 17 | }MemoryRestore; 18 | 19 | typedef struct{ 20 | uint64_t offests; 21 | uint64_t bytes; 22 | MemoryRestore restore; 23 | }Patch; 24 | 25 | Patch Patch1; 26 | 27 | 28 | @implementation NSObject (hook) 29 | 30 | 31 | +(void)load{ 32 | 33 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 34 | //构造一个Patch 35 | MemoryRestore orig_value; 36 | orig_value.address = 0; 37 | orig_value.size = 0; 38 | orig_value.value = 0; 39 | 40 | Patch1.offests = 0x101D95DA0; 41 | Patch1.bytes = 0xD65F03C0; 42 | Patch1.restore = orig_value; 43 | 44 | //添加Switch 45 | UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(100, 100, 100, 30)]; 46 | mySwitch.on = NO; 47 | mySwitch.tintColor = [UIColor redColor]; 48 | mySwitch.onTintColor = [UIColor blackColor]; 49 | mySwitch.thumbTintColor = [UIColor blueColor]; 50 | [mySwitch addTarget:self action:@selector(valueChanged:) forControlEvents:(UIControlEventValueChanged)]; 51 | [[UIApplication sharedApplication].keyWindow addSubview:mySwitch]; 52 | MemoryPatch2_64(0x101C4E020,0xD65F03C01E37F000); 53 | MemoryPatch2(0x101C22738,0xD65F03C0); 54 | MemoryPatch2(0x101D96384,0x1E2703E1); 55 | MemoryPatch2(0x1021C81FC,0xD65F03C0); 56 | MemoryPatch2(0x101D9638C,0x1E2703E0); 57 | MemoryPatch2(0x103A43138,0xD503201F); 58 | 59 | 60 | }); 61 | 62 | 63 | 64 | } 65 | 66 | - (void)valueChanged:(UISwitch *)swi{ 67 | 68 | if(swi.isOn){ 69 | //启用Patch 70 | PatchEnabled(Patch1.offests,Patch1.bytes,&Patch1.restore); 71 | }else{ 72 | //恢复内存 73 | PatchDisabled(&Patch1.restore); 74 | } 75 | 76 | } 77 | void MemoryRestored(MemoryRestore *restore); 78 | void MemoryPatch(uint64_t TargetAddr,uint32_t Bytes,MemoryRestore *orig_value); 79 | void MemoryPatch2(uint64_t TargetAddr,uint32_t Bytes); 80 | void MemoryPatch64(uint64_t TargetAddr,uint64_t Bytes,MemoryRestore *orig_value); 81 | void MemoryPatch2_64(uint64_t TargetAddr,uint64_t Bytes); 82 | void PatchEnabled(uint64_t TargetAddr,uint64_t Bytes,MemoryRestore *orig_value); 83 | void PatchDisabled(MemoryRestore *restore); 84 | 85 | void PatchDisabled(MemoryRestore *restore){ 86 | 87 | MemoryRestored(restore); 88 | 89 | } 90 | 91 | void MemoryRestored(MemoryRestore *restore){ 92 | 93 | int result = vm_protect(mach_task_self(),(vm_address_t)restore->address,restore->size,0,19); 94 | NSLog(@"------restore.address is %0llX\nrestore value is %llX",restore->address,restore->value); 95 | memcpy((void *)restore->address,&restore->value,restore->size); 96 | result = vm_protect(mach_task_self(),(vm_address_t)restore->address,restore->size,0,VM_PROT_READ | VM_PROT_EXECUTE); 97 | NSLog(@"-----Restored Successfully"); 98 | 99 | } 100 | 101 | void PatchEnabled(uint64_t TargetAddr,uint64_t Bytes,MemoryRestore *orig_value){ 102 | if(Bytes <= 0xFFFFFFFF){ 103 | 104 | MemoryPatch(TargetAddr,(uint32_t)Bytes,orig_value); 105 | 106 | }else{ 107 | 108 | MemoryPatch64(TargetAddr,Bytes,orig_value); 109 | 110 | 111 | } 112 | 113 | } 114 | 115 | void MemoryPatch(uint64_t TargetAddr,uint32_t Bytes,MemoryRestore *orig_value){ 116 | 117 | uint64_t ASLR = _dyld_get_image_vmaddr_slide(0); 118 | uint64_t real_address = TargetAddr + ASLR; 119 | orig_value->size = sizeof(uint32_t); 120 | int result = vm_protect(mach_task_self(),(vm_address_t)real_address,orig_value->size,0,19); 121 | orig_value->address = real_address; 122 | orig_value->value = *((uint32_t *)real_address); 123 | NSLog(@"--------orig_value is %llX",orig_value->value); 124 | *((uint32_t *)real_address) = Bytes; 125 | NSLog(@"--------modfied into %08X",*((uint32_t *)real_address)); 126 | result = vm_protect(mach_task_self(),(vm_address_t)real_address,orig_value->size,0,VM_PROT_READ | VM_PROT_EXECUTE); 127 | 128 | } 129 | void MemoryPatch64(uint64_t TargetAddr,uint64_t Bytes,MemoryRestore *orig_value){ 130 | 131 | uint64_t ASLR = _dyld_get_image_vmaddr_slide(0); 132 | uint64_t real_address = TargetAddr + ASLR; 133 | orig_value->size = sizeof(uint64_t); 134 | int result = vm_protect(mach_task_self(),(vm_address_t)real_address,orig_value->size,0,19); 135 | orig_value->address = real_address; 136 | orig_value->value = *((uint64_t *)real_address); 137 | NSLog(@"--------orig_value is %0llX",orig_value->value); 138 | *((uint64_t *)real_address) = Bytes; 139 | NSLog(@"--------modfied into %0llX",*((uint64_t *)real_address)); 140 | result = vm_protect(mach_task_self(),(vm_address_t)real_address,orig_value->size,0,VM_PROT_READ | VM_PROT_EXECUTE); 141 | 142 | } 143 | 144 | void MemoryPatch2_64(uint64_t TargetAddr,uint64_t Bytes){ 145 | 146 | uint64_t ASLR = _dyld_get_image_vmaddr_slide(0); 147 | uint64_t real_address = TargetAddr + ASLR; 148 | int result = vm_protect(mach_task_self(),(vm_address_t)real_address,sizeof(uint64_t),0,19); 149 | NSLog(@"--------orig_value is %llX",*((uint64_t *)real_address)); 150 | *((uint64_t *)real_address) = Bytes; 151 | NSLog(@"--------modfied into %0llX",*((uint64_t *)real_address)); 152 | result = vm_protect(mach_task_self(),(vm_address_t)real_address,sizeof(uint64_t),0,VM_PROT_READ | VM_PROT_EXECUTE); 153 | 154 | } 155 | 156 | void MemoryPatch2(uint64_t TargetAddr,uint32_t Bytes){ 157 | 158 | uint64_t ASLR = _dyld_get_image_vmaddr_slide(0); 159 | uint64_t real_address = TargetAddr + ASLR; 160 | int result = vm_protect(mach_task_self(),(vm_address_t)real_address,sizeof(uint32_t),0,19); 161 | NSLog(@"--------orig_value is %08X",*((uint32_t *)real_address)); 162 | *((uint32_t *)real_address) = Bytes; 163 | NSLog(@"--------modfied into %08X",*((uint32_t *)real_address)); 164 | result = vm_protect(mach_task_self(),(vm_address_t)real_address,sizeof(uint32_t),0,VM_PROT_READ | VM_PROT_EXECUTE); 165 | 166 | 167 | } 168 | 169 | 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /MemoryPatcherTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MemoryPatcherTests/MemoryPatcherTests(1).m: -------------------------------------------------------------------------------- 1 | // 2 | // MemoryPatcherTests.m 3 | // MemoryPatcherTests 4 | // 5 | // Created by 江南 on 2019/11/2. 6 | // Copyright © 2019 江南. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MemoryPatcherTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation MemoryPatcherTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /MemoryPatcherTests/MemoryPatcherTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // MemoryPatcherTests.m 3 | // MemoryPatcherTests 4 | // 5 | // Created by 江南 on 2019/11/2. 6 | // Copyright © 2019 江南. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MemoryPatcherTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation MemoryPatcherTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MemoryPatcher 2 | This project is designed to edit the codes while running the Applications. 3 | # How to use 4 | Use the type"patch" to start your patching. 5 | Use the function PatchEnabled() to enable your patch,and use the function PatchDisabled to disable your patch. 6 | Use the function MemoryPatch2() or MemoryPatch2_64() (only for edit uint64 "*two instructions*" ) to enable a quick patch.(No restore) 7 | # Warning 8 | Please use the function correctly,or it will crash or cause some problems. 9 | There are some code inside the project that it is used to hack PUBG Mobile, if you don't want to use, you can delete it. 10 | --------------------------------------------------------------------------------