NFLabs. エンジニアブログ

セキュリティやソフトウェア開発に関する情報を発信する技術者向けのブログです。

C++でインタプリタ言語を作っている話

はじめに

この記事は、NFLaboratories Advent Calendar 2024 12/11 の記事です。 https://adventar.org/calendars/10492

こんにちは。研究開発部の堺です。 今回は私が個人的に取り組んでいるC++でインタプリタ言語を作っている話を書いていこうと思います。

なぜインタプリタ言語を作っているのか

企業とは関係なく個人的に JavaScript実行エンジン の V8 にコントリビュートしたい、あわよくば脆弱性を見つけてCVEを取得したいと常日頃考えています。 少し過去の話ですが内部のJITコンパイラに対してファジングテストを実行なんてことをしたこともありました。 https://zenn.dev/famasoon/articles/932a504def7182

また、英語ですが、教材を見てV8の脆弱性を発見するアプローチについて学習する機会もありました。 https://academy.fuzzinglabs.com/introduction-browser-fuzzing

と、ここまでやったあたりで「どうせホワイトボックスだしV8の内部実装をしっかりと理解して脆弱性を探索したほうが効率が上がるのでは?」と思い至り、V8のソースコードを読もうとします。 しかし、V8のソースコードはかなり巨大で、C++で言語を実装することについて詳しくないと何が何だか全然わからないコードでした。 https://chromium.googlesource.com/v8/v8.git

コードリーディングをすれば良い、と言えばそれまでなのですが、今回は学習のために経験のないC++でプログラミング言語を実装してみることにしました。

学習の道のり

経験のある言語は以下の通りです。

  • C
  • x86 アセンブリ
  • Python
  • Java
  • Ruby
  • PHP
  • JavaScript/TypeScript
  • Golang
  • Rust

先述した通りC++での開発経験はないです。 そのためまずはC++の学習を始めました。

最初の学習

社内でC++の学習で何か役に立つ資料ありますか?と相談をしたところ https://ezoeryou.github.io/cpp-intro/ をおススメしていただきました。 このWebサイトはC++の入門としてはうってつけで基礎的な内容を重点的に学ぶことができました。

応用編

次に言語実装について学習したいなと考えました。 幸いなことに簡単なインタプリタなら下記の本を読みGolangで実装したことがあります。 https://www.oreilly.co.jp/books/9784873118222/

この本の内容をベースに実装している言語をC++に移植し始めました。

現状

成果物です。 https://github.com/famasoon/monkeycpp

ちゃんと動くの?といったところですが、インタプリタを起動して簡単な関数を動かすことくらいなら問題なく動作します。

>let x = fn(i,j){return i + j};
>let test = x(10,10);
>test
>20

CMakeを使って単体テストもしっかり行っています。 もうちょっとリファクタリングとかバグフィックスをしたら完成といったところです。

言語実装をふまえて

目標としているV8は今回作ったものよりも複雑でJITコンパイルしたり、WASM対応をしたりと、まだまだ学習するものは多いのですが、C++で言語を実装したのでちょっとしたコードリーディングならできるようになりました。 これから更に学習を重ねV8の内部実装に迫っていけたらなと思います。

おわりに

C++でインタプリタ言語を作っていることを紹介しました。 本記事のスコープ外ですが、V8のバグ収集やエクスプロイト開発、サンドボックスエスケープの方法などは収集しているので、これから活用していければと思っています。