セキュリティ・キャンプ全国大会2019へ参加することになった(応募用紙晒し)

中間試験が一段落したので少し出遅れた感はあるけれど、この記事を書いています。

題名のとおりセキュリティ・キャンプ全国大会2019のシステムプログラミングトラックOS開発ゼミに参加することになったので、恒例の応募用紙晒しをしてみようと思います。 ちなみにセキュキャンに応募するのは今回が2回目です。実はリバースエンジニアリングゼミにも興味があってそちらの応募用紙も完成させてはいたのですが、最終的にOS開発ゼミのほうで提出することにしました。

あらためて自分の応募用紙を見直してみると結構はずかしいです。そういえば書いている最中も自分の文章にあまり自信がもてなくて何回も消したり書いたりしてたなあなんて思いだしました。

以下で掲載している応募用課題はこちらで公開されています https://www.ipa.go.jp/files/000073173.txt

セキュリティ・キャンプ全国大会2019のホームページはこちら https://www.ipa.go.jp/jinzai/camp/2019/zenkoku2019_index.html

応募用紙

  • 共通問題A
我々講師は、普段いくつかのOSを使っていますが、使い込むうちに色々な発見をします。
皆さんもきっとそういう体験があると思います。
あなたが普段使っているOSで、好きな機能と改善してほしい部分について、思いのたけを聞かせてください。
この問では、皆さんが普段どの程度興味を持って既存OSを観察しているかを評価します。

私が使っているOSで好きな部分は、OSのソースコードが大変に簡潔に記述されていること、そして余計な機能を一切入れないこと、またそれらによってOSに存在する脆弱性を限りなく少なくすることを目的にしていることです。 このOSのソースコードは本当にびっくりするくらいにきれいです。私はOSというものにそこまで深く触れたことがなく、C言語C++でのプログラミングを少ししたことがある程度なのですが、それでも他のOSのソースコードを読もうとしたときより「これは楽に読めるぞ」と感じたのでトリッキーなコードが少なく素直なのだと思います。また、余計な機能を一切入れないこともコードの単純化に寄与しています。普段ほとんどの人が使わないような機能のためにOSの開発がより困難なものになってしまうのは私は良くないと思います。このようにOSの構造を簡潔に、わかりやすくすることで見通しを良くすることに私はとても共感しています。 しかし、これらは決していいことづくしというわけではありません。このOSはソースコードの単純さや余計な機能を一切入れないことによってパフォーマンスを犠牲にしています。ハードウェアの性能向上を待てばパフォーマンスは良くなると思いますが、ハードウェアの性能向上にそこまで期待していいのかという問題もありますから、なかなか難しい問題だなと思います。

  • 共通問題B
皆さんが仮にOSを作るとしたら、「どんなOS(やOSの機能)を作ってみたい」でしょうか?
(既にOSを作った事がある人は、その特徴を書いてくれても構いません。)
そして、なぜそれを作ってみたいと思ったのでしょうか?
皆さんが心の中で夢描いているであろう、ワクワクするようなOS像を教えてください。
※「Linux開発者を目指そう!」テーマを受講したいと思っている方は「どんなLinuxカーネルの機能を作ってみたいか」を答えてください。
※「Raspberry Pi向け組み込みOSを作ろう!」テーマを受講したいと思っている方は「どんな組み込みシステムを作ってみたいか」を答えてください。

Linuxでは現在Linux向けにコンパイルされたプログラムしか実行することができなかったと思いますが、他のOS向けにコンパイルされたプログラムを動かすことができるバイナリエミュレーションの機能をつくってみたいです。 動機としては、この機能が特別ほしいなと思ったというわけではなく、単に実装してみたいなと思ったからです。私は数多くあるOSの機能のうちユーザーアプリケーションを実行する機能が好きです。もともと私がOSに興味をもったきっかけが、自分の書いたプログラムがどのように動いているのか知りたかったことにあるのが影響しているのかもしれません。ユーザープログラムを実行するに際してはいろんなOSでいろんな工夫がされているなと思います。例えば、LinuxにはVDSOというものがありますが、これはシステムコールはkernel側で処理されるものだという常識を覆すおもしろい発明だなと思います。

  • 共通問題C
C言語で双方向リンクリストとそれを操作する関数を作り、ソースコードを提出してください。
  リンクリストを生成する関数、要素を任意の場所に挿入する関数、全ての要素を順に標準出力に印字する関数、の3つがあれば十分です。
  やる気があればもっとたくさんの機能を実装しても構いません!
#include <stdio.h>
#include <stdlib.h>

int init(void);
void end(void);
struct node * search_tail(void);
int insert_tail(int value);
void delete_tail(void);
int insert_index(int value, unsigned int index);
void print_list(void);

struct node {
    int value;
    struct node *next;
    struct node *prev;
};

struct node *head;

int
init(void)
{
    head = malloc(sizeof(struct node));
    if(head == NULL) return -1;
    head->value = 0;
    head->next  = NULL;
    head->prev  = NULL;
    return 0;
}

void
end(void)
{
    struct node *tail = search_tail();
    while(tail != head) {
        delete_tail();
        tail = search_tail();
    }
    free(head);
    return;
}

struct node *
search_tail(void)
{
    struct node *search = head;
    while(1) {
        if(search->next == NULL) return search;
        search = search->next;
    }
}

int
insert_tail(int value)
{
    struct node *ins;
    struct node *tail = search_tail();
    
    ins = malloc(sizeof(struct node));
    if(ins == NULL) return -1;
    
    ins->value = value;
    ins->next = NULL;
    ins->prev = tail;
    tail->next = ins;
    return 0;
}

void
delete_tail(void)
{
    struct node *tail = search_tail();
    if(tail == head) return;
    tail->prev->next = NULL;
    free(tail);
    return;
}

int
insert_index(int value, unsigned int index)
{
    unsigned int counter = 0;
    struct node *current = head;
    struct node *ins;

    ins = malloc(sizeof(struct node));
    if(ins == NULL) return -1;
    
    if(index < 0) return -1;
    while(counter < index) {
        if(current == NULL) return -1;
        current = head->next;
        counter++;
    }
    if(current == NULL) return -1;

    ins->value = value;
    ins->prev  = current;
    ins->next = current->next;

    current->next = ins;
    return 0;
}

void
print_list(void)
{
    struct node *current = head->next;
    while(current != NULL) {
        printf("%d\n", current->value);
        current = current->next;
    }
    return;
}

int
main(int argc, char *argv[])
{
    if(init() < 0) return -1;
    if(insert_index(5, 0) < 0) puts("error");
    if(insert_tail(6) < 0) puts("error");
    if(insert_index(3, 1) < 0) puts("error");
    print_list();
    end();
    return 0;
}
設計・実装で工夫した点を述べてください。

整数型の符号の有無や関数の引数などを最小限に抑え、簡潔な実装を心がけました。また、メモリリークなどのバグがないようエラーチェックをしっかりと行ったつもりです。

  • 選択問題S3
Linuxカーネルについて知りたいこと、それについてこれまで調べたこと、
つまづいたことを教えてください。最終的に解決しなかったとしてもOKです。
技術力が優れているかではなく、どれだけ試行錯誤したかという観点で採点をします。
「この機能のこのコードの意味がわからなかった」という高度なものでもいいですし、
「そもそも何から手を付けていいのかもわからなかった」というものでも構いません。

共通課題でも述べたのですが、私はプログラムを実行する仕組みに興味があるのでそれに関連するコードを少しだけ読んだことがあります。そこで不思議に思ったことなのですが、linuxのローダーの実装はfsというディレクトリの下に配置されています。fsというのはおそらくfilesystemのことをさしているのだと思いますが、自分にはこの理由がよくわかりませんでしたし、調べてもこれについて述べているものは探した限りなかったです。また、実際にLinuxにコントリビュートするとして、どういう機能を実装するかというアイデアをどうやって思いつくのか知りたいです。Linuxは多くの優秀な人がコントリビュートしていると思いますが、そのなかで必要とされる実装をどうやって生み出すのか私には全然分かりません。

  • 共通問題D
その他、書ききれなかったことを好きなだけ書いてください。

いままで自分一人では解決できなかった疑問をこの機会にぜひ解消していきたいです。そして、自分もLinuxや他のOSも含め貢献出来るような人になれるように努めていきたいです。

Emacsの設定@Gentoo&X11

春休みで時間があるので環境づくりに勤しんでおります。 今回は、前から気になっていたEmacsをインストールしたのでその設定方法を備忘録として残しておきます。

一番苦労したのはGUIのフォントの設定でした。ですから、まずはフォントの設定について述べておこうと思います。

フォントの設定@GUI

まず、Emacsのインストールですが「xft」のコンパイルオプションをpackage.useで有効にしておきます。

app-editors/emacs xft

次に~/.Xresourcesを以下のように編集します。

Xft.antialias: true

最後に、~/.emacs.d/init.elに以下の文字列を追加します。

(cond ((display-graphic-p)
       (set-default-font "{FontName}")
       (set-fontset-font (frame-parameter nil 'font)
             'japanese-jisx0208
             '("{FontName}" . "unicode-bmp")) )
      (t 0))

これで、GUIEmacsのフォントがいい感じになって幸せです。

package.elの設定

~/.emacs.d/init.elに以下を追加。

(require 'package)

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))

(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/"))

(add-to-list 'package-archives  '("marmalade" . "https://marmalade-repo.org/packages/"))

(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))

Mozcインストール

M-x package-list-packages
mozc i
x

~/.emacs.d/init.elに以下を追加。

(require 'mozc)
(set-language-environment "Japanese")
(setq default-input-mothod "japanese-mozc")
(prefer-coding-system 'utf-8)
(global-set-key (kbd "C-j") 'toggle-input-method)

mewインストール

SMTP: STARTTLS, IMAP: STARTTLSで設定。

stunnelをコンパイルしておきます。

~/.emacs.d/init.elに以下を追加。

(autoload 'mew "mew" nil t)
(autoload 'mew-send "mew" nil t)

(setq read-mail-command 'mew)

;; Optional setup (e.g. C-xm for sending a message):
(autoload 'mew-user-agent-compose "mew" nil t)
(if (boundp 'mail-user-agent)
    (setq mail-user-agent 'mew-user-agent))
(if (fboundp 'define-mail-user-agent)
    (define-mail-user-agent
      'mew-user-agent
      'mew-user-agent-compose
      'mew-draft-send-message
      'mew-draft-kill
      'mew-send-hook))

(setq mew-prog-ssl "/usr/bin/stunnel")
(setq mew-name "{Name}")
(setq mew-user "{Name}")
(setq mew-mail-domain "{Domain}")
(setq mew-smtp-user "{Name}")
(setq mew-smtp-server "{Domain}")
(setq mew-smtp-auth t)
(setq mew-smtp-ssl t)
(setq mew-smtp-port {Port})
(setq mew-smtp-ssl-port mew-smtp-port)
(setq mew-proto "%")
(setq mew-imap-user "{Name}")
(setq mew-imap-server "{Domain}")
(setq mew-imap-auth t)
(setq mew-imap-ssl t)
(setq mew-imap-port {Port})
(setq mew-imap-ssl-port mew-imap-port)
(setq mew-use-cached-passwd t)
(setq mew-ssl-verify-level 0)

以上。

Gentoo Linuxを使い始めた

TL;DR

前々からsystemdから抜け出したいなーという気持ちがあったので、initシステムを含め随所で選択の自由が与えられているLinuxディストリビューションGentoo Linuxを使い始めました。 この記事は、Firefoxコンパイル中に暇だから書こうと思い立ち、とりあえずインストール手順をまとめてみたポエムです。

さてインストールですが、基本はwikiに忠実にやっていけば大丈夫です。とても親切にわかりやすくまとめられているなと感動しました。

wiki.gentoo.org

以下、自分で選択する必要があったところについて簡単に書いていきます。

インストール環境

手順

Live Mediaを用意し、起動する

自分はminimalのやつをUSB Memoryに書き込みました。起動するとおなじみのgrubが出てくるので適当に選んで進みます。

インストールの準備をする

  • ネットワーク

自分のPCにはRJ45がささらない(かつUSBtoRJ45を持ってなかった)のでWiFiでインストールしました。 Live環境にはもとからwpa_supplicantが入っているのでこれでよしなに繋いでdhcpcdでip addressを貰えばいい感じです。

% ifconfig {interface} up
% wpa_supplicant -B -i {interface} -c <(wpa_passphrase {SSID} {PASSWORD})
% dhcpcd
  • ストレージ

自分のPCのSSDにはすでにOpenBSDとArchLinuxとUbuntuが入っていて一杯だったのでUbuntuの入っているパーティションをmkfs.ext4して使うことにしました。

  • 日時

ntpがちゃんと降ってくる恵まれた環境だったのでntpdで時間を合わせました。

  • stage tarballのダウンロード&展開

current-stage3-amd64を選択しました。tar.xzの展開方法が分からなかったので調べました。

  • make.conf

CFLAGSに-march=nativeを足して、MAKEOPTSに-j3を指定しました。

  • mirror serverの選択

北陸先端科学技術大学院大学にお世話になります。

  • DNS情報のコピー

これ最初忘れてて、あれ?インターネットにつながらないぞ!!を20分くらいやってました。

あとは適当にマウントしてchrootすればベース環境に入れます。

ベース環境の整備

よくわからないのでwikiに従って適当にやりました。eselectでprofileを選ぶところ、変にgnomeとかついているやつを選んでしまったので@worldの更新に3時間くらい取られました。まいった。

カーネルビルド

Gentooの象徴とも言えるカーネルビルドのお時間です。 まともに使えるLinuxカーネルのビルドはいままでに一度もやったことがなかったので結構苦戦しました。 とりあえず大事なのは、使うファイルシステムのドライバとUSBドライバをちゃんと選択しておくことです。これだけクリアしてればあとから何度でもやり直しできます。

自分がいじった設定としては、MMCとSCSI周りとUSBのNetworking Frameworkの有効化、それとNICのドライバをカーネルに含めてしまう設定くらいのものです。

今後いじってみて足りない機能は追加してみます。

設定が終わったらmakeしてカーネルモジュールとbzimageのインストールをして終わりです。このとき、/bootをマウントするのをお忘れなく。

fstab

必要に応じて書きます。最低限、/と/bootがあれば良さそう。

Hostname

かっこいい名前をつけましょう。モテるための秘訣です。

あとはwiki通りにやってumountして、grubのコンフィグをいじるとブートできます。 ブートしたあとはx11とwmを入れてstartxすると幸せになれます。

(ポエム書き終えたけどまだFirefoxコンパイル終わってない...)

アマチュア無線技士3級試験に合格した

CTFのWriteupに続いてアマチュア無線技士試験のWriteupを書きます。

昨年、僕はこんな記事を書きました↓

yukium.hatenablog.jp

要するに、デジタル通信訳わかんないから、とりあえずアナログ通信から勉強してみたかったわけです。 それで取り敢えず3アマを取ってハムになってみようと思っていたのですが、バイトとかCA行きとかSecHack365とかプロコンとか色々盛りだくさんの一年だったおかげで、試験は受けられずにいました。 ずっと受けよう、受けようと思っていたのですがなかなか時間が取れず結局平成最後の年、2019年になって時間が取れたので受けてきた、という次第です。

ところで、3アマは東京にある日本無線協会本部で当日試験というものを行っています。当日行って申し込んで、当日試験を受けて、当日合否が分かって更に免許の申請も出来ちゃうという素晴らしい制度です。 なのでこれを目指して試験日の2週間くらい前から勉強し始めました。もともと、電磁気学や電波工学には少し興味があって参考書を読んだりしたことがあったので、過去問は法規さえ暗記すればイケるなーと思っていました。

参考書には以下の2冊を使いました。

第3級ハム国試 要点マスター 2018 (アマチュア無線技士問題集)

第3級ハム国試 要点マスター 2018 (アマチュア無線技士問題集)

初めての3級・4級アマチュア無線技士試験

初めての3級・4級アマチュア無線技士試験

1冊目は、暗記するにはかなり効率的に作られていて2冊目はもう少し丁寧に抽象的な理論と共に解説してくれていて合わせて読むといい感じでした。

それで、試験当日はセンター試験2日目ということだったので、高専生でセンター試験とは縁がない身ではあるのですが取り敢えず気分だけ味わっておこうとセンター試験気分で会場へ行きました。

会場は勝どき駅から少し歩いたところで、東京駅方面へ都営バスも走っているのでなかなか便利なところです。この東京の東側の地域は、人が程よくまばらで建造物が比較的新しくいい街です。 試験は11時からだと思っていたのですがそれはどうやら受付開始時間だったようで、実際は13時からでした。9時30分には会場入りしていたので相当待ちました。時間はちゃんと確認しておきましょう。

それで、試験自体は15分もかからず終わっちゃうような内容で、素っ気なかったです。試験時間は70分ですが、30分立つと中途退出出来るようになります。 退出して、自己採点してみると満点でした。過去問流用の簡単な試験ではありますが嬉しい。 合格発表は50分くらい経ってからでした。自己採点で満点だったのでまあ合格だろうと先に免許申請書等を書いておいて、一応合格を確認してすぐに免許申請へ行きました。 ちなみに合格発表の掲示はこんな感じ。

というわけで、スムーズに3アマの取得が出来ました。勉強時間は合わせて10時間くらいです。不毛な授業中に内職したりしておくと不毛な授業時間が3アマ免許に化けた気がしてお得です。

せっかく免許を取ったので、取り敢えず電波を出してみたいです。もしこの記事をご覧の方で、ハムの方が居たらぜひ交信してください!

InterKosenCTF Writeup [初のイベント型CTFに参戦]

学校の先輩に誘われて、初めてリアルタイムで開催されているCTFに参加してみました(といっても、ksnctfのVillager Aくらいしか解いたことがないので実質CTF処女です)。 3日間の開催でしたが、1日目は早々にして寝落ちしたため、3日目はアマチュア無線の試験を受けに行っていたため取り組めたのは1日だけでした。その1日は先輩と一緒に新宿のルノアールで一日中CTFをやっていました(ルノアールさん長居してごめんなさい)。

webとかcryptoとかはそもそも全く見たこともなかったので解法の検討が全くつきませんでした。なので先輩に任せっきりでした(ごめんなさい)。私が唯一行けそうだなーと思ったのはreversingとpwnだけだったので基本的にその2つだけに集中して取り組みました。 それで、結局解けたのはreversingの100pt問題、「flag generator」だけでした。他の人の参考に、というよりかは解いただけで放置してしまうのはもったいない気がするのでこうして記録しておこうと思った次第です。

問題で渡されたのはx86_64 Linux向けのELFバイナリでした。 実行しても何も表示されず... とりあえず逆アセンブルして読んで見る。

0000000000401152 <r>:
  401152:  55                     push   rbp
  401153:  48 89 e5               mov    rbp,rsp
  401156:  8b 05 f0 2e 00 00      mov    eax,DWORD PTR [rip+0x2ef0]        # 40404c <s>
  40115c:   69 c0 6d 4e c6 41       imul   eax,eax,0x41c64e6d
  401162:  05 39 30 00 00           add    eax,0x3039
  401167:  25 ff ff ff 7f        and    eax,0x7fffffff
  40116c:   89 05 da 2e 00 00     mov    DWORD PTR [rip+0x2eda],eax        # 40404c <s>
  401172:  8b 05 d4 2e 00 00      mov    eax,DWORD PTR [rip+0x2ed4]        # 40404c <s>
  401178:  5d                      pop    rbp
  401179:  c3                       ret

000000000040117a <main>:
  40117a:   55                     push   rbp
  40117b:   48 89 e5               mov    rbp,rsp
  40117e:   48 83 ec 50           sub    rsp,0x50
  401182:  64 48 8b 04 25 28 00   mov    rax,QWORD PTR fs:0x28
  401189:  00 00 
  40118b:   48 89 45 f8           mov    QWORD PTR [rbp-0x8],rax
  40118f:   31 c0                   xor    eax,eax
  401191:  c7 45 d0 35 59 8f 60  mov    DWORD PTR [rbp-0x30],0x608f5935
  401198:  c7 45 d4 91 64 50 57     mov    DWORD PTR [rbp-0x2c],0x57506491
  40119f:   c7 45 d8 57 55 36 27     mov    DWORD PTR [rbp-0x28],0x27365557
  4011a6:   c7 45 dc a1 de e3 54   mov    DWORD PTR [rbp-0x24],0x54e3dea1
  4011ad:   c7 45 e0 d5 4e 5a 75     mov    DWORD PTR [rbp-0x20],0x755a4ed5
  4011b4:   c7 45 e4 b7 2e f4 17  mov    DWORD PTR [rbp-0x1c],0x17f42eb7
  4011bb:   c7 45 e8 59 90 4f 4a   mov    DWORD PTR [rbp-0x18],0x4a4f9059
  4011c2:   c7 45 ec 27 e8 08 1a    mov    DWORD PTR [rbp-0x14],0x1a08e827
  4011c9:   c7 45 f0 1f 39 9d 0d     mov    DWORD PTR [rbp-0x10],0xd9d391f
  4011d0:   c7 45 f4 aa 33 e5 59     mov    DWORD PTR [rbp-0xc],0x59e533aa
  4011d7:   c7 45 c8 7e 16 dc 25    mov    DWORD PTR [rbp-0x38],0x25dc167e
  4011de:   c7 45 cc 0a 00 00 00     mov    DWORD PTR [rbp-0x34],0xa
  4011e5:   c7 45 c0 00 00 00 00    mov    DWORD PTR [rbp-0x40],0x0
  4011ec:   c7 45 c4 00 00 00 00    mov    DWORD PTR [rbp-0x3c],0x0
  4011f3:   c7 45 bc 00 00 00 00    mov    DWORD PTR [rbp-0x44],0x0
  4011fa:   83 7d c4 00            cmp    DWORD PTR [rbp-0x3c],0x0
  4011fe:   75 10                 jne    401210 <main+0x96>
  401200:  bf 00 00 00 00          mov    edi,0x0
  401205:  e8 46 fe ff ff         call   401050 <time@plt>
  40120a:   89 05 3c 2e 00 00     mov    DWORD PTR [rip+0x2e3c],eax        # 40404c <s>
  401210:  b8 00 00 00 00          mov    eax,0x0
  401215:  e8 38 ff ff ff         call   401152 <r>
  40121a:   89 45 bc               mov    DWORD PTR [rbp-0x44],eax
  40121d:   8b 45 bc                mov    eax,DWORD PTR [rbp-0x44]
  401220:  39 45 c8               cmp    DWORD PTR [rbp-0x38],eax
  401223:  75 07                 jne    40122c <main+0xb2>
  401225:  c7 45 c4 01 00 00 00    mov    DWORD PTR [rbp-0x3c],0x1
  40122c:   83 7d c4 00            cmp    DWORD PTR [rbp-0x3c],0x0
  401230:  74 35                 je     401267 <main+0xed>
  401232:  8b 45 c0                mov    eax,DWORD PTR [rbp-0x40]
  401235:  48 98                 cdqe   
  401237:  8b 54 85 d0            mov    edx,DWORD PTR [rbp+rax*4-0x30]
  40123b:   8b 45 bc                mov    eax,DWORD PTR [rbp-0x44]
  40123e:   31 d0                   xor    eax,edx
  401240:  89 45 bc               mov    DWORD PTR [rbp-0x44],eax
  401243:  48 8d 45 bc            lea    rax,[rbp-0x44]
  401247:  48 89 c6               mov    rsi,rax
  40124a:   48 8d 3d b3 0d 00 00    lea    rdi,[rip+0xdb3]        # 402004 <_IO_stdin_used+0x4>
  401251:  b8 00 00 00 00          mov    eax,0x0
  401256:  e8 e5 fd ff ff           call   401040 <printf@plt>
  40125b:   83 45 c0 01           add    DWORD PTR [rbp-0x40],0x1
  40125f:   8b 45 c0                mov    eax,DWORD PTR [rbp-0x40]
  401262:  3b 45 cc                cmp    eax,DWORD PTR [rbp-0x34]
  401265:  74 0c                   je     401273 <main+0xf9>
  401267:  bf 01 00 00 00          mov    edi,0x1
  40126c:   e8 ef fd ff ff           call   401060 <sleep@plt>
  401271:  eb 87                   jmp    4011fa <main+0x80>
  401273:  90                     nop
  401274:  b8 00 00 00 00          mov    eax,0x0
  401279:  48 8b 4d f8             mov    rcx,QWORD PTR [rbp-0x8]
  40127d:   64 48 33 0c 25 28 00   xor    rcx,QWORD PTR fs:0x28
  401284:  00 00 
  401286:  74 05                 je     40128d <main+0x113>
  401288:  e8 a3 fd ff ff           call   401030 <__stack_chk_fail@plt>
  40128d:   c9                       leave  
  40128e:   c3                       ret    
  40128f:   90                     nop

適当にジャンプ命令をnopで埋めてみたりしていたら、何やらよくわからない文字が出力されました。 この文字は一体どこからきているのだろうとアセンブラを見てみると 40121aでr()の返り値がDWORD PTR [rbp-0x44]に代入されてそれを元に演算した結果が出力されていると分かりました。 なのでDWORD PTR [rbp-0x44]が正しい文字になるようにしてあげればよいのです。

じゃあ正しい文字になるような値ってなんだよとまたアセンブラを見直してみると最初にnopで埋めていたジャンプ命令の前にcmp DWORD PTR [rbp-0x38],eaxというのがあったのでここからDWORD PTR [rbp-0x38]がその値であると分かりました。

それでこの値をDWORD PTR [rbp-0x44]に入れてstep実行してみると「KOSE」という文字が出力されたのでよっしゃと思い続く処理もステップ実行してみたのですが、その後の文字はうまくASCIIにはなっていませんでした。

それでなにがいけないのかともう一度見直して、そもそもこのr()の返り値は40404cを元に計算されていることを発見し、またこの40404cはループ毎に変化する値であることが分かりました。それで、じゃあ最初のr()を実行し終わった後だけ手動で40404cとDWORD PTR [rbp-0x44]にDWORD PTR [rbp-0x38]の値をいれてステップ実行してみると次のような出力を得られました。

0x45534f4b
0x14654434e
0x25f53497b
0x353494854
0x44145525f
0x55f594c4c
0x645525f41
0x753524556
0x83f474e49
0x90000007d

最後の7dは「}」なので、これはFLAGだ!と思いどうにかこねくり回してFLAGにするのだと思い眺めてみると、MSBが0から9の値で変化していることに気づきました。これがあるせいでうまく文字に出来なかったのですが、これを除いて文字にしてみると見事FLAGが取得できました。

KOSENCTF{IS_THIS_REALLY_A_REVERSING?}

結局1問しか解けませんでしたが、初めて自力で解けたので結構感動しました。CTF面白いね!運営の皆さんありがとうございました。

Majestouch Convertible 2を買った

この記事はプロコンゼミ(SPC同好会) その1 Advent Calendar 2018の18日目の記事です。 夢の中で宇宙旅行を楽しんでいたら、地球のタイムゾーンをすっかり失念していました。ごめんなさい!!! というか、このアドベントカレンダー担当者はほぼ埋まっていたのに全然投稿されていないですねーなんででしょうか。

本来なら、この記事は高速ナベアツの続きを書く予定だったのですが、忙しくて続きがあまり出来ていないのと他のネタが出来たので、ネタ替えをすることにしました。重ねてごめんなさい!! 高速ナベアツの続きは年度内に書ければなーと思います。

yukium.hatenablog.jp

さて、弊部のアドベントカレンダーには他にもキーボードの記事が投稿されていました。

h2so4.hatenablog.com

これです。彼いわく、このキーボードはHHKBより良いらしいです。

さて、まあキーボードと言えどもピンキリですよね。高いものは学生には手が出せないくらいの値段しますし、秋葉原で投げ売られているものを買えば100円とか、ひょっとしたらもっと安く手に入るかもしれません。 筆者はしがない三流ソフトウェアエンジニアではあるものの、やはり良いキーボードというものに憧憬を抱くわけです。そこで、今回タイトルの通りMajestouch Convertible 2というキーボードを買ったという次第です。

それで、まずこのMajestouch Convertible 2(以下、MC2と呼ぶ)を買うにあたって重要になるのは軸の色です。 MC2はメカニカルキーボードと呼ばれるキーボードの一つで、キーのひとつひとつが独立したスイッチになっています。 MC2ではこのスイッチにCherry MXというブランドのスイッチを使っています。詳しくは、次のページを見てみてください。

DIATEC|ダイヤテック株式会社 製品情報

このページを見ると分かるように、キースイッチには幾つか種類がありその種類が軸の色によって決まっています。 筆者は、茶軸を買おうと決めました。

そして、アマゾンで注文して届きました。

それで、よく見ると赤軸を注文してしまっていました。間違えてしまった。まあ、違いはクリック感だけらしいのでそんなに気にしてません。

この日はちょうど友人とNTTの技術史料館に行く用事があったのでこのキーボードを持ち歩いてみることにしました。もともとキーボードは色々なところに持ち歩いて使おうと思っていたので良い機会です。

重量は電池を入れると1kgくらいあるので結構重かったです。リュックサックじゃなかったら持っていくのは迷いますね。

それで、打鍵感についてですが、赤軸でもけっこう良かったです。打っていて楽しいです。さっそくAtCoderの問題も解いてみました↓

atcoder.jp atcoder.jp

Enterキーが今まで使っていたキーボードより長くてこのあたりの慣れが必要です。あ、キーボードの写真が未掲載でした。載せます。

f:id:yuhki0223:20181229100544j:plain

こちらが今回買ったMC2のキーボード。

f:id:yuhki0223:20181229101029j:plain

こちらが普段使っているThinkPad Yoga 260の内蔵キーボード。

初めて手にしたノートパソコンのキー配列がUS配列だったので、それからずっとUS配列を使ってます。プログラミングをするときは記号のキーがいいかんじの所にあるので打ちやすいです。

見ての通り、配列自体はほぼ一緒(MC2のCapital LockとControlは入れ替えた)ですが、キートップの表面積が結構違うので前述の通り慣れが必要です。

HHKBは矢印キーが独立して存在していないですが、MC2にはあるので全体長は少し長めです。まあギリギリ持ち運べるサイズです。

あ、あとBluetooth機能もついています。ペアリングも簡単でした。

# systemctl start bluetooth
# bluetoothctl
[bluetooth]# power on
[bluetooth]# agent KeyboardOnly
[bluetooth]# default-agent
[bluetooth]# pairable on
[bluetooth]# scan on
[bluetooth]# pair [MAC address]
[bluetooth]# trust [MAC address]
[bluetooth]# connect [MAC address]

こんな感じだと思います。信頼したデバイスに登録しておくと、次回以降接続時にconnectを実行するだけなので楽です。

他のブログ記事を見ていると、キーの遅延があるだとかそういうレビューもあったのですが今の所僕の環境では起きていないです。bluetoothも好調に使えます。

という感じで、雑多なレビューをしてみました。 もしMC2の購入、あるいはキーボードの購入を検討している人がいたら参考にしていただけると幸いです。

お気に入りのキーボードを買って進捗を爆上げしていきましょう!!!