C++でHello worldを書いてみた

F
C++ で Hello world を書いてみた
2015/5/17
hotpepsi
自己紹介
 twitter: @hotpepsi
 趣味 : 競技プログラミング、
テニス、ピアノ
 キャッチフレーズ :
bootstrap から Bootstrap まで
デモ
 Ubuntu 14.04 x86-64
$ make -f hello_gen.mk
g++ -fno-operator-names -o hello_gen_gen
hello_gen_gen.cc
./hello_gen_gen > numbers.cc
g++ -o hello_gen hello_gen.cc
./hello_gen > _.c
cc -c -Wa,-R -w _.c
ld _.o -e _ -o hello
./hello
Hello, world!
ソースコードの先頭部分
_[]={
'('-'!'|((','-' ')<<('$'-' '))|
(('$'-' '|(('$'-' ')<<('$'-' ')))<<('('-' '))|
(('$'-' '|(('#'-'!')<<('$'-' '))|
((('/'-' ')<<('$'-' '))<<('('-' ')))<<('='-'-')),
...
記号プログラミング ( 二番煎じ )
C で記号プログラミング ( 復習 )
 記号のみでソースコードを記述
 int 型の配列 _ を定義して、 text セグメントに
配置してプログラムとして実行する
 エントリポイントを _start ではなく _ にする
ことでアルファベット (main) を書くことを回
避
 というような記号だけのソースコードを生成
するジェネレータを (C で ) 書いた
 強化点のご紹介
logo generator:
http://www.schoolidolproject.com/
強化点 1
 2010: C
 2015: C++ ← New!
マクロがテンプレートに
 2010: マクロ
 MAKE32(_4,_8,_6,_5,_6,_C,_6,_C), // Hell
 2015: テンプレート
 Symbolizer<‘H’>().s // H
マクロは地獄
struct Symbolizer
 Symbolizer<0>().s -> !””
 文字列 ( ポインタ ) の否定はゼロ
 Symbolizer<1>().s -> !!””
 ゼロの否定は 1
 Symbolizer<n>().s ->
Symbolizer<(n & 1)>().s |
(Symbolizer<(n>>1)>().s << 1)
テンプレートの優位性
 マクロ :
 0 から 16 までの値を用意する必要があった
 テンプレート :
 特殊化により、最低限 0, 1, n を用意すれば
、任意の数値が生成できる

例 : コンパイラにフィボナッチ数を計算させる
 0 の部分を生成しないようにしたり、 2, 3,
4, ... と個別に用意すれば、コードがコンパ
クトに
強化点 2
 2010: バイナリ (0xB8, 0x04, ...)
 2015: ニーモニック (mov ...)
C++ でバイナリ生成といえば ...
 Xbyak
 ニーモニックによる記述が可能に
 可読性と保守性の大幅な向上
 2010:
 MAKE32(_B,_8,_0,_4,_0,_0,_0,_0)
 2015:
 mov(eax, 4);
コード生成のステップ
1. コードジェネレータジェネレータ (C++)
 Xbyak でバイナリ生成
 バイナリを Symbolizer の呼び出しに置換
して出力
2. コードジェネレータ (C++)
 Symbolizer により記号化して出力
3. 記号だけのソースコード (C)
強化点 3
 2010: x86
 2015: x86 + x86-64
x86-64 対応 (1)
 32bit/64bit の両方に対応したい
が、 #ifdef は減らしたい
↓
 同じバイト列を生成するようにする
x86-64 対応 (2)
 x86 と x86-64 の命令バイト列はほぼ共
通
 64bit の即値代入命令を使い、後半
32bit に jmp 命令を埋め込むこと
で、 32bit モードの時だけ分岐する
 これにより同じバイト列で両方に対応
 デュアルアーキテクチャ
 x86 と x64 の両方で動くシェルコードを書いてみる
http://inaz2.hatenablog.com/entry/2014/07/06/185125
objdump: x86
$ objdump -d hello
hello: file format elf32-i386
Disassembly of section .text:
08048080 <_>:
8048080: c7 44 24 f0 48 65 6c 6c c7 44 24 f4 6f 2c 20 77 .D$.Hell.D$.o, w
8048090: c7 44 24 f8 6f 72 6c 64 66 c7 44 24 fc 21 0a ba .D$.orldf.D$.!..
80480a0: 0e 00 00 00 48 bb 01 00 00 00 eb 19 00 00 48 8d ....H.........H.
80480b0: 74 24 f0 bf 01 00 00 00 89 f8 0f 05 31 ff b8 3c t$..........1..<
80480c0: 00 00 00 0f 05 8d 4c 24 f0 b8 04 00 00 00 cd 80 ......L$........
80480d0: 31 db b8 01 00 00 00 cd 80 00 00 00 1...........
objdump: x86-64
$ objdump -d hello
hello: file format elf64-x86-64
Disassembly of section .text:
08048080 <_>:
8048080: c7 44 24 f0 48 65 6c 6c c7 44 24 f4 6f 2c 20 77 .D$.Hell.D$.o, w
8048090: c7 44 24 f8 6f 72 6c 64 66 c7 44 24 fc 21 0a ba .D$.orldf.D$.!..
80480a0: 0e 00 00 00 48 bb 01 00 00 00 eb 19 00 00 48 8d ....H.........H.
80480b0: 74 24 f0 bf 01 00 00 00 89 f8 0f 05 31 ff b8 3c t$..........1..<
80480c0: 00 00 00 0f 05 8d 4c 24 f0 b8 04 00 00 00 cd 80 ......L$........
80480d0: 31 db b8 01 00 00 00 cd 80 00 00 00 1...........
完全に一致
ファイルフォーマット以外は完全に
一致
コードジェネレータジェネレータ
Put St r i ng( const st d: : st r i ng &message) {
unsi gned i nt * dat a = ( unsi gned i nt * ) message. dat a( ) ;
mov( dwor d[ esp - 16] , dat a[ 0] ) ;
mov( dwor d[ esp - 12] , dat a[ 1] ) ;
mov( dwor d[ esp - 8] , dat a[ 2] ) ;
mov( wor d[ esp - 4] , dat a[ 3] ) ;
mov( edx, message. l engt h( ) ) ;
dec( eax) ;
mov( ebx, 1) ;
j mp( " @f " ) ;
add( byt e[ eax] , al ) ;
dec( eax) ;
l ea( esi , pt r [ esp - 16] ) ;
mov( edi , 1) ;
mov( eax, edi ) ;
syscal l ( ) ;
xor ( edi , edi ) ;
mov( eax, 60) ;
syscal l ( ) ;
L( " @@" ) ;
l ea( ecx, pt r [ esp - 16] ) ;
mov( eax, 4) ;
i nt 80h( ) ;
xor ( ebx, ebx) ;
mov( eax, 1) ;
i nt 80h( ) ;
}
スタック上にメッセージを
置く
(x86/x86-64 共通 )
x86-64 用コード
x86 用コード
https://github.com/firewood/test/blob/master/hello_gen_gen.cc
ソースコード
_[]={
'('-'!'|((','-' ')<<('$'-' '))|
(('$'-' '|(('$'-' ')<<('$'-' ')))<<('('-' '))|
(('$'-' '|(('#'-'!')<<('$'-' '))|
((('/'-' ')<<('$'-' '))<<('('-' ')))<<('='-'-')),
...
F0
24
C7
44
mov dword ptr[esp-16], imm
1 of 22

Recommended

Siv3Dで楽しむゲームとメディアアート開発 by
Siv3Dで楽しむゲームとメディアアート開発Siv3Dで楽しむゲームとメディアアート開発
Siv3Dで楽しむゲームとメディアアート開発Ryo Suzuki
7.8K views71 slides
C++14 Overview by
C++14 OverviewC++14 Overview
C++14 OverviewAkira Takahashi
11.8K views33 slides
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜 by
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜勝成 鈴江
5.2K views29 slides
ゲーム開発者のための C++11/C++14 by
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
103.6K views157 slides
Map by
MapMap
Mapkikairoya
10.2K views41 slides
Boost.Coroutine by
Boost.CoroutineBoost.Coroutine
Boost.Coroutinemelpon
23.8K views44 slides

More Related Content

What's hot

20分くらいでわかった気分になれるC++20コルーチン by
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
13K views31 slides
More C++11 by
More C++11More C++11
More C++11京大 マイコンクラブ
13.9K views57 slides
組み込みでこそC++を使う10の理由 by
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
27K views32 slides
Emcjp item21 by
Emcjp item21Emcjp item21
Emcjp item21MITSUNARI Shigeo
2.3K views12 slides
Visual C++で使えるC++11 by
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
36.8K views96 slides
BoostAsioで可読性を求めるのは間違っているだろうか by
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかYuki Miyatake
14.3K views31 slides

What's hot(20)

20分くらいでわかった気分になれるC++20コルーチン by yohhoy
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy13K views
組み込みでこそC++を使う10の理由 by kikairoya
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya27K views
Visual C++で使えるC++11 by nekko1119
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
nekko111936.8K views
BoostAsioで可読性を求めるのは間違っているだろうか by Yuki Miyatake
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
Yuki Miyatake14.3K views
ナウなヤングにバカうけのイカしたタグ付き共用体 by digitalghost
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
digitalghost2.3K views
C++ ポインタ ブートキャンプ by Kohsuke Yuasa
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Kohsuke Yuasa11K views
Effective Modern C++ 読書会 Item 35 by Keisuke Fukuda
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
Keisuke Fukuda11.1K views
C++入門? by tsudaa
C++入門?C++入門?
C++入門?
tsudaa3.6K views
Javaとかc#とか最近の言語使いのためのc++入門 by potimarimo
Javaとかc#とか最近の言語使いのためのc++入門Javaとかc#とか最近の言語使いのためのc++入門
Javaとかc#とか最近の言語使いのためのc++入門
potimarimo7.4K views
競技プログラミングのためのC++入門 by natrium11321
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
natrium11321 32.9K views
C++コンパイラ GCCとClangからのメッセージをお読みください by digitalghost
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
digitalghost4.7K views

Viewers also liked

フィルタドライバ入門 by
フィルタドライバ入門フィルタドライバ入門
フィルタドライバ入門firewood
20.2K views127 slides
unique_ptrにポインタ以外のものを持たせるとき by
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときShintarou Okada
6.9K views28 slides
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」 by
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」Takashi Ogura
4.4K views19 slides
Boost.Spirit.QiとLLVM APIで遊ぼう by
Boost.Spirit.QiとLLVM APIで遊ぼうBoost.Spirit.QiとLLVM APIで遊ぼう
Boost.Spirit.QiとLLVM APIで遊ぼうnvsofts
5.3K views27 slides
不遇の標準ライブラリ - valarray by
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
7.4K views36 slides
C++がなぜ組込みに採用されにくいか by
C++がなぜ組込みに採用されにくいかC++がなぜ組込みに採用されにくいか
C++がなぜ組込みに採用されにくいかTsuyoshi Kato
7.8K views13 slides

Viewers also liked(20)

フィルタドライバ入門 by firewood
フィルタドライバ入門フィルタドライバ入門
フィルタドライバ入門
firewood20.2K views
unique_ptrにポインタ以外のものを持たせるとき by Shintarou Okada
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
Shintarou Okada6.9K views
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」 by Takashi Ogura
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
RoboticsとC++@歌舞伎座.tech#8「C++初心者会」
Takashi Ogura4.4K views
Boost.Spirit.QiとLLVM APIで遊ぼう by nvsofts
Boost.Spirit.QiとLLVM APIで遊ぼうBoost.Spirit.QiとLLVM APIで遊ぼう
Boost.Spirit.QiとLLVM APIで遊ぼう
nvsofts5.3K views
不遇の標準ライブラリ - valarray by Ryosuke839
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
Ryosuke8397.4K views
C++がなぜ組込みに採用されにくいか by Tsuyoshi Kato
C++がなぜ組込みに採用されにくいかC++がなぜ組込みに採用されにくいか
C++がなぜ組込みに採用されにくいか
Tsuyoshi Kato7.8K views
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング - by Kishi Shundo
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
Kishi Shundo6.8K views
ELFの動的リンク by 7shi
ELFの動的リンクELFの動的リンク
ELFの動的リンク
7shi 18K views
バイナリアンを目指して For a binaryen by Eyes, JAPAN
バイナリアンを目指して For a binaryenバイナリアンを目指して For a binaryen
バイナリアンを目指して For a binaryen
Eyes, JAPAN4K views
独学道場アセンブリの会 by Ryota Suenaga
独学道場アセンブリの会独学道場アセンブリの会
独学道場アセンブリの会
Ryota Suenaga2.5K views
ctfで学ぼうリバースエンジニアリング by junk_coken
ctfで学ぼうリバースエンジニアリングctfで学ぼうリバースエンジニアリング
ctfで学ぼうリバースエンジニアリング
junk_coken6.6K views
Raw画像について by Sungsil Hwang
Raw画像についてRaw画像について
Raw画像について
Sungsil Hwang1.2K views
IdrisでWebアプリを書く by Hideyuki Tanaka
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書く
Hideyuki Tanaka19.4K views
関数プログラミング入門 by Hideyuki Tanaka
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
Hideyuki Tanaka21.8K views

Similar to C++でHello worldを書いてみた

Slide by
SlideSlide
SlideTakefumi MIYOSHI
1.2K views26 slides
[DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装 by
[DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装 [DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装
[DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装 Deep Learning JP
2.8K views36 slides
C++0x in programming competition by
C++0x in programming competitionC++0x in programming competition
C++0x in programming competitionyak1ex
1.8K views24 slides
x86x64 SSE4.2 POPCNT by
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTtakesako
8.9K views30 slides
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜 by
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜Takuya ASADA
2.9K views35 slides
PBL1-v1-009j.pptx by
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptxNAIST
3 views12 slides

Similar to C++でHello worldを書いてみた(20)

[DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装 by Deep Learning JP
[DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装 [DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装
[DLHacks]PyTorch, PixyzによるGenerative Query Networkの実装
Deep Learning JP2.8K views
C++0x in programming competition by yak1ex
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex1.8K views
x86x64 SSE4.2 POPCNT by takesako
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
takesako8.9K views
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜 by Takuya ASADA
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜
BHyVeでOSvを起動したい
〜BIOSがなくてもこの先生きのこるには〜
Takuya ASADA2.9K views
PBL1-v1-009j.pptx by NAIST
PBL1-v1-009j.pptxPBL1-v1-009j.pptx
PBL1-v1-009j.pptx
NAIST3 views
Clojure by yshigeru
ClojureClojure
Clojure
yshigeru1.3K views
C++0x in programming competition by yak1ex
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex1K views
EmacsとGlossでお絵描きしてみるよ by Kiwamu Okabe
EmacsとGlossでお絵描きしてみるよEmacsとGlossでお絵描きしてみるよ
EmacsとGlossでお絵描きしてみるよ
Kiwamu Okabe2.5K views
x86とコンテキストスイッチ by Masami Ichikawa
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
Masami Ichikawa8.6K views
Capture the flag write up q13,q20,q21 for ss by Masahiro Fukuda
Capture the flag write up q13,q20,q21 for ssCapture the flag write up q13,q20,q21 for ss
Capture the flag write up q13,q20,q21 for ss
Masahiro Fukuda70 views
第10回 計算機構成 by 眞樹 冨澤
第10回 計算機構成第10回 計算機構成
第10回 計算機構成
眞樹 冨澤384 views
Python standard 2022 Spring by anyakichi
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi218 views
F#入門 ~関数プログラミングとは何か~ by Nobuhisa Koizumi
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi3.6K views
超絶技巧プログラミングの世界(FTD2015) by mametter
超絶技巧プログラミングの世界(FTD2015)超絶技巧プログラミングの世界(FTD2015)
超絶技巧プログラミングの世界(FTD2015)
mametter3.1K views
as-5. サブルーチン呼び出しのメカニズム by kunihikokaneko1
as-5. サブルーチン呼び出しのメカニズムas-5. サブルーチン呼び出しのメカニズム
as-5. サブルーチン呼び出しのメカニズム
kunihikokaneko11.7K views

More from firewood

Best Bugs 2017 in the SmartNews iOS app by
Best Bugs 2017 in the SmartNews iOS appBest Bugs 2017 in the SmartNews iOS app
Best Bugs 2017 in the SmartNews iOS appfirewood
2K views15 slides
Xcodeでmrubyをステップ実行してみた by
Xcodeでmrubyをステップ実行してみたXcodeでmrubyをステップ実行してみた
Xcodeでmrubyをステップ実行してみたfirewood
1.1K views21 slides
Xcodeで値を表示する by
Xcodeで値を表示するXcodeで値を表示する
Xcodeで値を表示するfirewood
3.8K views26 slides
SmartNewsアプリの品質 by
SmartNewsアプリの品質SmartNewsアプリの品質
SmartNewsアプリの品質firewood
5.8K views26 slides
WkWebViewのキャッシュについて調べた by
WkWebViewのキャッシュについて調べたWkWebViewのキャッシュについて調べた
WkWebViewのキャッシュについて調べたfirewood
20.3K views23 slides
delayed_jobの自動再起動 by
delayed_jobの自動再起動delayed_jobの自動再起動
delayed_jobの自動再起動firewood
2.7K views13 slides

More from firewood(9)

Best Bugs 2017 in the SmartNews iOS app by firewood
Best Bugs 2017 in the SmartNews iOS appBest Bugs 2017 in the SmartNews iOS app
Best Bugs 2017 in the SmartNews iOS app
firewood2K views
Xcodeでmrubyをステップ実行してみた by firewood
Xcodeでmrubyをステップ実行してみたXcodeでmrubyをステップ実行してみた
Xcodeでmrubyをステップ実行してみた
firewood1.1K views
Xcodeで値を表示する by firewood
Xcodeで値を表示するXcodeで値を表示する
Xcodeで値を表示する
firewood3.8K views
SmartNewsアプリの品質 by firewood
SmartNewsアプリの品質SmartNewsアプリの品質
SmartNewsアプリの品質
firewood5.8K views
WkWebViewのキャッシュについて調べた by firewood
WkWebViewのキャッシュについて調べたWkWebViewのキャッシュについて調べた
WkWebViewのキャッシュについて調べた
firewood20.3K views
delayed_jobの自動再起動 by firewood
delayed_jobの自動再起動delayed_jobの自動再起動
delayed_jobの自動再起動
firewood2.7K views
三日で書くGroonga関数 by firewood
三日で書くGroonga関数三日で書くGroonga関数
三日で書くGroonga関数
firewood2K views
L-R by firewood
L-RL-R
L-R
firewood1.8K views

C++でHello worldを書いてみた

  • 1. C++ で Hello world を書いてみた 2015/5/17 hotpepsi
  • 2. 自己紹介  twitter: @hotpepsi  趣味 : 競技プログラミング、 テニス、ピアノ  キャッチフレーズ : bootstrap から Bootstrap まで
  • 3. デモ  Ubuntu 14.04 x86-64 $ make -f hello_gen.mk g++ -fno-operator-names -o hello_gen_gen hello_gen_gen.cc ./hello_gen_gen > numbers.cc g++ -o hello_gen hello_gen.cc ./hello_gen > _.c cc -c -Wa,-R -w _.c ld _.o -e _ -o hello ./hello Hello, world!
  • 4. ソースコードの先頭部分 _[]={ '('-'!'|((','-' ')<<('$'-' '))| (('$'-' '|(('$'-' ')<<('$'-' ')))<<('('-' '))| (('$'-' '|(('#'-'!')<<('$'-' '))| ((('/'-' ')<<('$'-' '))<<('('-' ')))<<('='-'-')), ...
  • 6. C で記号プログラミング ( 復習 )  記号のみでソースコードを記述  int 型の配列 _ を定義して、 text セグメントに 配置してプログラムとして実行する  エントリポイントを _start ではなく _ にする ことでアルファベット (main) を書くことを回 避  というような記号だけのソースコードを生成 するジェネレータを (C で ) 書いた
  • 8. 強化点 1  2010: C  2015: C++ ← New!
  • 9. マクロがテンプレートに  2010: マクロ  MAKE32(_4,_8,_6,_5,_6,_C,_6,_C), // Hell  2015: テンプレート  Symbolizer<‘H’>().s // H マクロは地獄
  • 10. struct Symbolizer  Symbolizer<0>().s -> !””  文字列 ( ポインタ ) の否定はゼロ  Symbolizer<1>().s -> !!””  ゼロの否定は 1  Symbolizer<n>().s -> Symbolizer<(n & 1)>().s | (Symbolizer<(n>>1)>().s << 1)
  • 11. テンプレートの優位性  マクロ :  0 から 16 までの値を用意する必要があった  テンプレート :  特殊化により、最低限 0, 1, n を用意すれば 、任意の数値が生成できる  例 : コンパイラにフィボナッチ数を計算させる  0 の部分を生成しないようにしたり、 2, 3, 4, ... と個別に用意すれば、コードがコンパ クトに
  • 12. 強化点 2  2010: バイナリ (0xB8, 0x04, ...)  2015: ニーモニック (mov ...)
  • 13. C++ でバイナリ生成といえば ...  Xbyak  ニーモニックによる記述が可能に  可読性と保守性の大幅な向上  2010:  MAKE32(_B,_8,_0,_4,_0,_0,_0,_0)  2015:  mov(eax, 4);
  • 14. コード生成のステップ 1. コードジェネレータジェネレータ (C++)  Xbyak でバイナリ生成  バイナリを Symbolizer の呼び出しに置換 して出力 2. コードジェネレータ (C++)  Symbolizer により記号化して出力 3. 記号だけのソースコード (C)
  • 15. 強化点 3  2010: x86  2015: x86 + x86-64
  • 16. x86-64 対応 (1)  32bit/64bit の両方に対応したい が、 #ifdef は減らしたい ↓  同じバイト列を生成するようにする
  • 17. x86-64 対応 (2)  x86 と x86-64 の命令バイト列はほぼ共 通  64bit の即値代入命令を使い、後半 32bit に jmp 命令を埋め込むこと で、 32bit モードの時だけ分岐する  これにより同じバイト列で両方に対応  デュアルアーキテクチャ  x86 と x64 の両方で動くシェルコードを書いてみる http://inaz2.hatenablog.com/entry/2014/07/06/185125
  • 18. objdump: x86 $ objdump -d hello hello: file format elf32-i386 Disassembly of section .text: 08048080 <_>: 8048080: c7 44 24 f0 48 65 6c 6c c7 44 24 f4 6f 2c 20 77 .D$.Hell.D$.o, w 8048090: c7 44 24 f8 6f 72 6c 64 66 c7 44 24 fc 21 0a ba .D$.orldf.D$.!.. 80480a0: 0e 00 00 00 48 bb 01 00 00 00 eb 19 00 00 48 8d ....H.........H. 80480b0: 74 24 f0 bf 01 00 00 00 89 f8 0f 05 31 ff b8 3c t$..........1..< 80480c0: 00 00 00 0f 05 8d 4c 24 f0 b8 04 00 00 00 cd 80 ......L$........ 80480d0: 31 db b8 01 00 00 00 cd 80 00 00 00 1...........
  • 19. objdump: x86-64 $ objdump -d hello hello: file format elf64-x86-64 Disassembly of section .text: 08048080 <_>: 8048080: c7 44 24 f0 48 65 6c 6c c7 44 24 f4 6f 2c 20 77 .D$.Hell.D$.o, w 8048090: c7 44 24 f8 6f 72 6c 64 66 c7 44 24 fc 21 0a ba .D$.orldf.D$.!.. 80480a0: 0e 00 00 00 48 bb 01 00 00 00 eb 19 00 00 48 8d ....H.........H. 80480b0: 74 24 f0 bf 01 00 00 00 89 f8 0f 05 31 ff b8 3c t$..........1..< 80480c0: 00 00 00 0f 05 8d 4c 24 f0 b8 04 00 00 00 cd 80 ......L$........ 80480d0: 31 db b8 01 00 00 00 cd 80 00 00 00 1...........
  • 21. コードジェネレータジェネレータ Put St r i ng( const st d: : st r i ng &message) { unsi gned i nt * dat a = ( unsi gned i nt * ) message. dat a( ) ; mov( dwor d[ esp - 16] , dat a[ 0] ) ; mov( dwor d[ esp - 12] , dat a[ 1] ) ; mov( dwor d[ esp - 8] , dat a[ 2] ) ; mov( wor d[ esp - 4] , dat a[ 3] ) ; mov( edx, message. l engt h( ) ) ; dec( eax) ; mov( ebx, 1) ; j mp( " @f " ) ; add( byt e[ eax] , al ) ; dec( eax) ; l ea( esi , pt r [ esp - 16] ) ; mov( edi , 1) ; mov( eax, edi ) ; syscal l ( ) ; xor ( edi , edi ) ; mov( eax, 60) ; syscal l ( ) ; L( " @@" ) ; l ea( ecx, pt r [ esp - 16] ) ; mov( eax, 4) ; i nt 80h( ) ; xor ( ebx, ebx) ; mov( eax, 1) ; i nt 80h( ) ; } スタック上にメッセージを 置く (x86/x86-64 共通 ) x86-64 用コード x86 用コード https://github.com/firewood/test/blob/master/hello_gen_gen.cc
  • 22. ソースコード _[]={ '('-'!'|((','-' ')<<('$'-' '))| (('$'-' '|(('$'-' ')<<('$'-' ')))<<('('-' '))| (('$'-' '|(('#'-'!')<<('$'-' '))| ((('/'-' ')<<('$'-' '))<<('('-' ')))<<('='-'-')), ... F0 24 C7 44 mov dword ptr[esp-16], imm