Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift compiler as a library: obfuscator case

Swift compiler as a library: obfuscator case

Presented during Mobile Warsaw meetup on 22nd of May 2018

43d2bef703ec7165166f161f137ac54f?s=128

Krzysztof Siejkowski

May 22, 2018
Tweet

Transcript

  1. Swift compiler as a library: 
 obfuscator case Krzysztof Siejkowski

  2. In software development, obfuscation is the deliberate act of creating

    source or machine code that is difficult for humans to understand — Wikipedia
  3. App Store YourApp binary file Your source code

  4. App Store YourApp binary file YourApp encrypted (FairPlay) Jailbroken device

    YourApp binary file Your source code
  5. App Store YourApp binary file YourApp encrypted (FairPlay) YourApp decrypted

    (in memory) Memory dump tool YourApp binary file Jailbroken device YourApp binary file Your source code
  6. App Store YourApp binary file YourApp encrypted (FairPlay) YourApp decrypted

    (in memory) Memory dump tool YourApp binary file Your source code Disassembler (Hopper) Assembly/pseudo-code Jailbroken device
  7. App Store YourApp binary file YourApp encrypted (FairPlay) YourApp decrypted

    (in memory) Memory dump tool YourApp binary file Your source code Disassembler (Hopper) Assembly/pseudo-code Jailbroken device
  8. None
  9. None
  10. None
  11. None
  12. class MyViewController: UIViewController {} class MyView: UIView {} class MyModel:

    NSManagedObject {} class MyRuntimeUsingObject: NSObject {} class SomeClass { @objc func someFunc() {} }
  13. Obfuscation is more than symbol renaming 
 Code Obfuscation Techniques

    for Software Protection
 —PhD thesis by Jan Cappaert
 

  14. How to obfuscate? • after compilation • during compilation •

    before compilation
  15. After compilation: binary to binary iXGuard (https://www.guardsquare.com/en/ixguard)

  16. During compilation: source to binary Obfuscator-LLVM (https://github.com/obfuscator-llvm/obfuscator)

  17. Before compilation: source to source WE!!!

  18. Goal: obfuscate Swift code 
 by renaming

  19. None
  20. None
  21. Does it work?

  22. Does it work? YES

  23. Not universal tool… • no DSYM support • no multiple

    targets • no mixed Swift/Obj-C • not all Swift constructs supported
  24. …but still powerful • Storyboards/XIBs renaming • various Swift expressions

    supported • excluding configuration • very easy to integrate
  25. $ bin/sirius -help USAGE: sirius -projectrootpath [PROJECTROOTPATH] -obfuscatedproject [OBFUSCATEDPROJECTPATH]

  26. Xcode project Zobfuskowany Xcode project Command line interface (standalone or

    as Xcode build step) Original Xcode project Obfuscated Xcode project (copy or inplace)
  27. Original Xcode project Xcode project parsing Symbols identification Generation of

    new names Obfuscated Xcode project (copy or inplace) Renaming in the source files
  28. Original Xcode project Xcode project parsing

  29. Original Xcode project Xcode project parsing Symbols identification

  30. Original Xcode project Xcode project parsing Symbols identification Generation of

    new names
  31. Original Xcode project Xcode project parsing Symbols identification Generation of

    new names Obfuscated Xcode project Renaming in the source files
  32. Obfuscation verification Original Xcode project Xcode project parsing Symbols identification

    Generation of new names Obfuscated Xcode project Renaming in the source files Main command line interface
  33. Obfuscation verification Original Xcode project Xcode project parsing Obfuscated Xcode

    project Main command line interface Swift compiler Symbols identification Generation of new names Renaming in the source files
  34. None
  35. None
  36. None
  37. None
  38. None
  39. None
  40. None
  41. None
  42. 1. create new folder in swift/tools
 2. add add_swift_tool_subdirectory function

    
 to swift/tools/CMakeLists.txt
 3. create new .cpp file with main function 
 4. create new CMakeLists.txt for your tool
 5. add add_swift_host_tool function 
 to swift/tools/<your-tool>/CMakeLists.txt 
 and define the source files, executable name and dependencies How to add new command line tool?
  43. None
  44. None
  45. None
  46. None
  47. None
  48. None
  49. None
  50. 1. create new folders in swift/include/swift and swift/lib
 2. add

    your .h interfaces 
 to swift/include/swift/<your-library>
 3. add your .cpp implementations to swift/lib/<your-library>
 4. create CMakeLists.txt for your library 
 at swift/lib/<your-library>/CMakeLists.txt 
 with add_swift_library function 
 that defines the source files, library name and dependencies
 5. add add_subdirectory function to swift/lib/CMakeLists.txt 
 How to add new library?
  51. None
  52. None
  53. None
  54. None
  55. None
  56. 1. create new folder in swift/unittests
 2. add your .cpp

    test source code 
 to swift/unittests/<your-library>
 3. create CMakeLists.txt for your unit tests
 at swift/unittests/<your-library>/CMakeLists.txt 
 with add_swift_unittest function that 
 defines the source files, executable name and dependencies
 4. add add_subdirectory call to swift/unittests/CMakeLists.txt 
 How to add unit tests?
  57. None
  58. None
  59. 1. create tool in swift/tools/<your-tool>
 2. (not required, but a

    good idea) create library 
 for the underlying logic 
 in swift/include/swift/<your-library> 
 and swift/lib/<your-library>
 3. add unit tests to swift/unittests/<your-library>
 4. add integration tests to swift/tests/<your-tool>
 How to create new compiler-based tool?
  60. None
  61. Abstract 
 Syntax 
 Tree

  62. CompilerInstance Compiler; CompilerInvocation Invocation; Invocation.setModuleName(ModuleName); Invocation.setMainExecutablePath(MainExecutablePath); for (const auto &InputFilename

    : InputFilenames) { Invocation.addInputFilename(InputFilename); } Invocation.setFrameworkSearchPaths(FrameworkPaths); Invocation.setSDKPath(SdkPath); Invocation.setTargetTriple(Triple); if (Compiler.setup(Invocation)) { return stringError("Error during compiler setup"); } Compiler.performSema();
  63. class SymbolsWalker : public SourceEntityWalker { bool visitDeclReference(ValueDecl *, CharSourceRange,

    TypeDecl *, ExtensionDecl *, Type, ReferenceMetaData) override; } for (auto* Unit : Compiler.getMainModule() ->getFiles()) { if (auto* Current = dyn_cast<SourceFile>(Unit)) { SymbolsWalker Walker; Walker.walk(&Current); } }
  64. ParamDecl *Parameter = //given from SourceEntityWalker auto Name = Parameter

    ->getName().str().str(); CharSourceRange Range(Parameter ->getNameLoc(), Name.length());
  65. auto &SourceManager = Current ->getASTContext().SourceMgr; auto BufferId = Current ->getBufferID().getValue();


    std ::error_code Error; llvm ::raw_fd_ostream DescriptorStream(Path, Error, F_None); SourceEditOutputConsumer Editor(SourceManager, 
 BufferId, DescriptorStream);
 
 CharSourceRange Range = // computed slide ago auto ReplacingString = // replacement for range in code Editor ->ide ::SourceEditConsumer ::accept(SourceManager, Range, ReplacingString);
  66. None
  67. static llvm ::cl ::opt<std ::string> SymbolsJsonPath("symbolsjson", llvm ::cl ::desc("Name of

    the file containing extracted symbols"), llvm ::cl ::cat(ObfuscatorNameMapper)); int main(int argc, char *argv[]) { INITIALIZE_LLVM(argc, argv); llvm ::cl ::ParseCommandLineOptions(argc, argv, “obfuscator-name-mapper");
  68. void MappingTraits<SymbolsJson> :: mapping(IO &Io, SymbolsJson &Object) { Io.mapRequired("symbols", Object.Symbols);

    } Input Input(JsonString); SymbolsJson Symbols; Input >> Symbols;
  69. • LLVM Programmer’s Manual 
 (http://llvm.org/docs/ProgrammersManual.html) 
 • LLVM Coding

    Standards 
 (http://llvm.org/docs/CodingStandards.html) • many more!
  70. 1. Get familiar with C++11 Few last practical tips

  71. 1. Get familiar with C++11
 2. Use Xcode as IDE

    (works really well!) Few last practical tips
  72. 1. Get familiar with C++11
 2. Use Xcode as IDE

    (works really well!)
 3. Keep Swift compiler in sync 
 with Xcode version Few last practical tips
  73. 1. Get familiar with C++11
 2. Use Xcode as IDE

    (works really well!)
 3. Keep Swift compiler in sync 
 with Xcode version
 4. Don’t let the lack of compiler knowledge 
 scare you away! Few last practical tips
  74. None
  75. Pros Cons Anything compiler can do, you can do too!

  76. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool
  77. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool So many tools are available!
  78. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool So many tools are available! No stable API, breaking changes all the time
  79. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool So many tools are available! No stable API, breaking changes all the time You can leverage 
 the existing infrastructure
  80. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool So many tools are available! No stable API, breaking changes all the time You can leverage 
 the existing infrastructure You must fit into 
 the existing infrastructure
  81. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool So many tools are available! No stable API, breaking changes all the time You can leverage 
 the existing infrastructure You must fit into 
 the existing infrastructure Support for both 
 Swift and Objective-C
  82. Pros Cons Anything compiler can do, you can do too!

    Compiler libs are designed for compilation, not for your tool So many tools are available! No stable API, breaking changes all the time You can leverage 
 the existing infrastructure You must fit into 
 the existing infrastructure Support for both 
 Swift and Objective-C There might be better alternatives
  83. Alternatives • libSyntax • SourceKit • existing swift tools

  84. None
  85. • https://github.com/PolideaPlayground/ SiriusObfuscator-SymbolExtractorAndRenamer 
 • Documentation folder has a lot

    of notes 
 on various implementation decisions, 
 with details and motivation
  86. None
  87. @KacperHarasim

  88. Questions? @_siejkowski

  89. Thank you!