/

String Array

Protection ID: stringArray

String Array is a fundamental obfuscation technique that extracts string literals from your code and places them in a special array. These strings are then accessed by reference, making it difficult for attackers to understand the purpose and functionality of your code.

This protection is available in all editions of ByteHide Shield.


How It Works

The String Array protection works by:

  1. Extracting string literals from your source code
  2. Placing these strings in a separate array
  3. Replacing original strings with calls to access the array
  4. Optionally encoding the strings using methods like XOR, base64 or RC4
  5. Adding various transformations to make the array harder to analyze

This approach makes it significantly more difficult to understand the purpose of functions and code blocks by hiding textual clues that would otherwise help in reverse engineering.


Parameters

  • Enabled boolean : Enables String Array protection. true by default

  • Threshold number : Sets the probability (from 0 to 1) that a string literal will be moved to the string array. 0.75 by default

  • Encoding string[] : Specifies the encoding methods to use for strings in the array. ['xor'] by default

    • Available values: 'none', 'base64', 'rc4', 'xor'
    • 'xor' is the recommended option as it provides an advanced XOR-based encryption derived from RC4 with better performance
  • Rotate boolean : Shifts the string array by random positions. true by default

  • Shuffle boolean : Randomly shuffles items in the string array. true by default

  • Index Shift boolean : Adds an additional shift for all string array calls. true by default

  • Calls Transform boolean : Transforms calls to the string array, making them harder to identify. false by default

  • Calls Transform Threshold number : Controls how many calls are transformed (from 0 to 1). 0.5 by default

  • Wrappers Count number : Number of wrappers for the string array in each scope. 1 by default

  • Wrappers Type string : Type of wrappers used. 'variable' by default

    • Available values: 'variable', 'function'

The String Array protection offers extensive customization. The default XOR encoding offers a good balance between security and performance. For maximum security at a higher performance cost, consider using RC4 encoding.


Configuration Examples

Basic Configuration (shield.config.json)

{
  "stringArray": true,
  "stringArrayThreshold": 0.75
}

Advanced Configuration

{
  "stringArray": true,
  "stringArrayThreshold": 0.8,
  "stringArrayEncoding": ["xor", "rc4"],
  "stringArrayRotate": true,
  "stringArrayShuffle": true,
  "stringArrayCallsTransform": true,
  "stringArrayCallsTransformThreshold": 0.6,
  "stringArrayWrappersCount": 3,
  "stringArrayWrappersType": "function"
}

Build Tool Integration (Webpack)

// webpack.config.js
const ByteHideShieldPlugin = require('@bytehide/webpack-shield');

module.exports = {
  // ... other webpack config
  plugins: [
    new ByteHideShieldPlugin({
      projectToken: 'your-project-token',
      config: {
        stringArray: true,
        stringArrayThreshold: 0.85,
        stringArrayEncoding: ["xor"],
        stringArrayRotate: true,
        stringArrayShuffle: true
      }
    })
  ]
}

Code Transformation Example

Original Code

function authenticateUser(username, password) {
  const validUsername = "admin";
  const validPassword = "securePassword123";
  
  if (username === validUsername && password === validPassword) {
    console.log("Authentication successful");
    return {
      status: "success",
      message: "Welcome to the dashboard",
      token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
    };
  } else {
    console.log("Authentication failed");
    return {
      status: "error",
      message: "Invalid username or password",
      token: null
    };
  }
}

Transformed Code (with String Array)

const _0x3a7e = [
    'admin',
    'securePassword123',
    'log',
    'Authentication successful',
    'status',
    'success',
    'message',
    'Welcome to the dashboard',
    'token',
    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
    'Authentication failed',
    'error',
    'Invalid username or password'
];

function _0x28ac(_0x5b4f12, _0x48c71c) {
    return _0x28ac = function(_0x3a7ef5, _0x28acb0) {
        _0x3a7ef5 = _0x3a7ef5 - 0x12d;
        let _0x21e88e = _0x3a7e[_0x3a7ef5];
        return _0x21e88e;
    }, _0x28ac(_0x5b4f12, _0x48c71c);
}

const _0x481df3 = _0x28ac;

function authenticateUser(username, password) {
    const _0x48c71c = _0x28ac;
    const _0x53cc31 = _0x48c71c(0x12d);
    const _0x2e028d = _0x48c71c(0x12e);
    
    if (username === _0x53cc31 && password === _0x2e028d) {
        console[_0x48c71c(0x12f)](_0x48c71c(0x130));
        return {
            [_0x48c71c(0x131)]: _0x48c71c(0x132),
            [_0x48c71c(0x133)]: _0x48c71c(0x134),
            [_0x48c71c(0x135)]: _0x48c71c(0x136)
        };
    } else {
        console[_0x48c71c(0x12f)](_0x48c71c(0x137));
        return {
            [_0x48c71c(0x131)]: _0x48c71c(0x138),
            [_0x48c71c(0x133)]: _0x48c71c(0x139),
            [_0x48c71c(0x135)]: null
        };
    }
}

Transformed Code (with String Array and XOR Encoding)

const _0x3f7b = [
    'TN5c7uA=', // Encoded: 'admin'
    'KL9F6sZ0pH4xVq3R', // Encoded: 'securePassword123'
    'H9k=', // Encoded: 'log'
    'UM1D4pX7tRw3Je8nKv6h', // Encoded: 'Authentication successful'
    'Za3v', // Encoded: 'status'
    'Vf7x', // Encoded: 'success'
    'Hn9p4s', // Encoded: 'message'
    'LK3R8pB1nMs5Ke2z', // Encoded: 'Welcome to the dashboard'
    'Nf2c', // Encoded: 'token'
    'JM9E5qNwtR3xVe8z', // Encoded: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'
    'UM1D4pX7tRw3Je8nF', // Encoded: 'Authentication failed'
    'Ws7i', // Encoded: 'error'
    'GP5T6sZ8tLw4Re9uKo8' // Encoded: 'Invalid username or password'
];

function _0x21e4(_0x5df722, _0x21b33f) {
    const _0x3f7bc5 = _0x3f7b;
    _0x21e4 = function(_0x21e48e, _0x4b8671) {
        _0x21e48e = _0x21e48e - 0x1af;
        let _0x166332 = _0x3f7bc5[_0x21e48e];
        if (_0x21e4['xorKey'] === undefined) {
            _0x21e4['xorKey'] = 0x7B;
            _0x21e4['decode'] = function(_0x276a3b) {
                const _0x549a3d = atob(_0x276a3b);
                let _0x42f8a7 = '';
                for (let _0x329a14 = 0; _0x329a14 < _0x549a3d.length; _0x329a14++) {
                    _0x42f8a7 += String.fromCharCode(_0x549a3d.charCodeAt(_0x329a14) ^ _0x21e4['xorKey']);
                }
                return _0x42f8a7;
            };
        }
        return _0x21e4['decode'](_0x166332);
    };
    return _0x21e4(_0x5df722, _0x21b33f);
}

function authenticateUser(username, password) {
    const _0x3e64f2 = _0x21e4;
    const _0x1fd2ac = _0x3e64f2(0x1af);
    const _0x2e7bba = _0x3e64f2(0x1b0);
    
    if (username === _0x1fd2ac && password === _0x2e7bba) {
        console[_0x3e64f2(0x1b1)](_0x3e64f2(0x1b2));
        return {
            [_0x3e64f2(0x1b3)]: _0x3e64f2(0x1b4),
            [_0x3e64f2(0x1b5)]: _0x3e64f2(0x1b6),
            [_0x3e64f2(0x1b7)]: _0x3e64f2(0x1b8)
        };
    } else {
        console[_0x3e64f2(0x1b1)](_0x3e64f2(0x1b9));
        return {
            [_0x3e64f2(0x1b3)]: _0x3e64f2(0x1ba),
            [_0x3e64f2(0x1b5)]: _0x3e64f2(0x1bb),
            [_0x3e64f2(0x1b7)]: null
        };
    }
}

When to Use

String Array protection is beneficial in almost all scenarios and is recommended as a baseline protection for any application. It's particularly valuable for:

  • Sensitive constants: Hiding API keys, endpoints, and other sensitive values
  • User interface text: Making it harder to identify screens and functionality
  • Error messages: Obscuring detailed error information that might help attackers
  • Business logic: Making the overall code functionality harder to comprehend

For optimal results:

  1. Use a higher threshold (0.8+) for critical code containing sensitive information
  2. Use the default XOR encoding for a good balance of security and performance
  3. Consider using RC4 encoding for highly sensitive data where performance is less critical
  4. Use function wrappers for higher security at the cost of performance

Compatibility Notes

String Array protection is highly compatible with all JavaScript environments:

  • Browser compatibility: Works in all browsers with minimal performance impact
  • Mobile performance: The default XOR implementation has minimal impact on performance
  • Bundle size: Increases bundle size, but the impact is usually manageable
  • Node.js: Fully compatible with server-side JavaScript

When using RC4 encoding, avoid also enabling Unicode Escape Sequence as this can greatly increase code size. The XOR encoding is recommended for most use cases as it provides good security with better performance.


For maximum security, combine String Array with:

Force Transform Strings

The forceTransformStrings option allows you to ensure specific strings are always transformed into the string array, even if they would normally be excluded by the stringArrayThreshold setting:

{
  "stringArray": true,
  "stringArrayThreshold": 0.5,         // Only 50% of strings will be transformed
  "forceTransformStrings": [
    "license-key",                     // Exact match
    "api-\\w+",                        // RegExp pattern for API strings
    "secret_token_\\d+"                // RegExp pattern for token strings
  ]
}

This option accepts an array of strings or regular expression patterns that identify string literals you want to ensure are always transformed, regardless of the stringArrayThreshold setting.

Important Notes:

  • The forceTransformStrings option affects only strings that wouldn't normally be transformed by the stringArrayThreshold setting
  • This option has priority over the reservedStrings option (strings matching both will be transformed)
  • However, it doesn't override conditional comments (if you've explicitly disabled obfuscation for a section with comments)

This is particularly useful when you want most string transformations to be controlled by the threshold percentage, but you have specific sensitive strings that must always be protected.

Performance Considerations

String Array protection can impact runtime performance, especially with additional options enabled:

  • Low Impact: Basic String Array with no encoding
  • Medium Impact: String Array with encoding and moderate threshold (0.5-0.7)
  • High Impact: String Array with encoding, high threshold (>0.8), and transform options

For performance-sensitive applications, consider using a lower threshold value and limiting encoding to critical strings.

Examples

Basic Protection

{
  "stringArray": true,
  "stringArrayThreshold": 0.75
}

Maximum Protection

{
  "stringArray": true,
  "stringArrayThreshold": 1,
  "stringArrayEncoding": ["rc4"],
  "stringArrayRotate": true,
  "stringArrayShuffle": true,
  "stringArrayWrappersType": "function",
  "stringArrayWrappersCount": 5
}

Balanced Approach

{
  "stringArray": true,
  "stringArrayThreshold": 0.6,
  "stringArrayEncoding": ["base64"],
  "forceTransformStrings": [
    "license",
    "api-key",
    "token"
  ],
  "reservedStrings": [
    "https://cdn",
    "data:image"
  ]
}

By properly configuring String Array protection, you can significantly increase the difficulty of reverse engineering your JavaScript code while managing the performance impact.

Previous
Dead Code Injection