Explore "Full-Stack" in depth!

情報系の専門学校で、今は機械学習に的を絞って学習中。プログラミングを趣味でやりつつ、IT系のあらゆる知識と技術を身に付けるべく奮闘中。

ELFバイナリに含まれるnullセクション/ヘッダの真実…?

概要

gccの吐くELFバイナリを見てみると、セクションヘッダテーブルの先頭に NULLヘッダ を見つけます。
これってなんだろう? ってずっと疑問だったのですが、今日理由がわかったのでそれについて述べたいと思います。

厳密には、 nullセクション も含まれています。
サイズが0のセクション と、それに対応する 全てのメンバが0のヘッダ が存在します。
また本記事で取り上げるnullセクション/ヘッダの意味は私がなんとなくそうじゃね?と思ったもので、
もっと歴史的な経緯、重要な意味が含まれているかも知れません。
その場合は教えて下さい。

続きを読む

Seccamp2019でCコンパイラ実装に取り組みました

  • 概要
  • 応募課題について
    • 問1
    • 問2
    • 問3
  • 集中開発コースについて
  • 成果物とその進捗について
    • 事前学習期間
    • 当日
  • 総評

概要

セキュリティ・キャンプ全国大会2019に参加しました!
集中開発コースの中にある 「Y-Ⅱ Cコンパイラを自作してみよう!」のテーマに応募し、
普段独学では絶対に出来ない事を多く経験し、
尊敬する講師の方々からたくさんの事を教えて頂きました。

セキュリティ・キャンプ(以下seccamp)とは?と思った方は
こちらのページを参考にしてください!

この記事では、

  • 応募課題はどんな内容のものだったか
    • 提出したものをそのまま載せます
  • 集中開発コースはどのようなものだったか?
    • 特に Yトラックについて詳しく
  • 成果物の進捗、所感
  • 総評

という流れでお話できればと思います。

来年以降seccampに参加しようとしている方の参考になれば幸いです。

注意:応募課題についてですが、
応募時点での状況、応募時点での知識を元にした内容が書かれています。
コンパイラの知識として間違っているものもあり、
また現在はラボユースとして活動していない等、
いくつか現時点とは異なる部分もあります。ご了承ください。

続きを読む

ABC137にHaskell縛りで参加しました!

概要

随分お久しぶりですね。 数カ月ぶりに記事を更新します。
今回は ABC137 に参加しました。

Haskell縛り ということで参加した本ABCですが、
非常に有意義なものになりました。
ここでは自分が解けた問題、ギリギリ解けなかった問題について取り上げます。

Haskellで競プロをやっている人の参考になれば幸いです。


続きを読む

オブジェクトファイルのシンボルテーブルを最低限理解する。

目次

  • 目次
  • 概要
    • 対象読者
  • 本題
    • ELFフォーマット復習
  • シンボルテーブル
    • シンボル名 name
    • シンボルの情報を格納する info
      • ST_BIND
      • ST_TYPE
    • シンボルの可視性 Other
    • シンボルの実体 Value
  • 総評

概要

お久しぶりです。
最近やりたい事が沢山あってブログをかけずにいましたが、

に述べている通りです。

今日はELFバイナリに埋め込まれるシンボルテーブルについて軽く解説しようと思います。
自作コンパイラとかやってる人には ほぼ必須の知識ですし、
バイナリ解析( Exploitation勢含む)が好きな人には楽しいお話だと思います。

今回の記事を作成する上で、

docs.oracle.com

こちらのサイトを参考にしました。
ご存知Oracle社のドキュメントなので安心出来ますね。

解説中に登場するソースコードは基本的にGolangで記述されています。
対応する構造体等は /usr/include/elf.h に記載されているので参考にしてください。

対象読者

  • バイナリ解析大好きな人
    • でも触りはじめたばかりであまり良くわからない人
  • ネイティブコンパイラの自作やってる人
    • アセンブリコードの生成だけではなく機械語まで吐き出したい人
    • 正直 この方面の人の為の記事
続きを読む

C言語の文字列はどこに?-ELFバイナリに見る実行プログラムの挙動-

目次

  • 目次
  • 概要
  • .dataに格納される文字列
    • .dataセクションとは
  • .rodataに書き込まれる文字列
  • x64命令セット、movabs
  • おまけ:mallocによるヒープ領域のアロケート
  • 総評

概要

※注意!

Twitterでもご指摘があったように、
本記事はC言語の習熟度が低い人間
いろいろ試行錯誤しながらまとめたものになります。

あくまで勉強の一環として
作成した記事であるという事を前提に考えていただければと思います。

C言語で文字列の扱いにこまるという方は多いです。
私もコードを書いていてよくSIGSEGVで落ちることがあります。
それは単純にC言語に慣れていないだけなんですが…。

今回は自身が言語処理系の勉強をしているだけあって、
C言語は文字列をどのように管理しているか?という疑問を持ちました。

様々なコードを書きながら、
ELFバイナリがどのように文字列を保有しているのかについて探っていきます。

以下の点に注意して読み進めてください。

  • 指摘された内容については修正しましたが、正確性に欠ける可能性があります。
  • 示されるソースコードについてはC言語の優れたコーディング方法を示すというわけではない
    • あくまで 挙動を確認するため
続きを読む

フルスクラッチによるセルフホスティングCコンパイラ自作日記#1

目次

概要

以前から rui314/9ccをGoで再実装する勉強法を取っていた私ですが、

drumato.hatenablog.com

に述べたように、
Cプログラミングに慣れたいということと、
単純に自分で試行錯誤しながら作ってみたいというところから、
フルスクラッチコンパイラ自作をスタートしました。

github.com

ルールとしては、

  • C言語のコードは普通に調べる
    • ベストプラクティスを吸収したり
  • コンパイラ実装に関連するコードは、あくまでも 参考程度に
    • 概念・設計は参考にしてもいい
    • あくまで 自分の力で、 試行錯誤 することを念頭に

ことを掲げています。

今回は 字句解析コードについてお話します。

はてなブログMarkdownパーサーが壊れてるっぽいので、
全てGistのコード引用で紹介していきます。


本題

ヘッダファイル omo.h

まずはヘッダファイルを見ていきます。

例によって、全体のコードを貼った後に各コードについて解説を加えていきます。

util.c

様々な処理を簡易的に利用するための自作ライブラリという感じです。

ファイルストリームを開いたり、
内容を取得したり、ファイル情報を取得したり。

後は配列の長さを調べる関数とか、
文字列のチェックを行う関数ですね。

util.cに記述された実際の定義を見てみます。

このようにutilityを充実させることがプログラミングをスムーズに進めるコツだと思っていて、
普段からちょっとした処理を関数に切り出すようにしています。

今回一番重要なのは、

ですね。
これにはCプログラミングを行う上で注意しなければいけない点が詰まっています。

についてですが、

まずは(type*)malloc(size_t nmemb);のように
汎用ポインタを即座にキャストします。

これは JPCERTのセキュアコーディング規約 に記載がありました。

www.jpcert.or.jp

また、fread()関数はnull終端が保証されていない為に、
手動で終端に \0を入力する必要があります。

ヌルバイトを挿入しないことによる脆弱性については、

codezine.jp

が参考になると思います。

また、先述した セキュアコーディング規約にも、

www.jpcert.or.jp

www.jpcert.or.jp

www.jpcert.or.jp

などに、
nullバイトに関する記述がありました。


token

ここではトークンの構造体を定義しつつ、
enumによって定数を定義しています。

これは 種類を識別するため に使われるもので、
int型によって列挙しています。

トークンの構造体の各フィールドを紹介します。

  • ty列挙したトークンの種類の定数が代入される
  • intvalリテラルの値を評価し、ここに代入
    • floatval も未対応ではあるが使い方は同じ
    • 具体的な代入方法については後述
  • str… 文字列リテラル保有場所
    • これについても代入方法は後述
  • input… 具体的にどのような文字列をトークンとしたのか、というフィールド
    • 例を見せます

main.c

Token->inputをダンプしてみましょう。

main.cを見てみます。

-tオプション によって表示する事が出来るようになっています。

f:id:orangebladdy:20190502110306j:plain

16進数もきちんと表示できている事がわかるかと思います。

因みに-sオプションではcat <filepath>とした出力と同じものが得られます。


logger.c

これもほぼutil.cの考え方と同じです。

ログファイルに出力する関数を置いています。
これは ファイルが開けなかった時等のエラーをダンプするものではなく、

コンパイル時に入力されたコードの良し悪しを判断して、
Warningのような役割でログを吐くようにしようと思っています。

ほぼ手を付けていないので結構無駄がありそうですね。
変数宣言相当多いかも。


目玉:lex.c

今回の本題、 字句解析のコードを見ていきます。

コード量めちゃくちゃ多いので気をつけてくださいね。

  • number literal
  • string literal
  • identifier

等を解析する関数について見ていきましょう。

char型やり忘れてたので後でやります。

因みにこれら、
char の種類を判別する関数は、

ctype.h に定義されているんですよね。既に。

どうせなら自分でやろうと思って作りましたが、
その関数を使ったほうがいいと思います。

現在見ているASCIIコードが範囲内かどうかチェックしながら、
readchar()によってオフセットを進めるという典型的な実装です。

token->intval = strtol(token->input, NULL, base);として文字列を変換し、
Token構造体に格納しています。

次に文字列リテラルですね。

実装はとてもシンプルです。

最後に識別子の解析ですが、
鋭い人ならわかると思いますがC言語の仕様に準拠していません。

要は途中で数字とかを許容できていないんですよね。
これは今日中に直します。

解析した識別子は、
lookup_identifier()という関数を用いて
予約語なのかユーザ定義なのかをチェックします。


総評

ここまでで実に3日ぐらいかかっています。

Cプログラミング本当に下手なんです…許してください。

とてもやりがいがあるので、少しずつですが頑張っていきます。

令和だし自身のやってること、やらなければいけないことを整理

目次

  • 目次
  • 概要
  • ここ最近やっていること
    • コンパイラ自作の実践
      • 何が足りない?
    • AttnGAN風T2Iモデルの実装
    • 何が足りない?
    • 自作OS
  • 具体的な勉強計画
  • 参考にしたい書籍
  • 総評

概要

元号、令和になりましたね。
あいも変わらず技術力が足りない私ですが、
これからも精進して強くなっていきます。

今回は 大きな節目ということで、
またもや 勉強計画を立てていこうと思います。

私はこの 定期的に振り返る事をとても大事にしていて、
勉強する中で常に具体的なイメージが持てると思っています。


続きを読む