From e9a37fcd75e3ec6554196c9855f9944b4810b614 Mon Sep 17 00:00:00 2001 From: eugeneyang Date: Tue, 23 Aug 2016 02:18:22 +0800 Subject: [PATCH] oc method and json symbol feature finish --- .gitignore | 106 +++++ .gitmodules | 3 + class-dump | 1 + restore-symbol.xcodeproj/project.pbxproj | 425 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + restore-symbol/RSScanMethodVisitor.h | 17 + restore-symbol/RSScanMethodVisitor.m | 100 +++++ restore-symbol/RSSymbol.h | 28 ++ restore-symbol/RSSymbol.m | 44 ++ restore-symbol/RSSymbolCollector.h | 24 + restore-symbol/RSSymbolCollector.m | 126 ++++++ restore-symbol/main.m | 120 +++++ restore-symbol/restore-symbol.m | 196 ++++++++ restore-symbol/restore-symbol.pch | 17 + 14 files changed, 1214 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 160000 class-dump create mode 100644 restore-symbol.xcodeproj/project.pbxproj create mode 100644 restore-symbol.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 restore-symbol/RSScanMethodVisitor.h create mode 100644 restore-symbol/RSScanMethodVisitor.m create mode 100644 restore-symbol/RSSymbol.h create mode 100644 restore-symbol/RSSymbol.m create mode 100644 restore-symbol/RSSymbolCollector.h create mode 100644 restore-symbol/RSSymbolCollector.m create mode 100644 restore-symbol/main.m create mode 100644 restore-symbol/restore-symbol.m create mode 100644 restore-symbol/restore-symbol.pch diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4d83ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,106 @@ +# svn +*.svn* + +# mac +__MACOSX +*.DS_Store* +*._* +*.lock +*.Spotlight-V100 +*.Trashes +*ehthumbs.db +*Thumbs.db + +# Python +*.pyc +__pycache__/ + + +# Vim +*.swp +*.swo +*.swn + +# Xcode +*~.nib +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate + +# generated files +bin/ +gen/ + +# built application files +*.apk +*.ap_ + +# files for the dex VM +*.dex + +# Java class files +*.class + +# Local configuration file (sdk path, etc) +local.properties + +# Eclipse project files +.classpath +.project +.settings/ + +# Proguard folder generated by Eclipse +proguard/ + +# Intellij project files +*.iml +*.ipr +*.iws +.idea/ + +#Pod +Pods/ +!podfile +!podfile.lock + +# Gradle files +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +#Android studio For eclipse +#build.gradle +#gradle/ +#gradlew +#gradlew.bat +#.gradle/ +# + + + +#tweak +_/ +.theos/ +obj/ +*.deb + + + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..70367dd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "class-dump"] + path = class-dump + url = https://github.com/0xced/class-dump diff --git a/class-dump b/class-dump new file mode 160000 index 0000000..a8877b6 --- /dev/null +++ b/class-dump @@ -0,0 +1 @@ +Subproject commit a8877b6695f317816322134944a410de09da4911 diff --git a/restore-symbol.xcodeproj/project.pbxproj b/restore-symbol.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1422404 --- /dev/null +++ b/restore-symbol.xcodeproj/project.pbxproj @@ -0,0 +1,425 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 8F92BBCA1D6B7085008EA4C4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBC91D6B7085008EA4C4 /* main.m */; }; + 8F92BBE31D6B70C7008EA4C4 /* libMachObjC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F92BBDA1D6B70A3008EA4C4 /* libMachObjC.a */; }; + 8F92BBEF1D6B7265008EA4C4 /* restore-symbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBE71D6B7265008EA4C4 /* restore-symbol.m */; }; + 8F92BBF01D6B7265008EA4C4 /* RSScanMethodVisitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBE91D6B7265008EA4C4 /* RSScanMethodVisitor.m */; }; + 8F92BBF11D6B7265008EA4C4 /* RSSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBEB1D6B7265008EA4C4 /* RSSymbol.m */; }; + 8F92BBF21D6B7265008EA4C4 /* RSSymbolCollector.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBED1D6B7265008EA4C4 /* RSSymbolCollector.m */; }; + 8F92BBF51D6B72E1008EA4C4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F92BBF41D6B72E1008EA4C4 /* Foundation.framework */; }; + 8F92BBF91D6B7445008EA4C4 /* CDClassDump.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBF81D6B7445008EA4C4 /* CDClassDump.m */; }; + 8F92BBFD1D6B750E008EA4C4 /* CDVisitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBFB1D6B750E008EA4C4 /* CDVisitor.m */; }; + 8F92BBFF1D6B758A008EA4C4 /* CDTypeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BBFE1D6B758A008EA4C4 /* CDTypeController.m */; }; + 8F92BC021D6B78FD008EA4C4 /* CDSearchPathState.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BC011D6B78FD008EA4C4 /* CDSearchPathState.m */; }; + 8F92BC041D6B790C008EA4C4 /* CDStructureTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BC031D6B790C008EA4C4 /* CDStructureTable.m */; }; + 8F92BC061D6B791D008EA4C4 /* CDStructureInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F92BC051D6B791D008EA4C4 /* CDStructureInfo.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 8F92BBD91D6B70A3008EA4C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 013D1F1113A5AE5A00BF0A67; + remoteInfo = MachObjC; + }; + 8F92BBDB1D6B70A3008EA4C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 01EB825F13A590D9003EDE60; + remoteInfo = "class-dump"; + }; + 8F92BBDD1D6B70A3008EA4C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 013D1EFB13A5A0F100BF0A67; + remoteInfo = deprotect; + }; + 8F92BBDF1D6B70A3008EA4C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 01B02CFF13A5B0DC0047BC53; + remoteInfo = formatType; + }; + 8F92BBE11D6B70A3008EA4C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0165B8B11827137D00CC647F; + remoteInfo = UnitTests; + }; + 8F92BBF61D6B73BD008EA4C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 013D1F1013A5AE5A00BF0A67; + remoteInfo = MachObjC; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 8F92BBC41D6B7085008EA4C4 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 8F92BBC61D6B7085008EA4C4 /* restore-symbol */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "restore-symbol"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F92BBC91D6B7085008EA4C4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "class-dump.xcodeproj"; path = "class-dump/class-dump.xcodeproj"; sourceTree = ""; }; + 8F92BBE71D6B7265008EA4C4 /* restore-symbol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "restore-symbol.m"; sourceTree = ""; }; + 8F92BBE81D6B7265008EA4C4 /* RSScanMethodVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSScanMethodVisitor.h; sourceTree = ""; }; + 8F92BBE91D6B7265008EA4C4 /* RSScanMethodVisitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSScanMethodVisitor.m; sourceTree = ""; }; + 8F92BBEA1D6B7265008EA4C4 /* RSSymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSymbol.h; sourceTree = ""; }; + 8F92BBEB1D6B7265008EA4C4 /* RSSymbol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSymbol.m; sourceTree = ""; }; + 8F92BBEC1D6B7265008EA4C4 /* RSSymbolCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSymbolCollector.h; sourceTree = ""; }; + 8F92BBED1D6B7265008EA4C4 /* RSSymbolCollector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSymbolCollector.m; sourceTree = ""; }; + 8F92BBF31D6B72C6008EA4C4 /* restore-symbol.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "restore-symbol.pch"; sourceTree = ""; }; + 8F92BBF41D6B72E1008EA4C4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 8F92BBF81D6B7445008EA4C4 /* CDClassDump.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDClassDump.m; path = "../class-dump/Source/CDClassDump.m"; sourceTree = ""; }; + 8F92BBFB1D6B750E008EA4C4 /* CDVisitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVisitor.m; path = "../class-dump/Source/CDVisitor.m"; sourceTree = ""; }; + 8F92BBFE1D6B758A008EA4C4 /* CDTypeController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDTypeController.m; path = "../class-dump/Source/CDTypeController.m"; sourceTree = ""; }; + 8F92BC011D6B78FD008EA4C4 /* CDSearchPathState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDSearchPathState.m; path = "../class-dump/Source/CDSearchPathState.m"; sourceTree = ""; }; + 8F92BC031D6B790C008EA4C4 /* CDStructureTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDStructureTable.m; path = "../class-dump/Source/CDStructureTable.m"; sourceTree = ""; }; + 8F92BC051D6B791D008EA4C4 /* CDStructureInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDStructureInfo.m; path = "../class-dump/Source/CDStructureInfo.m"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8F92BBC31D6B7085008EA4C4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8F92BBF51D6B72E1008EA4C4 /* Foundation.framework in Frameworks */, + 8F92BBE31D6B70C7008EA4C4 /* libMachObjC.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8F92BBBD1D6B7085008EA4C4 = { + isa = PBXGroup; + children = ( + 8F92BBF41D6B72E1008EA4C4 /* Foundation.framework */, + 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */, + 8F92BBC81D6B7085008EA4C4 /* restore-symbol */, + 8F92BBC71D6B7085008EA4C4 /* Products */, + ); + sourceTree = ""; + }; + 8F92BBC71D6B7085008EA4C4 /* Products */ = { + isa = PBXGroup; + children = ( + 8F92BBC61D6B7085008EA4C4 /* restore-symbol */, + ); + name = Products; + sourceTree = ""; + }; + 8F92BBC81D6B7085008EA4C4 /* restore-symbol */ = { + isa = PBXGroup; + children = ( + 8F92BC001D6B789F008EA4C4 /* ref-to-class-dump */, + 8F92BBE81D6B7265008EA4C4 /* RSScanMethodVisitor.h */, + 8F92BBE91D6B7265008EA4C4 /* RSScanMethodVisitor.m */, + 8F92BBEA1D6B7265008EA4C4 /* RSSymbol.h */, + 8F92BBEB1D6B7265008EA4C4 /* RSSymbol.m */, + 8F92BBEC1D6B7265008EA4C4 /* RSSymbolCollector.h */, + 8F92BBED1D6B7265008EA4C4 /* RSSymbolCollector.m */, + 8F92BBC91D6B7085008EA4C4 /* main.m */, + 8F92BBE71D6B7265008EA4C4 /* restore-symbol.m */, + 8F92BBF31D6B72C6008EA4C4 /* restore-symbol.pch */, + ); + path = "restore-symbol"; + sourceTree = ""; + }; + 8F92BBD11D6B70A3008EA4C4 /* Products */ = { + isa = PBXGroup; + children = ( + 8F92BBDA1D6B70A3008EA4C4 /* libMachObjC.a */, + 8F92BBDC1D6B70A3008EA4C4 /* class-dump */, + 8F92BBDE1D6B70A3008EA4C4 /* deprotect */, + 8F92BBE01D6B70A3008EA4C4 /* formatType */, + 8F92BBE21D6B70A3008EA4C4 /* UnitTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 8F92BC001D6B789F008EA4C4 /* ref-to-class-dump */ = { + isa = PBXGroup; + children = ( + 8F92BC051D6B791D008EA4C4 /* CDStructureInfo.m */, + 8F92BC031D6B790C008EA4C4 /* CDStructureTable.m */, + 8F92BC011D6B78FD008EA4C4 /* CDSearchPathState.m */, + 8F92BBF81D6B7445008EA4C4 /* CDClassDump.m */, + 8F92BBFE1D6B758A008EA4C4 /* CDTypeController.m */, + 8F92BBFB1D6B750E008EA4C4 /* CDVisitor.m */, + ); + name = "ref-to-class-dump"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8F92BBC51D6B7085008EA4C4 /* restore-symbol */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8F92BBCD1D6B7085008EA4C4 /* Build configuration list for PBXNativeTarget "restore-symbol" */; + buildPhases = ( + 8F92BBC21D6B7085008EA4C4 /* Sources */, + 8F92BBC31D6B7085008EA4C4 /* Frameworks */, + 8F92BBC41D6B7085008EA4C4 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 8F92BBF71D6B73BD008EA4C4 /* PBXTargetDependency */, + ); + name = "restore-symbol"; + productName = "restore-symbol"; + productReference = 8F92BBC61D6B7085008EA4C4 /* restore-symbol */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8F92BBBE1D6B7085008EA4C4 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0730; + ORGANIZATIONNAME = Jun; + TargetAttributes = { + 8F92BBC51D6B7085008EA4C4 = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 8F92BBC11D6B7085008EA4C4 /* Build configuration list for PBXProject "restore-symbol" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 8F92BBBD1D6B7085008EA4C4; + productRefGroup = 8F92BBC71D6B7085008EA4C4 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 8F92BBD11D6B70A3008EA4C4 /* Products */; + ProjectRef = 8F92BBD01D6B70A3008EA4C4 /* class-dump.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 8F92BBC51D6B7085008EA4C4 /* restore-symbol */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 8F92BBDA1D6B70A3008EA4C4 /* libMachObjC.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libMachObjC.a; + remoteRef = 8F92BBD91D6B70A3008EA4C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8F92BBDC1D6B70A3008EA4C4 /* class-dump */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = "class-dump"; + remoteRef = 8F92BBDB1D6B70A3008EA4C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8F92BBDE1D6B70A3008EA4C4 /* deprotect */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = deprotect; + remoteRef = 8F92BBDD1D6B70A3008EA4C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8F92BBE01D6B70A3008EA4C4 /* formatType */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = formatType; + remoteRef = 8F92BBDF1D6B70A3008EA4C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8F92BBE21D6B70A3008EA4C4 /* UnitTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = UnitTests.xctest; + remoteRef = 8F92BBE11D6B70A3008EA4C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + 8F92BBC21D6B7085008EA4C4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8F92BBEF1D6B7265008EA4C4 /* restore-symbol.m in Sources */, + 8F92BC041D6B790C008EA4C4 /* CDStructureTable.m in Sources */, + 8F92BBCA1D6B7085008EA4C4 /* main.m in Sources */, + 8F92BBF01D6B7265008EA4C4 /* RSScanMethodVisitor.m in Sources */, + 8F92BC061D6B791D008EA4C4 /* CDStructureInfo.m in Sources */, + 8F92BBF21D6B7265008EA4C4 /* RSSymbolCollector.m in Sources */, + 8F92BBF11D6B7265008EA4C4 /* RSSymbol.m in Sources */, + 8F92BBF91D6B7445008EA4C4 /* CDClassDump.m in Sources */, + 8F92BC021D6B78FD008EA4C4 /* CDSearchPathState.m in Sources */, + 8F92BBFF1D6B758A008EA4C4 /* CDTypeController.m in Sources */, + 8F92BBFD1D6B750E008EA4C4 /* CDVisitor.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8F92BBF71D6B73BD008EA4C4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MachObjC; + targetProxy = 8F92BBF61D6B73BD008EA4C4 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 8F92BBCB1D6B7085008EA4C4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 8F92BBCC1D6B7085008EA4C4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 8F92BBCE1D6B7085008EA4C4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREFIX_HEADER = "restore-symbol/restore-symbol.pch"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/class-dump/Source/**"; + }; + name = Debug; + }; + 8F92BBCF1D6B7085008EA4C4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREFIX_HEADER = "restore-symbol/restore-symbol.pch"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/class-dump/Source/**"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8F92BBC11D6B7085008EA4C4 /* Build configuration list for PBXProject "restore-symbol" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F92BBCB1D6B7085008EA4C4 /* Debug */, + 8F92BBCC1D6B7085008EA4C4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8F92BBCD1D6B7085008EA4C4 /* Build configuration list for PBXNativeTarget "restore-symbol" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8F92BBCE1D6B7085008EA4C4 /* Debug */, + 8F92BBCF1D6B7085008EA4C4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8F92BBBE1D6B7085008EA4C4 /* Project object */; +} diff --git a/restore-symbol.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/restore-symbol.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c3cdcfc --- /dev/null +++ b/restore-symbol.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/restore-symbol/RSScanMethodVisitor.h b/restore-symbol/RSScanMethodVisitor.h new file mode 100644 index 0000000..a02bd3a --- /dev/null +++ b/restore-symbol/RSScanMethodVisitor.h @@ -0,0 +1,17 @@ +// -*- mode: ObjC -*- + +// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. +// Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. + +#import "CDVisitor.h" +#import "RSSymbolCollector.h" + +// This limits the output to methods matching the search string. Some context is included, so that you can see which class, category, or protocol +// contains the method. + +@interface RSScanMethodVisitor : CDVisitor + +- (instancetype)initWithSymbolCollector:(RSSymbolCollector*)collector; + + +@end diff --git a/restore-symbol/RSScanMethodVisitor.m b/restore-symbol/RSScanMethodVisitor.m new file mode 100644 index 0000000..75b5a18 --- /dev/null +++ b/restore-symbol/RSScanMethodVisitor.m @@ -0,0 +1,100 @@ +// -*- mode: ObjC -*- + +// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. +// Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. + +#import "RSScanMethodVisitor.h" + +#import "CDClassDump.h" +#import "CDObjectiveC1Processor.h" +#import "CDMachOFile.h" +#import "CDOCProtocol.h" +#import "CDLCDylib.h" +#import "CDOCClass.h" +#import "CDOCCategory.h" +#import "CDOCMethod.h" +//#import "CDTypeController.h" + +@interface RSScanMethodVisitor () + +@property (nonatomic, strong) CDOCProtocol *context; + +@property (nonatomic, weak) RSSymbolCollector * collector; + +@end + +#pragma mark - + +@implementation RSScanMethodVisitor +{ + CDOCProtocol *_context; + +} + +- (id)initWithSymbolCollector:(RSSymbolCollector *)collector +{ + if ((self = [super init])) { + _context = nil; + _collector = collector; + } + + return self; +} + +#pragma mark - + +- (void)willVisitProtocol:(CDOCProtocol *)protocol; +{ + [self setContext:protocol]; +} + +- (void)willVisitClass:(CDOCClass *)aClass; +{ + [self setContext:aClass]; +} + + +- (void)willVisitCategory:(CDOCCategory *)category; +{ + [self setContext:category]; +} + +- (void)visitClassMethod:(CDOCMethod *)method; +{ + if (method.address == 0 ) { + return; + } + NSString *name = [NSString stringWithFormat:@"+[%@ %@]", _context.name, method.name]; + + RSSymbol *s = [RSSymbol symbolWithName:name address:method.address]; + + [self.collector addSymbol:s]; + +} + +- (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState; +{ + if (method.address == 0 ) { + return; + } + NSString *name = [NSString stringWithFormat:@"-[%@ %@]", _context.name, method.name]; + + RSSymbol *s = [RSSymbol symbolWithName:name address:method.address]; + + [self.collector addSymbol:s]; + +} + + +#pragma mark - + +- (void)setContext:(CDOCProtocol *)newContext; +{ + if (newContext != _context) { + _context = newContext; + } +} + + + +@end diff --git a/restore-symbol/RSSymbol.h b/restore-symbol/RSSymbol.h new file mode 100644 index 0000000..a66b662 --- /dev/null +++ b/restore-symbol/RSSymbol.h @@ -0,0 +1,28 @@ +// +// RSSymbol.h +// restore-symbol +// +// Created by EugeneYang on 16/8/19. +// +// + +#import + + +#define RS_JSON_KEY_ADDRESS @"address" +#define RS_JSON_KEY_SYMBOL_NAME @"name" + +@interface RSSymbol : NSObject + + +@property (nonatomic, strong) NSString * name; +@property (nonatomic) uint64 address; + + ++ (NSArray *)symbolsWithJson:(NSData *)json; + ++ (RSSymbol *)symbolWithName:(NSString *)name address:(uint64)addr; + + + +@end diff --git a/restore-symbol/RSSymbol.m b/restore-symbol/RSSymbol.m new file mode 100644 index 0000000..dfa02e7 --- /dev/null +++ b/restore-symbol/RSSymbol.m @@ -0,0 +1,44 @@ +// +// RSSymbol.m +// restore-symbol +// +// Created by EugeneYang on 16/8/19. +// +// + +#import "RSSymbol.h" + +@implementation RSSymbol + + ++ (NSArray *)symbolsWithJson:(NSData *)json{ + NSError * e = nil; + + NSArray *symbols = [NSJSONSerialization JSONObjectWithData:json options:NSJSONReadingMutableContainers error:&e]; + + if (!symbols) { + fprintf(stderr,"%s\n", e.description.UTF8String); + return nil; + } + + NSMutableArray * rt = [NSMutableArray array]; + for (NSDictionary *dict in symbols) { + NSString *addressString = dict[RS_JSON_KEY_ADDRESS]; + unsigned long long address; + NSScanner* scanner = [NSScanner scannerWithString:addressString]; + [scanner scanHexLongLong:&address]; + RSSymbol * symbol = [self symbolWithName:dict[RS_JSON_KEY_SYMBOL_NAME] address:address]; + [rt addObject:symbol]; + } + + return rt; +} + + ++ (RSSymbol *)symbolWithName:(NSString *)name address:(uint64)addr{ + RSSymbol * s = [RSSymbol new]; + s.name = name; + s.address = addr; + return s; +} +@end diff --git a/restore-symbol/RSSymbolCollector.h b/restore-symbol/RSSymbolCollector.h new file mode 100644 index 0000000..974d61f --- /dev/null +++ b/restore-symbol/RSSymbolCollector.h @@ -0,0 +1,24 @@ +// +// RSSymbolCollector.h +// restore-symbol +// +// Created by EugeneYang on 16/8/19. +// +// + +#import +#import "RSSymbol.h" +#import "CDMachOFile.h" + +@interface RSSymbolCollector : NSObject + +@property (nonatomic, weak) CDMachOFile * machOFile; +@property (nonatomic, strong) NSMutableArray *symbols; + + +- (void)addSymbol:(RSSymbol *)symbol; +- (void)addSymbols:(NSArray *)symbols; + + +- (void)generateAppendStringTable:(NSData **)stringTable appendSymbolTable:(NSData **)nlist; +@end diff --git a/restore-symbol/RSSymbolCollector.m b/restore-symbol/RSSymbolCollector.m new file mode 100644 index 0000000..8b09e38 --- /dev/null +++ b/restore-symbol/RSSymbolCollector.m @@ -0,0 +1,126 @@ +// +// RSSymbolCollector.m +// restore-symbol +// +// Created by EugeneYang on 16/8/19. +// +// + +#import "RSSymbolCollector.h" + +#import +#import "CDLCSymbolTable.h" +#import "CDLCSegment.h" +#import "CDSection.h" + +@implementation RSSymbolCollector + + + +- (instancetype)init +{ + self = [super init]; + if (self) { + _symbols = [NSMutableArray array]; + } + return self; +} + + +- (void)addSymbol:(RSSymbol *)symbol{ + if (symbol == nil) { + return ; + } + [_symbols addObject:symbol]; +} + + +- (void)addSymbols:(NSArray *)symbols{ + if (symbols == nil) + return ; + [_symbols addObjectsFromArray:symbols]; +} + + +- (void)generateAppendStringTable:(NSData **)stringTable appendSymbolTable:(NSData **)symbolTable{ + + const bool is32Bit = ! _machOFile.uses64BitABI; + + NSMutableData * symbolNames = [NSMutableData new]; + + NSMutableData * nlistsData = [NSMutableData dataWithLength:_symbols.count * ( is32Bit ? sizeof(struct nlist) : sizeof(struct nlist_64))]; + + memset(nlistsData.mutableBytes, 0, nlistsData.length); + + uint32 origin_string_table_size = _machOFile.symbolTable.strsize; + + + for (int i = 0; i < _symbols.count; i ++) { + + + RSSymbol * symbol = _symbols[i]; + if (symbol.address == 0) { + continue; + } + + + if (is32Bit) { + struct nlist * list = nlistsData.mutableBytes; + bool isThumb = symbol.address & 1; + list[i].n_desc = isThumb ? N_ARM_THUMB_DEF : 0; + list[i].n_type = N_PEXT | N_SECT; + list[i].n_sect = [self n_sectForAddress:symbol.address]; + list[i].n_value = (uint32_t)symbol.address & ~ 1; + list[i].n_un.n_strx = origin_string_table_size + (uint32)symbolNames.length; + + } else { + struct nlist_64 * list = nlistsData.mutableBytes; + bool isThumb = symbol.address & 1; + list[i].n_desc = isThumb ? N_ARM_THUMB_DEF : 0; + list[i].n_type = N_PEXT | N_SECT; + list[i].n_sect = [self n_sectForAddress:symbol.address]; + list[i].n_value = symbol.address; + list[i].n_un.n_strx = origin_string_table_size + (uint32)symbolNames.length; + } + + [symbolNames appendBytes:symbol.name.UTF8String length:symbol.name.length]; + [symbolNames appendBytes:"\0" length:1]; + } + + + *stringTable = symbolNames; + *symbolTable = nlistsData; + + +} + +- (uint8)n_sectForAddress:(uint64)address{ + + + uint8 n_sect = 0; + + for (id loadCommand in _machOFile.loadCommands) { + if ([loadCommand isKindOfClass:[CDLCSegment class]]){ + CDLCSegment * seg = (CDLCSegment *)loadCommand; + if(![loadCommand containsAddress:address]) { + n_sect += [[seg sections] count]; + } else { + for (CDSection * section in [seg sections]){ + n_sect ++; + if ([section containsAddress:address]) { + return n_sect; + } + + } + + } + } + } + + NSLog(@"Address(%llx) not found in the image", address); + exit(1); + return 1; +} + + +@end diff --git a/restore-symbol/main.m b/restore-symbol/main.m new file mode 100644 index 0000000..0cfbf0b --- /dev/null +++ b/restore-symbol/main.m @@ -0,0 +1,120 @@ +// +// main.m +// class-dump +// +// Created by EugeneYang on 16/8/22. +// +// + +#include + +#include +#include +#include +#include + + + +#define RESTORE_SYMBOL_BASE_VERSION "1.0 (64 bit)" + +#ifdef DEBUG +#define RESTORE_SYMBOL_VERSION RESTORE_SYMBOL_BASE_VERSION //" (Debug version compiled " __DATE__ " " __TIME__ ")" +#else +#define RESTORE_SYMBOL_VERSION RESTORE_SYMBOL_BASE_VERSION +#endif + +#define RS_OPT_DISABLE_OC_DETECT 1 +#define RS_OPT_VERSION 2 + + + +void print_usage(void) +{ + fprintf(stderr, + "\n" + "restore-symbol %s\n" + "\n" + "Usage: restore-symbol -o [-j ] \n" + "\n" + " where options are:\n" + " -o New mach-o-file path\n" + " --disable-oc-detect Disable auto detect and add oc method into symbol table,\n" + " just add symbol in json file\n" + " -j Json file containing extra symbol info, the key is \"name\",\"address\"\n like this:\n \n" + " [\n {\n \"name\": \"main\", \n \"address\": \"0xXXXXXX\"\n }, \n {\n \"name\": \"-[XXXX XXXXX]\", \n \"address\": \"0xXXXXXX\"\n },\n .... \n ]\n" + + , + RESTORE_SYMBOL_VERSION + ); +} + + + +void restore_symbol(NSString * inpath, NSString * output, NSString *jsonPath, bool oc_detect_enable); + +int main(int argc, char * argv[]) { + + + + + bool oc_detect_enable = true; + NSString *inpath = nil; + NSString * outpath = nil; + NSString *jsonPath = nil; + + BOOL shouldPrintVersion = NO; + + int ch; + + struct option longopts[] = { + { "disable-oc-detect", no_argument, NULL, RS_OPT_DISABLE_OC_DETECT }, + { "output", required_argument, NULL, 'o' }, + { "json", required_argument, NULL, 'j' }, + { "version", no_argument, NULL, RS_OPT_VERSION }, + { NULL, 0, NULL, 0 }, + + }; + + + if (argc == 1) { + print_usage(); + exit(0); + } + + + + while ( (ch = getopt_long(argc, argv, "o:j:", longopts, NULL)) != -1) { + switch (ch) { + case 'o': + outpath = [NSString stringWithUTF8String:optarg]; + break; + case 'j': + jsonPath = [NSString stringWithUTF8String:optarg]; + break; + + case RS_OPT_VERSION: + shouldPrintVersion = YES; + break; + + case RS_OPT_DISABLE_OC_DETECT: + oc_detect_enable = false; + break; + + default: + break; + } + } + + if (shouldPrintVersion) { + printf("restore-symbol %s compiled %s\n", RESTORE_SYMBOL_VERSION, __DATE__ " " __TIME__); + exit(0); + } + + if (optind < argc) { + inpath = [NSString stringWithUTF8String:argv[optind]]; + } + + + restore_symbol(inpath, outpath, jsonPath, oc_detect_enable); + +} \ No newline at end of file diff --git a/restore-symbol/restore-symbol.m b/restore-symbol/restore-symbol.m new file mode 100644 index 0000000..63a5001 --- /dev/null +++ b/restore-symbol/restore-symbol.m @@ -0,0 +1,196 @@ +// +// main.m +// restore-symbol +// +// Created by EugeneYang on 16/8/16. +// +// + +#import +#include +#include +#import "CDFile.h" +#import "CDMachOFile.h" +#import "CDLCSymbolTable.h" +#import "CDLCSegment.h" +#import "CDSymbol.h" +#import "CDLCDynamicSymbolTable.h" +#import "CDLCLinkeditData.h" +#import "CDClassDump.h" +#import "CDFindMethodVisitor.h" +#import "RSScanMethodVisitor.h" +#import "CDFatFile.h" + + + +#define IntSize (Is32Bit? sizeof(uint32_t) : sizeof(uint64_t) ) +#define NListSize (Is32Bit? sizeof(struct nlist) : sizeof(struct nlist_64) ) + + +#define vm_addr_round(v,r) ( (v + (r-1) ) & (-r) ) + + + + + +void restore_symbol(NSString * inpath, NSString *outpath, NSString *jsonPath, bool oc_detect_enable){ + + + + + if (![[NSFileManager defaultManager] fileExistsAtPath:inpath]) { + fprintf(stderr, "Error: Input file doesn't exist!\n"); + exit(1); + } + + + fprintf(stderr, "=========== Start =============\n"); + + + + + [[NSFileManager defaultManager] removeItemAtPath:outpath error:nil]; + + NSMutableData * outData = [[NSMutableData alloc] initWithContentsOfFile:inpath]; + + CDFile * ofile = [CDFile fileWithContentsOfFile:inpath searchPathState:nil]; + + if ([ofile isKindOfClass:[CDFatFile class]] ) { + fprintf(stderr,"Restore-symbol supports armv7 and arm64 archtecture, but not support fat file. Please use lipo to thin the image file first."); + exit(1); + } + + + CDMachOFile * machOFile = (CDMachOFile *)ofile; + const bool Is32Bit = ! machOFile.uses64BitABI; + + + RSSymbolCollector *collector = [RSSymbolCollector new]; + collector.machOFile = machOFile; + + if (oc_detect_enable) { + fprintf(stderr, "Scan OC methoc in mach-o-file.\n"); + + CDClassDump *classDump = [[CDClassDump alloc] init]; + CDArch targetArch; + if ([machOFile bestMatchForLocalArch:&targetArch] == NO) { + fprintf(stderr, "Error: Couldn't get local architecture!\n"); + exit(1); + } + classDump.targetArch = targetArch; + [classDump processObjectiveCData]; + [classDump registerTypes]; + + NSError *error; + if (![classDump loadFile:machOFile error:&error]) { + fprintf(stderr, "Error: %s\n", [[error localizedFailureReason] UTF8String]); + exit(1); + } else { + [classDump processObjectiveCData]; + [classDump registerTypes]; + + RSScanMethodVisitor *visitor = [[RSScanMethodVisitor alloc] initWithSymbolCollector:collector]; + visitor.classDump = classDump; + [classDump recursivelyVisit:visitor]; + + } + + fprintf(stderr, "Scan OC methoc finish.\n"); + } + + + if (jsonPath != nil && jsonPath.length != 0) { + fprintf(stderr, "Parse symbols in json file.\n"); + NSArray *jsonSymbols = [RSSymbol symbolsWithJson:[NSData dataWithContentsOfFile:jsonPath]]; + if (jsonSymbols == nil) { + fprintf(stderr,"Error: Json file cann't parse!"); + exit(1); + } else { + [collector addSymbols:jsonSymbols]; + } + fprintf(stderr, "Parse finish.\n"); + } + + + NSData *string_table_append_data = nil; + NSData *symbol_table_append_data = nil; + [collector generateAppendStringTable:&string_table_append_data appendSymbolTable:&symbol_table_append_data]; + + + uint32 increase_symbol_num = (uint32)collector.symbols.count; + uint32 increase_size_string_tab = (uint32)string_table_append_data.length; + uint32 increase_size_symtab = (uint32)symbol_table_append_data.length; + uint32 increase_size_all_without_padding = increase_size_symtab + increase_size_string_tab; + + + + uint32 origin_string_table_offset = machOFile.symbolTable.stroff; + uint32 origin_string_table_size = machOFile.symbolTable.strsize; + uint32 origin_symbol_table_offset = machOFile.symbolTable.symoff; + uint32 origin_symbol_table_num = machOFile.symbolTable.nsyms; + + //LC_CODE_SIGNATURE need align 16 byte, so add padding at end of string table. + uint32 string_table_padding = 0; + { + CDLCLinkeditData * codesignature = nil; + for (CDLoadCommand *command in machOFile.loadCommands) { + if (command.cmd == LC_CODE_SIGNATURE){ + codesignature = (CDLCLinkeditData *)command; + } + } + + struct linkedit_data_command *command = (struct linkedit_data_command *)((char *)outData.mutableBytes + codesignature.commandOffset); + uint32_t tmp_offset = command -> dataoff + increase_size_all_without_padding; + uint32_t final_offset = vm_addr_round(tmp_offset, 16); + + string_table_padding = final_offset - tmp_offset; + command -> dataoff = final_offset; + + } + + + { + CDLCSymbolTable *symtab = [machOFile symbolTable]; + struct symtab_command *symtab_out = (struct symtab_command *)((char *)outData.mutableBytes + symtab.commandOffset); + symtab_out -> nsyms += increase_symbol_num; + symtab_out -> stroff += increase_size_symtab; + symtab_out -> strsize += increase_size_string_tab + string_table_padding; + } + + { + CDLCDynamicSymbolTable *dysymtabCommand = [machOFile dynamicSymbolTable]; + struct dysymtab_command *command = (struct dysymtab_command *)((char *)outData.mutableBytes + dysymtabCommand.commandOffset); + command -> indirectsymoff += increase_size_symtab; + } + + + + { + CDLCSegment * linkeditSegment = [machOFile segmentWithName:@"__LINKEDIT"]; + if (Is32Bit) { + struct segment_command *linkedit_segment_command = (struct segment_command *)((char *)outData.mutableBytes + linkeditSegment.commandOffset); + linkedit_segment_command -> filesize += increase_size_all_without_padding + string_table_padding; + linkedit_segment_command -> vmsize = (uint32) vm_addr_round((linkedit_segment_command -> filesize), 0x4000); + + + } else { + + struct segment_command_64 *linkedit_segment_command = (struct segment_command_64 *)((char *)outData.mutableBytes + linkeditSegment.commandOffset); + linkedit_segment_command -> filesize += increase_size_all_without_padding + string_table_padding; + linkedit_segment_command -> vmsize = vm_addr_round((linkedit_segment_command -> filesize), 0x4000); + } + } + + + + + // must first insert string + [outData replaceBytesInRange:NSMakeRange(origin_string_table_offset + origin_string_table_size , 0) withBytes:(const void *)string_table_append_data.bytes length:increase_size_string_tab + string_table_padding]; + + [outData replaceBytesInRange:NSMakeRange(origin_symbol_table_offset + origin_symbol_table_num * NListSize , 0) withBytes:(const void *)symbol_table_append_data.bytes length:increase_size_symtab]; + + [outData writeToFile:outpath atomically:true]; + chmod(outpath.UTF8String, 0755); + fprintf(stderr,"=========== Finish ============\n"); + +} diff --git a/restore-symbol/restore-symbol.pch b/restore-symbol/restore-symbol.pch new file mode 100644 index 0000000..8c3a965 --- /dev/null +++ b/restore-symbol/restore-symbol.pch @@ -0,0 +1,17 @@ +// +// restore-symbol.pch +// restore-symbol +// +// Created by EugeneYang on 16/8/23. +// Copyright © 2016年 Jun. All rights reserved. +// + +#ifndef restore_symbol_pch +#define restore_symbol_pch + +// Include any system framework and library headers here that should be included in all compilation units. +// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. +#include +#import "CDExtensions.h" +#define __cmd __PRETTY_FUNCTION__ +#endif /* restore_symbol_pch */