Skip to content

Uncaught ReferenceError: test is not defined #804

Closed

Description

@rafaeleyng

version: tested with both 2.6.3 and 2.8.0

I'm getting a Uncaught ReferenceError: test is not defined that I cannot understand. I've done a lot of testing and I can tell so far:

  • seems to be related to code using async
  • the error always is caused by trying to use a variable called exactly test
  • the error seems to happen in different parts of my code, changing the point where it happens as I produce different builds (I'm using the webpack-obfuscator for this)
  • I don't have a property or variable named test in any part of my code
  • the error only happens if controlFlowFlattening: true AND selfDefending: true
  • I'm testing using the seed option. With some seeds the error never occurs; with others, it always occurs

Obfuscated snippet (this is just the top of the file, there is more functions later but they don't seem to be relevant here - I can send it if needed, preferably privately). The error occurs at test['constructor']:

import _0x3317b2 from '../conf';
function _await(_0x55ad0d, _0x74fe2a, _0x56a29b) {
    if (_0x56a29b)
        return _0x74fe2a ? _0x74fe2a(_0x55ad0d) : _0x55ad0d;
    return (!_0x55ad0d || !_0x55ad0d['then']) && (_0x55ad0d = Promise['resolve'](_0x55ad0d)),
    _0x74fe2a ? _0x55ad0d['then'](_0x74fe2a) : _0x55ad0d;
}
function _async(_0x39e875) {
    const _0x256514 = function() {
        let _0x57d75a = !![];
        return function(_0x2ab882, _0x3ca6b0) {
            const _0x30cf38 = _0x57d75a ? function() {
                if (_0x3ca6b0) {
                    const _0x46535c = _0x3ca6b0['apply'](_0x2ab882, arguments);
                    return _0x3ca6b0 = null,
                    _0x46535c;
                }
            }
            : function() {}
            ;
            return _0x57d75a = ![],
            _0x30cf38;
        }
        ;
    }()
      , _0x282d2a = _0x256514(this, function() {
        const _0x246224 = function() {
            const _0x3fc13d = test['constructor']('return\x20/\x22\x20+\x20this\x20+\x20\x22/')()['constructor']('^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}');
            return !_0x3fc13d['test'](_0x282d2a);
        };
        return _0x246224();
    });
    return _0x282d2a(),
    function() {
        for (var _0x150116 = [], _0x3429a4 = 0x0; _0x3429a4 < arguments['length']; _0x3429a4++) {
            _0x150116[_0x3429a4] = arguments[_0x3429a4];
        }
        try {
            return Promise['resolve'](_0x39e875['apply'](this, _0x150116));
        } catch (_0x30fc7a) {
            return Promise['reject'](_0x30fc7a);
        }
    }
    ;
}

export const getResult = _async(function(_0x1f8d7f) {
    const _0x5c05b5 = {
        'ApnJM': 'BACKEND_URL'
    }
      , _0x544bdb = _0x3317b2(_0x5c05b5['ApnJM']) + '/result/' + _0x1f8d7f
      , _0xe8ce2e = {
        'method': 'GET',
        'credentials': 'include'
    };
    return _await(fetch(_0x544bdb, _0xe8ce2e), function(_0x1632a6) {
        if (!_0x1632a6['ok'])
            throw new CustomError(_0x1632a6['status']);
        return _0x1632a6['json']();
    });
});

// there is more code, but I don't think is needed

Config (my intention is to enable everything that is false below, I've just disabled it to isolate the problem):

options: {
    seed: 2,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 0.1,
    identifierNamesGenerator: 'hexadecimal',
    selfDefending: true,
    splitStrings: false,
    shuffleStringArray: false,
    rotateStringArray: false,
    stringArray: false,
}

Activity

  1. sanex3339 commented on Nov 9, 2020

    @sanex3339
    Member

    Can you provide a minimal standalone reproducible example that will show this error after obfuscation?
    Also what obfuscator version are you using?

  2. rafaeleyng commented on Nov 9, 2020

    @rafaeleyng
    Author

    The original code looks very much like this (I've just removed the body and renamed funcA and funcB):

    import conf from '../conf'
    
    export function CustomError(status, responseBody) {
      this.status = status
      this.responseBody = responseBody
    }
    
    export const funcA = async () => {
    }
    
    export const funcB = async () => {
    }
    
    export const getResult = async id => {
      const url = `${conf('BACKEND_URL')}/result/${id}`
      const options = { method: 'GET', credentials: 'include' }
      const response = await fetch(url, options)
    
      if (!response.ok) throw new CustomError(response.status)
    
      return response.json()
    }

    With these changes, I'm getting at the same point I got Uncaught ReferenceError: regExp is not defined. The obfuscated code is (the error happens at !regExp['test'](_0xd4ed39):

    import _0x35757e from '../conf';
    function _await(_0x428c5c, _0x54d433, _0x170ae2) {
        if (_0x170ae2)
            return _0x54d433 ? _0x54d433(_0x428c5c) : _0x428c5c;
        return (!_0x428c5c || !_0x428c5c['then']) && (_0x428c5c = Promise['resolve'](_0x428c5c)),
        _0x54d433 ? _0x428c5c['then'](_0x54d433) : _0x428c5c;
    }
    function _async(_0x12c610) {
        const _0x1a706a = function() {
            let _0x46347f = !![];
            return function(_0x493357, _0x4ff391) {
                const _0x3b7845 = _0x46347f ? function() {
                    if (_0x4ff391) {
                        const _0x1a9bfb = _0x4ff391['apply'](_0x493357, arguments);
                        return _0x4ff391 = null,
                        _0x1a9bfb;
                    }
                }
                : function() {}
                ;
                return _0x46347f = ![],
                _0x3b7845;
            }
            ;
        }()
          , _0x1bc5f4 = _0x1a706a(this, function() {
            const _0x34d53b = function() {
                const _0x157caf = _0x34d53b['constructor']('return\x20/\x22\x20+\x20this\x20+\x20\x22/')()['constructor']('^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}');
                return !regExp['test'](_0xd4ed39);
            };
            return _0x34d53b();
        });
        return _0x1bc5f4(),
        function() {
            for (var _0x8a2aec = [], _0x12da42 = 0x0; _0x12da42 < arguments['length']; _0x12da42++) {
                _0x8a2aec[_0x12da42] = arguments[_0x12da42];
            }
            try {
                return Promise['resolve'](_0x12c610['apply'](this, _0x8a2aec));
            } catch (_0x328c07) {
                return Promise['reject'](_0x328c07);
            }
        }
        ;
    }
    export function CustomError(_0x5176df, _0x1267da) {
        this['status'] = _0x5176df,
        this['responseBody'] = _0x1267da;
    }
    export const funcA = function() {
        return _await();
    };
    export const funcB = function() {
        return _await();
    };
    export const getResult = _async(function(_0x4bad58) {
        const _0x1426bc = {
            'uSDsB': function(_0x15aa3b, _0x4346cf, _0x48bc90) {
                return _0x15aa3b(_0x4346cf, _0x48bc90);
            }
        }
          , _0x4e7e71 = _0x35757e('ROYALE_URL') + '/result/' + _0x4bad58
          , _0x23ce6c = {
            'method': 'GET',
            'credentials': 'include'
        };
        return _await(_0x1426bc['uSDsB'](fetch, _0x4e7e71, _0x23ce6c), function(_0x219bd3) {
            if (!_0x219bd3['ok'])
                throw new CustomError(_0x219bd3['status']);
            return _0x219bd3['json']();
        });
    });
  3. rafaeleyng commented on Nov 9, 2020

    @rafaeleyng
    Author

    @sanex3339 I've added the version to the top of the original post. Sorry for forgetting that.

    I'll try to setup a repo to reproduce the error and ping back in a few minutes.

  4. sanex3339 commented on Nov 9, 2020

    @sanex3339
    Member

    This is very strange. Need a repo from you.

  5. rafaeleyng commented on Nov 9, 2020

    @rafaeleyng
    Author

    Nice, I'm preparing it. One thing I've noticed already preparing the repo, if (instead of importing my import conf from '../conf') I just define const conf = () => {}, the error goes away.

  6. rafaeleyng commented on Nov 9, 2020

    @rafaeleyng
    Author

    @sanex3339 Here we go: https://github.com/rafaeleyng/demo-obfuscator

    I've tweaked a lot and is very strange. The error occurs on myClient.js. Changing mostly everything there will cause the error to change or disappear. Like putting funcA before funcB, or changing the string BACKEND_URL_2 to BACKEND_URL_1.

    Also, changing the string BACKEND_URL_2 to other numbers at the end, I was able to get a different error (fn is not defined)

  7. rafaeleyng commented on Nov 9, 2020

    @rafaeleyng
    Author

    Adding garbage at the end of that string I also got regEx is not defined

  8. sanex3339 commented on Nov 9, 2020

    @sanex3339
    Member

    Minimal reproducible example:

        const code: string =  `
            function foo () {};
            
            foo();
        `;
    
        for (let i = 0; i < 1000; i++) {
            let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
                code,
                {
                    stringArray: false,
                    selfDefending: true,
                    controlFlowFlattening: true,
                    controlFlowFlatteningThreshold: 0.1,
                    splitStrings: false,
                    seed: i
                }
            ).getObfuscatedCode();
    
            try {
                console.log(eval(obfuscatedCode));
            } catch (error) {
                console.log(error, obfuscatedCode);
                break;
            }
        }
    
  9. sanex3339 commented on Nov 9, 2020

    @sanex3339
    Member

    Oh. It was hard to catch. PR will be ready soon.

  10. sanex3339 commented on Nov 10, 2020

    @sanex3339
    Member
  11. rafaeleyng commented on Nov 10, 2020

    @rafaeleyng
    Author

    It works perfectly! Thanks a lot 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions