Search code examples
javascriptreact-nativeobfuscation

How to obfuscate code in react-native for IOS


I have been trying to obfuscate the code for a while by using react-native-obfuscating-transformer. Everything seems okay but when I check the bundle.js. I can't see any obfuscated code.

PS: Currently, I try only for IOS.

Here are my config files.

metro.config.js


module.exports = {
    transformer: {
        babelTransformerPath: require.resolve('./transformer'),
        getTransformOptions: async () => ({
            transform: {
                experimentalImportSupport: false,
                inlineRequires: false,
            },
        }),
    },
};

transformer.js

const obfuscatingTransformer = require('react-native-obfuscating-transformer');

module.exports = obfuscatingTransformer({
    upstreamTransformer: require('metro-react-native-babel-transformer'),
    enableInDevelopment: true,
    obfuscatorOptions: {
        compact: true,
        controlFlowFlattening: true,
        controlFlowFlatteningThreshold: 0.75,
        deadCodeInjection: true,
        deadCodeInjectionThreshold: 0.4,
        debugProtection: false,
        debugProtectionInterval: false,
        disableConsoleOutput: true,
        identifierNamesGenerator: 'hexadecimal',
        log: false,
        numbersToExpressions: true,
        renameGlobals: false,
        rotateStringArray: true,
        selfDefending: true,
        shuffleStringArray: true,
        simplify: true,
        splitStrings: true,
        splitStringsChunkLength: 10,
        stringArray: true,
        stringArrayEncoding: ['base64'],
        stringArrayWrappersCount: 2,
        stringArrayWrappersChainedCalls: true,
        stringArrayWrappersType: 'variable',
        stringArrayThreshold: 0.75,
        transformObjectKeys: true,
        unicodeEscapeSequence: false,
    },
});


Solution

  • I finally figured out how to make it work after several test.

    my react and react native version:

     "react": "16.9.0",
     "react-native": "0.61.5",
    

    install other dependencies needed:

    npm install babylon --save
    npm install --save babel-traverse
    

    transformer.js

    const obfuscatingTransformer = require("react-native-obfuscating-transformer")
    const filter = filename => { 
      return filename.startsWith("src");
    };
    
    module.exports = obfuscatingTransformer({
    // this configuration is based on https://github.com/javascript-obfuscator/javascript-obfuscator
      obfuscatorOptions:{
        compact: true,
        controlFlowFlattening: false,
        deadCodeInjection: false,
        debugProtection: false,
        debugProtectionInterval: false,
        disableConsoleOutput: true,
        identifierNamesGenerator: 'hexadecimal',
        log: false,
        renameGlobals: false,
        rotateStringArray: true,
        selfDefending: true,
        shuffleStringArray: true,
        splitStrings: false,
        stringArray: true,
        stringArrayEncoding: ['base64'],
        stringArrayThreshold: 0.75,
        unicodeEscapeSequence: false
      },
      upstreamTransformer: require('metro-react-native-babel-transformer'),
      emitObfuscatedFiles: false,
      enableInDevelopment: true,
      filter: filter,
      trace: true
    })
    

    metro.config.js

    module.exports = {
      transformer: {
        getTransformOptions: async () => ({
          transform: {
            experimentalImportSupport: false,
            inlineRequires: false,
          },
        }),
        babelTransformerPath: require.resolve("./transformer")   // add here the transformer.js
      },
    };
    

    NOTE:

    set emitObfuscatedFiles to true in obfuscatorOptions to emit the obfuscated versions of files alongside their originals, for comparison.

    If you're building in release, you can also compare the generated index.android.bundle (located in \android\app\build\generated\assets\react\release) with and without using the react-native-obfuscating-transformer using online diff tool to see the difference