作者:areuu
原文鏈接:https://mp.weixin.qq.com/s/qxhmcpATMklTvvvb7ccVvg

fuzzilli IL compiler 是將javascript 編譯為fuzzilli 中間語言的工具,可以在fuzz 時導入到fuzzilli ,作為初始化的語料庫。

不過看readme 的說明以及dockerfile 的安裝,我這邊是不容易安裝好,版本也有點老,然后想想自己應該后面要擴展下,于是選擇將ocaml 版本適配為4.14.0 最新的官方發布版,4.15.0 有點新不敢用

ocaml 4.14.0 安裝

opam init -a --disable-sandboxing
opam repo add dra27 'git+https://github.com/dra27/opam-repository.git#glibc-2.34-4.10+'
opam repository add dra27 --all-switches --set-default
opam switch create 4.14.0
eval $(opam env --switch 4.14.0)

為了安裝flow 解析庫,先安裝依賴,opam install 逐步安裝下列包

base
core_kernel
fileutils
dtoa
visitors

之后可以直接安裝,應該不會出錯

opam pin add -y flow_parser https://github.com/facebook/flow.git\#v0.192.0

安裝完后,進入到compiler 目錄,修改package.json

{
  "name": "fuzzilli_compiler",
  "version": "0.1",
  "esy": {
    "build": "dune build -p #{self.name}"
  },
  "dependencies": {
    "@opam/core": "*",
    "@opam/ocaml-lsp-server": "*",
    "@opam/ocaml-protoc": "*",
    "@opam/core_unix": "*",
    "flow_parser": "*",
    "ocaml": "~4.14.0",
    "@opam/alcotest": "*",
    "@opam/uuidm": "*"
  },
  "resolutions": {
    "flow_parser": "link:/home/uuu/.opam/4.14.0/.opam-switch/sources/flow_parser/flow_parser.opam"
  },
  "scripts": {
    "build-pbs": "./build-pbs.sh"
  }
}

注意添加 core_unix ,flow_parser,ocaml 版本要求,以及flow_parser resolutions 路徑

最后要修改下flow_parser.opam,我這邊路徑是 /home/uuu/.opam/4.14.0/.opam-switch/sources/flow_parser/flow_parser.opam ,添加一些包的依賴

...
depends: [
        "base" {build}
        "core_kernel" {build}
        "fileutils" {build}
        "dtoa" {build}
        "visitors" {build}
  "ocaml" {>= "4.14.0"}
  "ocamlfind" {build}
  "ocamlbuild" {build}
  "ppx_deriving" {build}
  "ppx_gen_rec" {build}
  "sedlex" {>= "2.3"}
  "wtf8"
]
...

修改一下源碼 bin/fuzzilli_compiler.ml,在4.14.0 ocaml 版本中取消了Filename和Comand,需要改為Filename_unix, Command_unix

let command =
  let open Core in
  Command.basic
    ~summary:"Compile a JS source file to Fuzzil"
    Command.Let_syntax.(
      let%map_open
        infile = (anon ("infile" %: Filename_unix.arg_type))
        and outfile = (anon ("outfile" %: string))
        and emit_ast = flag "-ast" no_arg ~doc: "Print the Flow_ast"
        and emit_builtins = flag "-builtins" no_arg ~doc: "Print all builtins encountered"
        and v8_natives = flag "-v8-natives" no_arg ~doc: "Include v8 natives, as funtions without the leading %. Requires the builtins be included in the fuzzilli profile for v8. Currently only uses a hardcoded list in util.ml"
        and use_placeholder = flag "-use-placeholder" no_arg ~doc: "Replaces each unknown builtin with 'placeholder'."
    in
    fun () -> do_compile infile outfile ~emit_ast ~emit_builtins ~v8_natives ~use_placeholder)

let () =
  Command_unix.run command

bin/dune 文件,需要額外opam install core_unix

(executable
  (name fuzzilli_compiler)
  (public_name fuzzilli_compiler)
  (libraries core core_unix.command_unix core_unix.filename_unix compiler flow_parser ocaml-protoc proto str)
  (preprocess (pps ppx_jane ppx_deriving ppx_deriving.show)))

以及src/VariableScope.ml,src/translate.ml,在0.192.0 版本的flow 中PropertyPrivateName 結構發生改變,id 取消,改為name ,這兩個文件都需要改幾處

and get_expression_useData_member (memb_exp: ('M, 'T) Flow_ast.Expression.Member.t) =
    let sub_data = get_expression_useData memb_exp._object in
    let property_data = match memb_exp.property with
        PropertyIdentifier (_, i) -> build_use_data i.name
        | PropertyPrivateName (_, p) ->
          (*  let (_, i) = p in  changed in v0.192.0 *)
            build_use_data p.name   (* this *)
        | PropertyExpression pe -> get_expression_useData pe

最后一發入魂

esy install && esy build

?  Compiler git:(main) find . -name '*.exe'
./_build/default/.ppx/1a740f3d096b3e068997dd58c8517124/ppx.exe
./_build/default/.ppx/be48c90307a99d7a582c7fc983be9816/ppx.exe
./_build/default/.ppx/0bb5094b13567c3c4e1ee33245b80e63/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-4e107294/default/.ppx/1a740f3d096b3e068997dd58c8517124/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-4e107294/default/.ppx/be48c90307a99d7a582c7fc983be9816/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-4e107294/default/.ppx/0bb5094b13567c3c4e1ee33245b80e63/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-68248c3f/default/bin/fuzzilli_compiler.exe
./_esy/default/store/b/fuzzilli__compiler-68248c3f/default/.ppx/1a740f3d096b3e068997dd58c8517124/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-68248c3f/default/.ppx/be48c90307a99d7a582c7fc983be9816/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-68248c3f/default/.ppx/0bb5094b13567c3c4e1ee33245b80e63/ppx.exe
./_esy/default/store/b/fuzzilli__compiler-68248c3f/default/test/test.exe

可看到生成 fuzzilli_compiler.exe

?  Compiler git:(main) ./fuzzilli_compiler.exe -h
Compile a JS source file to Fuzzil

  fuzzilli_compiler.exe INFILE OUTFILE

=== flags ===

  [-ast]                     . Print the Flow_ast
  [-builtins]                . Print all builtins encountered
  [-use-placeholder]         . Replaces each unknown builtin with 'placeholder'.
  [-v8-natives]              . Include v8 natives, as funtions without the
                               leading %. Requires the builtins be included in
                               the fuzzilli profile for v8. Currently only uses
                               a hardcoded list in util.ml
  [-build-info]              . print info about this build and exit
  [-version]                 . print the version of this build and exit
  [-help], -?                . print this help text and exit

不過看下他內置的builtins ,目前這工具感覺有點ji,可以自己加點東西。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/2011/