17歳からのプログラミング入門。

情報系の門の先で起きたことをたまにメモ。

高専セキュリティコンテスト Binary 500 OreNoFS

高専セキュリティコンテストでCTFに触れてきたのwrite upの分割です。

OreNoFSとは

f:id:Iruyan_Zak:20171022163611p:plain

高専セキュリティコンテストで1日目終了前に追加された500点問題で、32MB程度のオレオレファイルシステムの中からzipファイルを取り出す問題です。 バイナリ解析ツールなんて高尚なものは初挑戦で持ち合わせているはずもなく、 tail hexdumpC言語の知識だけで挑みました。

プロセス

まず、ファイルを hexdump で確認します。パーティションっぽい文字列があります。ここは問題から無視していいと思ったのでひとまず無視。 下まで見ていくと、「flag.zip」という文字列が見つかります。

*
00104000  0f 66 6c 61 67 2e 7a 69  70 00 00 00 1a e7 0f 00  |.flag.zip.......|
00104010  fd 05 00 00 00 00 00 00  00 00 00 00 00 00 ff 00  |................|
00104020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*

これがディレクトリエントリっぽいので、約束に従って読んで仮定とします。

filename:flag.zip
extension: 0*3
size: 1a e7 0f 00 = 1042202?
offset_of_cluster: fd 05 = 1533?
attribute: 0*12
reserved: ff 00 = 255

エンディアンはわからない・・・けれど、このファイルは32MB弱なので、sizeがそれを上回ると不自然だなあと思ってリトルエンディアンで読んでみました。 オフセットはきっとクラスタのことなので、クラスタサイズ4096をかけると0x005fd000くらいになりました。こんな番地にデータが置いてあれば便利なんだけどなー。

次に、zipファイルがどこかに置いてありそうなので「50 4b」で検索してみました。

*
006fd000  50 4b 03 04 14 00 08 00  08 00 69 b5 49 4b 00 00  |PK........i.IK..|
006fd010  00 00 00 00 00 00 00 00  00 00 08 00 10 00 66 6c  |..............fl|
006fd020  61 67 2e 70 6e 67 55 58  0c 00 0a 7d db 59 f5 7c  |ag.pngUX...}.Y.||
006fd030  db 59 f5 01 14 00 ec bc  07 5c 53 dd b6 2f 4a 93  |.Y.......\S../J.|

「50 4b 03 04」まで一致するのは0x006fd000番地にあります。上で計算したアドレスに似ています。きっと差分(1MB分くらい?)はGPTが持っていったのでしょう! いらない部分を tail -c+N で切り取って解析を進めます。

データの入ったクラスタの次のクラスタが0埋めされている事に気づきます。

00710fe0  74 b1 87 81 9b 0f ed 73  2b 92 7e 40 ec 91 e1 47  |t......s+.~@...G|
00710ff0  5c fe 2b 4b 55 4d 9f 3f  9f 05 a0 eb a7 d4 c4 ba  |\.+KUM.?........|
00711000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00712000  df 59 4c 7c 5a f8 da 12  96 6f 27 e7 e7 98 72 b5  |.YL|Z....o'...r.|
00712010  61 6d c3 65 ec 97 a4 28  65 d3 f5 f4 3a 9e d2 e6  |am.e...(e...:...|

つまり、そのまま読んでもダメで、うまくファイルを繋げ直さないといけない。 直列につなげようかとも思ったけれど、zipっぽいパートは16MBくらいの位置にあってダメそうだな、と思って寝ました。

2日目に入ってから、よく考えるとATを無視していることに気づきました。 ATには各クラスタが使えるかどうかが書いてあって、FAT16ではff f7は不正クラスタ、適当な値が書いてある時はそのクラスタに続く、ということらしいです。 ひとまずC言語(C++だけど)でATを1個ずつ出力します。

#include<cstdio>

int main(){
    FILE* file = fopen("AT.dmg", "r");

    if(!file){
        puts("read error.");
        return 1;
    }

    short n;
    short* nptr = &n;
    for(int i=0; fread(nptr, 2, 1, file); i++){
        if (n > 0){
            printf("%4d %d\n", i, n);
        }
    }
}

0や負の値が多いので、正の値だけ表示すると255行でした。 仮定で求めたsizeは4096で割ると255弱なので、きっと問題なしです。 適当に tsort を使って並べ替えてみると最初は1533番目(最初の仮定でメモしたオフセット)、最後は6202番目のクラスタということで、クラスタ6202を見に行くとzipの末尾のようなものがありました。

0193a6e0  81 b3 e4 0f 00 5f 5f 4d  41 43 4f 53 58 2f 2e 5f  |.....__MACOSX/._|
0193a6f0  66 6c 61 67 2e 70 6e 67  55 58 08 00 0a 7d db 59  |flag.pngUX...}.Y|
0193a700  f5 7c db 59 50 4b 05 06  00 00 00 00 03 00 03 00  |.|.YPK..........|
0193a710  d2 00 00 00 32 e6 0f 00  00 00 00 00 00 00 00 00  |....2...........|
0193a720  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*

ちなみに、途中に余計なルートが混じっていても tsort では気づけないので、ちゃんとCで書き直してます。

あとはこんなC言語風味を書いて、

#include<cstdio>
#include<iostream>

char buf[4096*8192 + 1];
short ns[8192];

int main(){
    FILE* fs_file = fopen("no-gpt.dmg", "r");

    if(!fs_file){
        puts("FS read error.");
        return 1;
    }

    fread(buf, 4096, 8192, fs_file);
    fclose(fs_file);

    FILE* at_file = fopen("AT.dmg", "r");

    if(!at_file){
        puts("AT read error.");
        return 1;
    }

    fread(ns, 2, 8192, at_file);
    fclose(at_file);

    for(int i = 1533; i > 0; i = ns[i]) {
        std::cerr << i << std::endl;
        fwrite(buf+(i*4096), 1, 4096, stdout);
    }

}

解凍すると画像に鍵が。 正直、画像に鍵が隠されているとお手上げだなあと思ったのですが、最後は素直に鍵が出てきたので嬉しかったです。 あと、書くべきプログラムもとてもシンプルだったので、いるやんでも解くことができました。


問題のファイルは32MBとサイズが大きいのでここでは公開しませんが、いるやん含め参加者が持っています。

高専セキュリティコンテストでCTFに触れてきた

要約

  • CTF初めての人4人でチームを組んだら35チーム中6位になれた
  • KoH問題を除いて一番高得点な500点問題を解けて嬉しい
  • この2日でみんないっぱい勉強して、CTFが好きになった

書き出し

10/21-22の期間、高専セキュリティコンテストというイベントに参加してきました。 解いた問題について言及することをwrite upというらしいので、それをやりながらエモい自慢をします。

チーム結成まで

いるやんは今までCTFには興味があったけれど、なかなか一歩目が踏み出せませんでした。 でももうすぐ卒業しちゃうし、結局CTFやらずに卒業するのはもったいないなあ、と思ったら、同じようにCTFに手を出せなかった3年生が3人集まってくれました。 名前はまあ、危険シェル芸高専ということで :(){:|:&};: (forkbombと読む)で良いだろうと決めましたがこのコマンドは絶対に実行しないでください。 本校にはBiPhoneというCTF熟達者達のチームがあったので、今回は成果を狙わず「0点以外の点数を狙っていこう」という目標を立てていました。

で、何をするコンテストなのか

大きく分けて、問題が2つ。

  1. ITクイズ
    • Jeopardyというらしいです。
    • 問題サーバからファイルをダウンロードしたり、暗号を解いたりして、隠された鍵を見つけます。
    • それをサーバに提出すると100点~500点くらい手に入ります。
  2. King of the Hill(KoH)
    • いわゆる陣取り合戦です。
    • サーバの脆弱性などをついて問題サーバに乗り込み、flagというファイルに自分のチームの名前を書くと10分ごとに30点ずつ手に入ります。
    • 一度乗り込んだら相手に侵入されないように侵入経路を閉じるなどをするらしいです。

write up

うちのチームを含め、ほとんどすべてのチームがKoH問題を解けなかったので、ここではITクイズについて自分が解いた範囲で言及していきたいと思います。

00 サンプル

ページを開くと鍵が置いてあって、提出すると100点です。 開始30秒で目標を達成してしまいました。

07 簡単な暗号化

数字とアルファベットのみだったので、これはbase64エンコードされた文字列だな!と #シェル芸 の勘が囁きました、大正解。チーム :(){:|:&};: なのでまあ、これは取れていい問題かな、と思いました。

U0NLT1NFTntiYXNlNjRfaXNfdmVyeV9lYXN5fQ

11 君(脆弱性)の名は

最近話題のWPA2のお話だったので、WPA2とか適当な文字を投げていたのですが、最後のレポートに"KRACKs"とあったのでこれが正解でした。Twitterやってるとこういう語彙力がついて良いです。 f:id:Iruyan_Zak:20171022161420p:plain

12 便利なプロトコル

「alter dhcp 1998」とかで調べてもいまいちだったので、Google Scholarに「dhcp」、著年1998で調べてそれっぽいものを入れると正解。「Management of IP numbers by peg-dhcp」という論文らしいです。 f:id:Iruyan_Zak:20171022161426p:plain

03 ボスを倒せ

アクセスすると名前を聞かれ、その後ボスとの戦闘が始まります。ボスの体力が圧倒的だし、コマンドもないので勝ち目がありません。

ログ

バイナリを落として来られる雰囲気もないので、とりあえず「AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA」と名乗ると自分の体力が増えましたやったね。 名前→自分の体力→ボスの体力というメモリ配置っぽいので、いい感じに長さを調整して名前を入力するとボスの体力が68くらいになりました、わーい。

19 灯台下暗し

サーバにアクセスするとこんなページが。

ページ

「the FLAG is admin's password.」と書かれていたので、「FLAG」とかいろいろ試したんですがダメで、hintをよく読むと、ファイル名を指定してDBを見に行ってました。そのままwgetでDBファイルをもらってsqlite3でusersを覗いてゲームセットです。

21 Web2

穴埋め問題です。もしかしたら高速な解法もあるのかもしれませんが、mapという文字列が見えた(関数型好きだから使い方を推測できた)のと、問題のやりたいことがすぐに掴めたので正攻法で解きました。 問題作る方は楽しそうだなと思いました。

f:id:Iruyan_Zak:20171022161638p:plain

20 Web1

難読化したJSを読む問題です。

JSファイル

再代入、ブロックによる変数の隠蔽、状態の変わるリストから属性を取り出すなど、悪意に満ちたコードでした。 地道に溶かして、コンソール上で実行したら鍵が現れました。

05 簡単な暗号化

暗号化は簡単(base64)ですが、その先は簡単なんて一言も言ってない、そんな問題。

ファイル

base64デコードすると16進の数字が出てきて、これをバイナリ化するとよくわかんないdataが出来てしまいました。 ただ、中にファイル名の断片みたいなのがあって圧縮ファイルっぽいなと思ったのでマジックナンバーを調べるとzipでした。 ファイル名はチグハグ(順番が入れ替わっている)になっていたのですが、手作業で並べ替えるとこれはミドルエンディアンだったことがわかり、元の16進数をよしなに並び替えてバイナリ生成したら解凍に成功しました。

・・・なのですが、そもそもファイル名が word/document.xml だったり _rels/ で始まっていたり・・・って、これdocx!?となって圧縮ファイルの状態でLibreOffice Writerで開いたら鍵が縦並びに書いてありました。docxが圧縮ファイルというのは #シェル芸 界隈では有名なことのようなので、気づいて良かったなって思いました。


正直、ここまでで解ける問題がなくなって満足していたのですが、1日目終了前に問題が追加されました。

04 OreNoFS

満を持して登場した500点問題。 オレオレファイルシステムの中からzipファイルを取り出す問題です。

ちょっと詳細に書きたい気持ちなので、記事を分けることにします。解法は こちら に。

結果

2800点で6位です。予想の28倍頑張りました。

f:id:Iruyan_Zak:20171022162713p:plain

また、上位15チームみんな解いているRSAの問題(08,09)が解けなかったり、逆に上位3チームしか解いていないファイルシステム(04)の問題を解いていたり、変なチームです。

所感

  • みんな初心者だったのに、パケットキャプチャの問題をほとんど(KoH2のヒント鍵までたどり着いてるし)解いていてすごい!って思った。
  • #シェル芸 とかやってるとあいてぃー雑学強くなるなあと思いました。が、優勝したinsecureチームのふるつきくんはシェル芸botというものを作ってました。敗北。
  • 他の大会との比較はできませんが、楽しく解けるいい問題が多かったように思います。
  • RSAはダメ(ダメ)

謝辞

本大会を企画・運営してくださった皆様、およびこの雨の共に競って下さった各高専の競技者の皆様に、ありがとうございました、とお伝えします。

2017/10/09 第28回 高専プロコンを眺めてきた。

工程

  • 8日
    • 6時頃 電車に乗る
    • 14時前 徳山駅に着く
    • 14時過ぎ 高専プロコン会場に着く
    • 17時まで 競技を見たり自由・課題部門のブースを回ったり
    • 17時 学生交流会
    • 19時前 名刺バラマキ会
    • 20時前 後輩にご飯を奢る
    • 23時 寝る
  • 9日
    • 8時40分頃 会場につく
    • 14時まで 競技を見たり自由・課題部門のブースを回ったり
    • 14時 色んな人に挨拶をして帰る
    • 15時前 徳山を発つ
    • 20時過ぎ まだ岡山

良かったこ

考えたこ

  • プロダクトを作れる人ってすごいなあ、と自由や課題を見ながら漠然と憧れていたけれど、みんなチームでやっているのだなあと思ったら、個々の力よりも環境の力が大きいのかな、と思った。
  • 審査の人、やっぱりこわい。あれが社会で活躍するための疑似ボーダーライン、じゃないですよね・・・。
  • 男の子はやっぱり多かったけれど、女の子が想像よりも多かった。青春を感じますね、どうぞご安全に。
  • 「今動かないんですよね・・・」と言いながら解決策を必死で考えている人はやっぱり惚れるほどかっこいい!

内省パート

  • 人に、もっと言って、問い詰めて来る大人に見せる物を作ると知識が深くなるものだなあって思う。
    • 専門分野は最初にこれ、と決めて学ぶものではなくて、こういう機会で経験値を得られたスキルを専門分野にしていくのかな。
    • そうなると場数を踏まなければ、ということになるのだけれど、自分に何ができるか・・・。
      • あまり深く考えなくていいや。時が解決してくれるだろう。
  • 高専プロコンの環境は普通じゃない。
    • この空気の中で化け物みたいな能力者が現れるのはある意味当然です。
    • 張り合うことは適切じゃない、というか、元より人と張り合わないでください。
    • でも、自分に与えられた環境の中でちゃんと活動できているなら大丈夫かな、とまあ、ないものねだりはしないように、とひとつ成長した。
    • 自分が出せている価値は0ではないと思うので、これからも続けていきたい所存
  • どこまで行っても知らない世界がある、反対に忘れられたら知らない世界にできる。
    • 小学時代のクラスメートの顔をどれだけ覚えているだろうか。
    • ここで作ったコネクションも、維持しないと消えてしまう。
    • 高専プロコンの参加者の存在がプレッシャーでも、もっと必死に生きないといけない状況になったら忘れてしまうかもしれない。
    • 「知り合い」から「友達」にすることは意味のある行為だな、と思った。
    • 反対に、自分より力のある人間は対数目盛でn目盛り分くらい存在するだろうし、いちいち1目盛り上の人間なんて気にしてても仕方ない。
      • 辛いなら忘れちゃえ!
      • 忘れられたら苦労しないですね。

最後に

  • 書き始めから5駅くらい進みました。
    • 岡山県を抜けるまで後また5駅くらいです。
      • 駅間はめっちゃ長いです。
  • 鈍行列車はどこか懐かしい空気とともに内省にぴったりです。おすすめです。
    • 是非「青春18きっぷ」や「秋の乗り放題パス」などを使って無意味な電車旅をしよう。
      • きっと何かが得られるさ。最悪親しくない人への話題に使えるよ。

感謝パート

  • ブースでお話を聞かせて頂いた方
  • いるやんと会ってくださった方
  • この良い大会を運営するに関連された方

ありがとうございました!

echo 学生セキュリティ勉強会 | sed 's/.*/sed計算機/'

前置き

9/23(土)、秋葉原カスペルスキーさんで『第一回 学生セキュリティ勉強会』というイベントに参加してきました。

参加者は40人程度、部屋は満員で、主催者も驚いていたようでした、し、いるやんもびっくりでした。

本会の内容は、セキュリティに関する話ということで言わないように釘を刺されているので触れられません、ごめんなさい。 言える範囲としては「SQLインジェクションXSS等の基本的なWeb脆弱性の体験と解説」(イベントページより)ということで、全く攻撃を行ったことがない初心者にとっては(脆弱性に対する考え方も含めての)学びがある良いイベントだったのではないかと思ったのでした。

懇親会(本会)

17:30くらいから懇親会が始まりました。時間は1時間くらいということで、カスペルスキーさんのご厚意のピザを頬張りながら交流を楽しみました。

ただまあ、人が集まるとLTしたくなるのが芸人の性というもので、何故かセキュリティ勉強会でシェル芸とsedの発表をしてしまいました。 発表では不明瞭な点もありましたので、以下にまとめなおして振り返りとさせていただきます。

シェル芸とは?

  • 「マウスも使わず、ソースコードも残さず、GUIツールを立ち上げる間もなく、あらゆる調査・計算・テキスト処理をCLI端末へのコマンド入力一撃で終わらすこと。」
    • 重要な(繰り返し使いそうな)操作ならソースコードに残しましょう、そうするべきだなーとシェル芸しながらつくづく思います・・・。
    • 人々は楽しみでこれをやっているのです。
  • シェル芸勉強会というのがあります。

シェル芸の例題紹介

  • contents.texについて、「\begin{figure}と\end{figure}」で囲まれた部分を全て抽出してください。(シェル芸勉強会 vol.28 Q1より)
    • sedというコマンドの検索機能を使うと、汎用プログラミング言語で解くより遥かに簡単に解けます。
    • 解答は公開されているので、いるやんの解答を書いておきます。
    • sed -n '/\\begin{figure}/,/\\end{figure}/p'
    • 「いらないところは表示しない、 “\begin{figure}” を見つけて、 “\end{figure}” が見つかるまでの範囲を表示して」と読みます。
  • 他にも、grepを使うとさくっと解けるvol.30 Q1を紹介しました。

(GNU) sedについて

  • sedはエディタです。(Stream EDitorの略、manにもそう書いてある)
  • リッチなエディタを立ち上げなくても、コマンド"ライン"上で検索・置換・追加(これはほとんど使われない)といった操作ができます。
  • sedでは数値の計算が行えません。
    • awkとかを使うのが一般的かなーって。

sedで足し算作った(本題)

LISPっぽい足し算を行ってみました。

echo '(+ 4 7)' | sed -E 's/\(\+ ([0-9]) ([0-9])\)/\1\2/;y/123456789/abcdefghi/;s/.$/\U&/;tadd;:add;s/(.)X/1\10/;s/(.?)0(.?)/\L\1\2/;tendadd;y/abcdefghiABCDEFGHI/0abcdefghBCDEFGHIX/;badd;:endadd;y/abcdefghi/123456789/'

これ1行をbashに貼り付けてもらうと11と表示されます。 実際、 (+ 1 1) -> 2 のような変換を100個くらい書けばできるんですが、それじゃ味気ないよね、と。

プログラムの解説

1行で書くのは読みにくいだけなので、主にセミコロンごとに改行して1行ずつ読み下していきましょう。 nlコマンドを使って行番号を振ってみました。

     1   echo '(+ 4 7)' |
     2  sed -E '
     3  s/\(\+ ([0-9]) ([0-9])\)/\1\2/;
     4  y/123456789/abcdefghi/;
     5  s/.$/\U&/;
     6  tadd;
     7  :add;
     8  s/(.)X/1\10/;
     9  s/(.?)0(.?)/\L\1\2/;
    10  tendadd;
    11  y/abcdefghiABCDEFGHI/0abcdefghBCDEFGHIX/;
    12  badd;
    13  :endadd;
    14  y/abcdefghi/123456789/
    15  '

[string]という形式でその時点での文字列を表示することとします。 また、以後で _ は何かのパターンを表します。 _ という文字そのもののつもりではないことを認識してもらうとともに、正しいパターンの書き方は↑のコマンド列に記されていることをご確認ください。

  1. (+ 4 7) という文字列を後続のコマンドに渡します。
  2. [(+ 4 7)] 後続のコマンドはsedです。拡張正規表現(sed内部でのバックスラッシュのルールが変わります)を使用します。
  3. [47] sコマンドは s/pattern/str/ の構文で patternstr に置換します。今回は (+ _ _) の形式の文字列のアンダーバーの部分を取り出して、それを繋げた文字列に置換します。_ はいずれも1文字の数字を表します。
  4. [dg] yコマンドは逐語変換と言って、左側の文字を対応する右の文字に変換します。 1a に、 2b に、・・・と言った具合です。 4d に、 7g に対応します。
  5. [dG] 末尾の1字を大文字に変換します。
  6. [dG] 実はsedのコマンドにはC言語のようなラベルジャンプ機能があります。tコマンドは直前のtコマンド以降(なければプログラム開始以降)にsコマンドが成功していれば、指定のラベルにジャンプします。 add ラベルは7行目にあるので、6行目は単純に以前のsコマンドの成功をリセットしているだけです。
  7. [dG] :コマンドはラベルの定義です。 add というラベルを定義します。
  8. [dG] _X の形式の文字列を 1_0 という風に置換します。今回は X がないので置換に失敗して、文字列はそのままです。
  9. [dG] _0_ の形式の文字列からアンダーバーの部分を取り出して、それを繋げた文字列に置換します。今回の _ は数字でなくてもいいし、存在しなくてもいいです。ちなみに今回は 0 がないので置換失敗です。
  10. [dG] 8-9行目で置換に成功していれば endadd というラベルにジャンプします。今回はどちらも失敗しているのでそのまま素通りします。
  11. [cH] 逐語変換です。前の文字を1文字若くして、後ろの文字を1文字老かせます。
  12. [cH] bコマンドは無条件ジャンプです。アセンブリで言うところのbranchに相当するのでしょうか。7行目の add ラベルまでジャンプします。

これ以降の7-12行目の動きは3度ほど上と同じ操作を繰り返し、 [cH] から、 [bI][aX] となって7行目から説明を再開します。

  1. [aX] add ラベルにジャンプしてきました。
  2. [1a0] _X の形式の文字列を 1_0 に置換します。 _ にはaがマッチして 1a0 という文字列になります。
  3. [1a] _0_ (ただし _ はなくても良い)の形式に a0 の部分がマッチして、 a のみに置換されます。 1 はそのまま残るので、 1a となります。
  4. [1a] 8行目で置換に成功しているのでtコマンドが発動して、13行目の endadd ラベルまでジャンプします。

13行目以降は計算終了処理が続きます。

  1. [1a] endadd ラベルを定義します。飛んできました。
  2. [11] 逐語変換で、アルファベットを数字に戻します。
  3. [11] sedコマンドはここまでで、この状態の文字列として4+7の答え 11 が出力されます。お疲れ様でした。

今後の展望

  • 複数桁の足し算もやってみたいです。愚直にやればできるんですが、桁上りのスマートな解決に悩んでいます。1桁ずつ切り出して計算を行う方法はできることを確認済みです。
  • 1桁同士であれば引き算は簡単なんじゃないかと思ってます。足し算よりコード短くなりそう。
  • sedの知識の更なる拡充
  • そもそもこんなふざけた計算機はもう作りたくないです💢

おわりに

危険シェル芸は手元では絶対実行しないようにしようね! 誰が書いたかわからないシェルコマンドが落ちていても実行しちゃダメだぞ!中に何が書かれているかは確認できる範囲で確認しよう!

保健室の先生とお話してきた。

表題の通りです。

なんとなく書き付けておきたかったので、話し始めだけ書き付けています。

お悩み相談の入り口でしかないので、メッセージ性があったりするわけでもないです。

 

続きを読む

プログラマの端は書き捨て。

kosen13s' Advent Calendar 2016 (http://www.adventar.org/calendars/1855) の 3 日目の記事です。

これは供養です!

先日、半年ほど使っていた Xubuntu 15.10 の仮想マシンに別れを告げ Xubuntu 16.10 に乗り換えたのですが、 前のディスクの tmp ディレクトリに大量のプログラムが書き捨てられていました。

f:id:Iruyan_Zak:20161203234928p:plain

人からの相談や、耳にした tips などを tmp に投げ入れているため、 もう用のないコードではありますが、もしかしたら誰かの知見になりうるかと思うので、公開します。

ただし、本当に意味のわからないコードもあるので、紹介するのは一部だけです。

/0523

C++ の deprecated を用いたコンパイル時型表示のプログラムです。

#include<bits/stdc++.h>
class H{};

template <class T>
[[deprecated]] void chk_type(T t){}

int main(){
    auto cache = new std::unordered_map<int, std::weak_ptr<const H>>;
    chk_type(cache);
}

これをコンパイルすると

a.cpp: In function ‘int main()’:
a.cpp:10:19: warning: ‘void chk_type(T) [with T = std::unordered_map<int, std::weak_ptr<const H> >*]’ is deprecated [-Wdeprecated-declarations]
     chk_type(cache);
                   ^
a.cpp:6:21: note: declared here
 [[deprecated]] void chk_type(T t){}
                     ^

このような警告が出て、 cache の型の推論結果が表示されます。 一節には、そこらの IDE では推論できない推論結果まで教えてくれるらしいです。

/0830

https://speakerdeck.com/greymd/mei-ri-kou-keru-sieruyun-wojue-eyou?slide=31 これで遊んでた時の残骸だと思う。シェル芸いいよ。 xaa ってこれわけわからずに split 打った出力だよなあ。

% ls 0830
fuga  hoge  holidays  xaa

あと、同時期に "man コマンドクイズ" ってのにもはまってました。

man vim を実行すると vim - Vi IMproved, プログラマのテキストエディタ と表示され、 vim はエディタであるとわかるのですが、 man emacs を実行すると emacs - GNU project Emacs と表示され、「EmacsEmacsだ」という強い意志を感じることができます。

/0904

C++ラムダ式は関数ポインタに突っ込めるんだなあ・・・。 これで最適化を封じて時間計測する、みたいな技があると聞いた気がする。

#include<iostream>
using namespace std;

int main(void){
    int (*hoge)(int) = [](int n){ return n*n; };
    cout << hoge(10) << endl;
}

/0921

mkfifo ってコマンドを使うと名前付きパイプっていう面白いファイルを作ることができます。 もしかしたら環境によってコマンド名は違うかも。

% ls 0921
echo hello  fifo|  hello@  p|  preprocess.c

何ができるかは説明すると長くなるんだけど、2つのプロセスからこのファイルへの書き出しと読み出しが両方行われた時に初めて、2つのプロセスに書き出しと読み出しを行わせる(それまではブロックする)っていう挙動をします。

何に使えるかわからん。

/1024

やさしい C のポインタのお話。 言いたいことはすべてコメントになってる。

#include<stdio.h>

int main(){
    char h[4];
    h[0] = 1;
    h[1] = 2;
    h[2] = 3;
    h[3] = 4;

    // ポインタなんて所詮整数だからビット演算にかけられたりするよ
    printf("%p, %zu\n", h, (size_t)h);
    printf("%d\n", *(char*)((size_t)(h+3) & (-4)));

    putchar('\n');

    // ポインタなんて所詮その変数が格納されている"先頭の"アドレスでしかないから、サイズの違う型のポインタにキャストしてやればもともとの変数の境界なんてうやむやにできるよ
    *((short*)h+1) = *(short*)h;
    for(int i=0; i<4; i++) printf("%d\n", h[i]);

    putchar('\n');

    // short はここでは 2 バイト整数型として、それらを 1 バイトずつ表示。リトルエンディアン方式により下位のバイトが先行するのが見える
    short a = 258;
    printf("%d, %d", *(char*)&a, *((char*)&a+1));
}

この話を後輩に面白く話せるようになれたらいいなあ。 このコードが欲しければ好きに持って行ってください。

/1119

split コマンドの挙動を調べたくなったので、 sudo apt-get source coreutils してソースを拾ってきました。

いろんなコマンドの実装が読めて楽しいです。

% ls 1119
coreutils-8.23/                  coreutils_8.23-4ubuntu2.dsc  hgoe   xaa  xac
coreutils_8.23-4ubuntu2.diff.gz  coreutils_8.23.orig.tar.gz   pipe/  xab  xad

あとがき

思ったより何書いてるかわからないものが多くて抜粋に苦労しました。 広く浅く、いろんな言語、いろんな分野をやっているので、 面白い tips をご存じの方はぜひ教えて下さい!

#mixi_git challenge に参加した話

ざっくり言うと

mixi さん主催の git イベントに、 同じ学校の人(以下ペアの人)に誘われて行ってみたら、 1位タイになってしまったお話

です。

続きを読む