Skip to content

Spidermonkey Debugging and Understanding

Lukas Hock edited this page Sep 9, 2022 · 1 revision

dis()

To get a better understanding of how Spidermonkey processes JS-code, we can use the dis() function. It is used to show information about a script/function and will (among other things) show us the generated bytecode.

Requirements

  • Configure .mozconfig to do a debug build (ac_add_options --enable-debug)
  • Build

Usage

Analyzing Scripts

  • Add dis() to the top of your script.
  • Run script (e.g. via BuildPath> dist/bin/js path/to/script)

Example

Running the script...

dis();

x = taint(10);
s = "Hello";

r = x + s;
r.taint;

will generate the following output...

loc     op
-----   --
main:
00000:  GetGName "dis"                  # dis
00005:  Undefined                       # dis undefined
00006:  CallIgnoresRv 0                 # dis()
00009:  Pop                             #
00010:  BindGName "x"                   # GLOBAL
00015:  GetGName "taint"                # GLOBAL taint
00020:  Undefined                       # GLOBAL taint undefined
00021:  Int8 10                         # GLOBAL taint undefined 10
00023:  Call 1                          # GLOBAL taint(...)
00026:  SetGName "x"                    # taint(...)
00031:  Pop                             #
00032:  BindGName "s"                   # GLOBAL
00037:  String "Hello"                  # GLOBAL "Hello"
00042:  SetGName "s"                    # "Hello"
00047:  Pop                             #
00048:  BindGName "r"                   # GLOBAL
00053:  GetGName "x"                    # GLOBAL x
00058:  GetGName "s"                    # GLOBAL x s
00063:  Add                             # GLOBAL (x + s)
00064:  SetGName "r"                    # (x + s)
00069:  Pop                             #
00070:  GetGName "r"                    # r
00075:  GetProp "taint"                 # r.taint
00080:  Pop                             #
00081:  RetRval                         #

Source notes:
 ofs line column    pc  delta desc       args
---- ---- ------ ----- ------ ---------- ------
  0:    1      0     0 [   0] step-sep
  1:    1      0     0 [   0] breakpoint
  2:    1      0    10 [  10] setline    lineno 3
  4:    3      0    10 [   0] step-sep
  5:    3      0    10 [   0] breakpoint
  6:    3      0    23 [  13] colspan    colspan 4
  8:    3      4    23 [   0] breakpoint
  9:    3      4    32 [   9] newline
 10:    4      0    32 [   0] step-sep
 11:    4      0    32 [   0] breakpoint
 12:    4      0    48 [  16] xdelta
 13:    4      0    48 [   0] setline    lineno 6
 15:    6      0    48 [   0] step-sep
 16:    6      0    48 [   0] breakpoint
 17:    6      0    70 [  22] xdelta
 18:    6      0    70 [   0] newline
 19:    7      0    70 [   0] step-sep
 20:    7      0    70 [   0] breakpoint
 21:    7      0    81 [  11] setline    lineno 23
 23:   23      0    81 [   0] colspan    colspan 9
 25:   23      9    81 [   0] breakpoint

Exception table:
kind               stack    start      end

Scope notes:
   index   parent    start      end

Analyze Function

  • Run JS-shell
  • Enter dis(f), where f is you function (e.g. dis((a,b)=>a+b))

Example

Executing the line...

dis((a,b)=>a+b)

will generate the following output...

flags: LAMBDA ARROW
loc     op
-----   --
main:
00000:  GetArg 0                        # a
00003:  GetArg 1                        # a b
00006:  Add                             # (a + b)
00007:  Return                          #
00008:  RetRval                         # !!! UNREACHABLE !!!

Source notes:
 ofs line column    pc  delta desc       args
---- ---- ------ ----- ------ ---------- ------
  0:    3      4     0 [   0] colspan    colspan 7
  2:    3     11     0 [   0] step-sep
  3:    3     11     0 [   0] breakpoint
  4:    3     11     7 [   7] colspan    colspan 2

Exception table:
kind               stack    start      end

Scope notes:
   index   parent    start      end