Sunday 20 November 2011

Javascript Obfuscation - The numbers

The numbers

In this section we will explore the different ways we can get number values. The way javascript handles number and operator have a good set of particular behavior that can be surprising and we will see those behavior in detail. Also numbers in javascript only exist in one flavor 64-bit float. Whether we are talking about 1 or 0.5, it's always a 64-bit float.

Number declaration

There are multiple way of declaring a number, most of them are simple, but it can always be interesting to use a variety of them to confuse the reader.

 Notation  Expression 
Decimal100
Octal0144
Hexadecimal0x64

Using parseInt

The "parseInt" function has two particularities that are very interesting for obfuscation. The first one is that if you don't pass a 2nd argument to the function, it won't default to base 10, but it will try to guess the base of your number.

parseInt("10") === 10
parseInt("010") === 8


The second particularity of the function is that you can pass anything as a first argument including object and function. When you pass it something that isn't a string as the first argument, it will internally cast it as a string. Here are few examples that are using this point :

parseInt([].sort, 16) === 15 // function ... with base 16
parseInt([][[]], 31) === 26231474015353 // undefined ... with base 31


Casting anything to number

It's also possible to obtain number with the "+" operator as an unary operator. The result of the operation will be 1 or 0, expect if what you are prefixing is a number or a string. In fact for anything that isn't a string or a number the result of the operation is based on whether what you are trying to cast is truthy of falsy. Here's a good summary of what you can do with it :

Expression Result
+[]0
+""0
+!![]1
+null0
+true1
+false0
+"10"10
+"010"10

Note: I left the last one to point out that the "+" operator will always try to cast a number with base 10.

1 comment: