$30 off During Our Annual Pro Sale. View Details »

Swift compiler as a library: obfuscator case

Swift compiler as a library: obfuscator case

Presented during Mobile Warsaw meetup on 22nd of May 2018

Krzysztof Siejkowski

May 22, 2018
Tweet

More Decks by Krzysztof Siejkowski

Other Decks in Programming

Transcript

  1. Swift compiler as a
    library: 

    obfuscator case
    Krzysztof Siejkowski

    View Slide

  2. In software development,
    obfuscation is the deliberate act of
    creating source or machine code that
    is difficult for humans to understand
    — Wikipedia

    View Slide

  3. App Store
    YourApp binary file
    Your source code

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  8. View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. class MyViewController: UIViewController {}
    class MyView: UIView {}
    class MyModel: NSManagedObject {}
    class MyRuntimeUsingObject: NSObject {}
    class SomeClass {
    @objc func someFunc() {}
    }

    View Slide

  13. Obfuscation is more
    than symbol renaming

    Code Obfuscation Techniques for Software Protection

    —PhD thesis by Jan Cappaert


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  18. Goal: obfuscate Swift
    code 

    by renaming

    View Slide

  19. View Slide

  20. View Slide

  21. Does it work?

    View Slide

  22. Does it work?
    YES

    View Slide

  23. Not universal tool…
    • no DSYM support
    • no multiple targets
    • no mixed Swift/Obj-C
    • not all Swift constructs supported

    View Slide

  24. …but still powerful
    • Storyboards/XIBs renaming
    • various Swift expressions supported
    • excluding configuration
    • very easy to integrate

    View Slide

  25. $ bin/sirius -help
    USAGE: sirius -projectrootpath [PROJECTROOTPATH]
    -obfuscatedproject [OBFUSCATEDPROJECTPATH]

    View Slide

  26. Xcode project
    Zobfuskowany Xcode project
    Command line interface
    (standalone or as Xcode build step)
    Original Xcode project
    Obfuscated Xcode project (copy or inplace)

    View Slide

  27. Original Xcode project
    Xcode project parsing
    Symbols identification
    Generation of new names
    Obfuscated Xcode project (copy or inplace)
    Renaming in the source files

    View Slide

  28. Original Xcode project
    Xcode project parsing

    View Slide

  29. Original Xcode project
    Xcode project parsing
    Symbols identification

    View Slide

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

    View Slide

  31. Original Xcode project
    Xcode project parsing
    Symbols identification
    Generation of new names
    Obfuscated Xcode project
    Renaming in the source files

    View Slide

  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

    View Slide

  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

    View Slide

  34. View Slide

  35. View Slide

  36. View Slide

  37. View Slide

  38. View Slide

  39. View Slide

  40. View Slide

  41. View Slide

  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//CMakeLists.txt 

    and define the source files, executable name and dependencies
    How to add new command line tool?

    View Slide

  43. View Slide

  44. View Slide

  45. View Slide

  46. View Slide

  47. View Slide

  48. View Slide

  49. View Slide

  50. 1. create new folders in swift/include/swift and swift/lib

    2. add your .h interfaces 

    to swift/include/swift/

    3. add your .cpp implementations to swift/lib/

    4. create CMakeLists.txt for your library 

    at swift/lib//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?

    View Slide

  51. View Slide

  52. View Slide

  53. View Slide

  54. View Slide

  55. View Slide

  56. 1. create new folder in swift/unittests

    2. add your .cpp test source code 

    to swift/unittests/

    3. create CMakeLists.txt for your unit tests

    at swift/unittests//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?

    View Slide

  57. View Slide

  58. View Slide

  59. 1. create tool in swift/tools/

    2. (not required, but a good idea) create library 

    for the underlying logic 

    in swift/include/swift/ 

    and swift/lib/

    3. add unit tests to swift/unittests/

    4. add integration tests to swift/tests/

    How to create new compiler-based tool?

    View Slide

  60. View Slide

  61. Abstract 

    Syntax 

    Tree

    View Slide

  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();

    View Slide

  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(Unit)) {
    SymbolsWalker Walker;
    Walker.walk(&Current);
    }
    }

    View Slide

  64. ParamDecl *Parameter = //given from SourceEntityWalker
    auto Name = Parameter ->getName().str().str();
    CharSourceRange Range(Parameter ->getNameLoc(),
    Name.length());

    View Slide

  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);

    View Slide

  66. View Slide

  67. static llvm ::cl ::opt
    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");

    View Slide

  68. void MappingTraits ::
    mapping(IO &Io, SymbolsJson &Object) {
    Io.mapRequired("symbols", Object.Symbols);
    }
    Input Input(JsonString);
    SymbolsJson Symbols;
    Input >> Symbols;

    View Slide

  69. • LLVM Programmer’s Manual 

    (http://llvm.org/docs/ProgrammersManual.html) 

    • LLVM Coding Standards 

    (http://llvm.org/docs/CodingStandards.html)
    • many more!

    View Slide

  70. 1. Get familiar with C++11
    Few last practical tips

    View Slide

  71. 1. Get familiar with C++11

    2. Use Xcode as IDE (works really well!)
    Few last practical tips

    View Slide

  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

    View Slide

  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

    View Slide

  74. View Slide

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

    View Slide

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

    View Slide

  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!

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  83. Alternatives
    • libSyntax
    • SourceKit
    • existing swift tools

    View Slide

  84. View Slide

  85. • https://github.com/PolideaPlayground/
    SiriusObfuscator-SymbolExtractorAndRenamer 

    • Documentation folder has a lot of notes 

    on various implementation decisions, 

    with details and motivation

    View Slide

  86. View Slide


  87. @KacperHarasim

    View Slide

  88. Questions?
    @_siejkowski

    View Slide

  89. Thank you!

    View Slide