兄貴動画見てたらあんかけチャーハン作りたくなった

Posted on

あぁん!?あんかけチャーハン!?というわけで、作って見ました。レシピはこれー

20101226_01.JPG

家族4人分作ったんですが、父親が肉が食べられないので海老にしました。注意点としては、解凍したときの水が結構すごいので、いためてる最中に水を捨てることです。このとき、敷いた油も一緒に流れちゃうのでもっかい継ぎ足さないと油が足りず、ご飯がこげちゃいますw おこげはおこげで美味しいんですが。

調理実習ではいっつも後片付けばっかりやってましたが、作るのもたのしい!プログラミングも裁縫も料理も、何か作るのは結構好きかも。でもどっちかっていうと、料理はプログラミングというよりは実験かな?

東大ニコ研が23日11時からZUNさんの講演会を生放送するお!

Posted on

 東京大学は駒場祭真っ最中なう!

 本日、午前11時より東大でまるきゅう(東方のダンス踊る人たち)主催による、ZUNさんの講演会が行われます!

 私の所属している東大ニコ研では、この中継を生放送します!!いろいろと面白いお話が聞けそうなので、ぜひ聞いてみてくださいね!

五月祭の東方ダンスを、今度は実況中継!

 五月祭で好評だった本講演会主催のまるきゅうによる東方ダンスが、駒場祭でも行われます!最高学府の⑨な人たちによるダンスもぜひ見てゆっくりしていってね。

五月祭の模様

今日の放送

で、あんた何やってるの?

 上記の放送と前後の準備時間以外は、五号館三階、531教室の半分がニコニコ動画研究会で延々と生放送します!

 私は東大の本屋さんでもベストセラーとなったライトノベル僕は友達が少ないに登場する「エア友達」の作り方を、現役エリートぼっち東大生ψ(プサイ)がgdgdと伝授します!

 リア充でもこのご時世、エア友達は必須です!ぜひ作り方を覚えて帰って行ってね。

 ちなみに百合柄の浴衣着てるのでよろしく。今回はちゃんと化粧するよ!そんなんやってるから友達できないんじゃ…。

[東大ニコ研] イカ東がイカ頭つくったでゲソ [ハロウィン企画]

Posted on

イカ娘のイカ帽子をこちらの作り方を参考にイカ東(いかにも東大生)が実際に作ってみたでゲソ。初ニコニコ手芸部。

必要なもの

  • 紙(幅が元の1/4になります。1/6ドール用ならA6がちょうどいい。)
  • ハサミ
  • すずらんテープ(触手用;青色で決まりでゲソね!)
  • のり(触手をくっつける用)

疲れた

ので詳しくは上の動画見てください。そもそも文章と画像だけではわかりづらいな~と思って動画上げたので…。

撮影風景

DSCN4887.JPG

ちさちゃん(ドール)の写真取るの忘れてたー!ま、また今度かぶってもらえば良いか。

そういえばこっちだと初お披露目ですね。>ドール かわいいですよ~、女の子だけの趣味だなんてひどい!子供の時からやりたかったよ~!!

気をつけないと、Ruby on Railsで勝手にDBが書き換えられちゃう?

Posted on

 ふと思いついたネタを。単純なネタですがこの点に関する注意をしている記事を見た記憶がないので。

概要

 scaffoldは気をつけて使わないと、ユーザから上書きされてはいけないフィールドが書き換えられる恐れあり。scaffoldは便利だけど、そのままではすこし危険

scaffoldは便利だけど…

 とりあえずRuby on Railsが有名だと思うのでRuby on Rails(バージョン2.2.3)で書きますが、grailsでも同様の問題がありました。

 さて、まずはscaffoldしないと話になりません:

% rails test
% cd test
% script/generate scaffold User name:string password:string is_admin:boolean

 としてモデル・コントローラ・ビューを自動生成できますよね。このうち、おそらく管理者かどうかをチェックするためにつけたと思われる「is_admin」が、そのままだと一般ユーザから書き換え放題になります。

 どうやるかって?簡単です。newアクションのviewはこうなりますよね。

20100918_01.png

 この時の、生成されるhtmlのうち:

<p>
<label for="user_is_admin">Is admin</label><br />
<input id="user_is_admin" name="user[is_admin]" type="checkbox" value="1" /><input name="user[is_admin]" type="hidden" value="0" />
</p>

 のチェックボックスの<input>とその後のhiddenな<input>が並んだところをコピーして控えておきます。この部分は、このアプリだけでなく他のアプリを攻撃する際にも使い回せます。(name属性だけ書き換えて再利用します。)

 さて。実際のアプリにおいて、is_adminは管理者が設定するフラグであって、ユーザ側から選択できてはマズいですから、削除すると思います。こんな感じで:

<h1>New user</h1>
<% form_for(@user) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :password %><br />
<%= f.text_field :password %>
</p>
//-------------ここから削除------------------
<p>
<%= f.label :is_admin %><br />
<%= f.check_box :is_admin %>
</p>
//-------------ここまで削除------------------
<p>
<%= f.submit "Create" %>
</p>
<% end %>
<%= link_to 'Back', users_path %> 

 そうするとこんな感じの画面になって、一見ユーザからは管理人であるかどうかは選択できなくなりますよね:

20100918_02.png

 実際に、このまま普通に作っても、「Is admin: 」となって、falseになっていることが分かります:

20100918_08.png

 ところがどっこい、動的にHTMLを書き換えてさっきメモした<input>のコードを動的にフォームの中にコピーすると管理者になれちゃいます!w

 FirefoxのFirebugや、Chromeのデベロッパーツールを使えば簡単にHTMLを動的に書き換えることできます。プラグインをインストールする必要が無くて楽なChromeで試してみます。

 デベロッパーメニューはこちらにあります†1: 

20100918_03.png

 次に、動的に書き換えるためにformのところをクリックして、「Edit as HTML」を選びます:

20100918_04.png

 すると編集できるようになるので、先程の<input>のコードを<form>のすぐ次くらいにでも張り付けます:

20100918_05.png

 これで終わりです。適当にエディット領域外をクリックして編集を終了すると…

20100918_06.png

 チェックボックスが出てきます。あとはご想像のとおり。これを黒くチェックして、適当にIDとパスワードを入力すると…

20100918_07.png

 はい、管理者ユーザになれました。

 まあたしかに、is_adminという名前が分からないと書き換えはできないので、ソースコードを公開してないアプリなら即危ないというわけではありませんが、セキュリティ的にはやっぱりマズイと思います。特にオープンソースアプリ…大丈夫でしょうか?

対策

Userコントローラのcreateアクションのうち、

@user = User.new(params[:user])

 この部分を、

@user = User.new(params[:user])
@user.is_admin = false

 にするとか(今確認したらredmineだとこうしてる)、

@user = User.new(:name=> params[:user][:name], :password=> params[:user][:password])

 として、そのアクションで何を書き換えるのかをはっきりさせる、とかでしょうか。

なんだかなあ

 すごく単純なミスですが、実を言うと今まで全く気づかなかったので今回掲載しました^^;UFO大好き霊子さんにもこのミスがあります。証明写真作成工房は修正しておきました。

 出力されるformの中身を自動的にチェックして、formの中身以外のがリクエストに混入してたらアウトって出来ないのかなあ?その方がrailsっぽいよね。Ajaxで動的にフォームを生成するときは、そのための設定をするとか。

 ソースコード読んだら修正できるだろうか?

  • †1: Dev channelなので、多少画面はお手持ちのChromeと異なる可能性があります

磯野ー!ワードサラダ作ってアフィリエイト付スパムブログしようぜー!

Posted on

 この記事は「[痛デバドラ] /dev/louise_love作ってみた [Linux]」の解説記事です。内部でルイズコピペを自動生成するために使った、ワードサラダの技術について解説しています。

ワードサラダ??

 みなさんはワードサラダってご存知でしょうか。サンプルとしてこのBlogを上げておきます。なんだか、日本語が変じゃありませんか?ところどころ読めるけど、なんだか変なような…。

着目すべきは、「核抑止力」を「強化」するという表現である。。

これについては核武装大腸がんの予防論を参照。。

 核武装大腸がん???なんじゃそら。

 こういった、ぱっと見日本語に見えるんだけど、ちゃんと読むと意味不明、という文章を「ワードサラダ」と呼びます。†1スパマーがプログラムで自動生成して、スパム広告用のBlogに利用しているみたいです。†2

 さて、こんな文章どうやれば作れるんでしょう?ワードサラダの作り方を書いてあるサイトは結構あるんですが、ちゃんと動くソースコードが貼ってあるサイトはなかなかないんで、実際にやってみましょう。

実際にRubyで作ってみよう

 ソースコードは「[痛デバドラ] /dev/louise_love作ってみた [Linux]」の「辞書作成ユーティリティ」の中にありますので、DLしてみてください。githubでも公開していて、Webから見るならこちらの方が便利かもしれません。

 なお、利用にはYahoo!デベロッパーネットワークのアプリケーションIDが必要です(OAuthは利用しません)。取得したIDは、parser.rb冒頭の「APP_ID」にセットしてください。

大まかな流れ

  1. 文章を形態素解析
  2. マルコフ連鎖のための辞書を作成
  3. 辞書に基づいて実際にマルコフ連鎖して文章を生成

形態素解析

 形態素解析とは、文章を解析して、単語にわけ、それぞれの品詞についても調べる事です。受験の時に古文で同じことを手動でさせられましたが(涙)、受験でも何でもありませんのでコンピュータに自動で解析させましょう。

 形態素解析のソフトにはMeCab等のローカルのライブラリを使うのが定石みたいですが、インストールがめんどくさいので、Yahoo!の構文解析WebAPIを使おうと思います。Web経由なんであまり高速に大量のデータは処理はできませんが、まあ実験には十分でしょう。

 さらに係り受け解析の結果も使うとそれっぽい日本語が作れるようですが、目的がルイズコピペの無限生成なんで、そこまでやらなくてもそれっぽい文章ができると思います。係受け解析の結果も利用するうまい文章作成ソフトができたら/あったら教えてください。

 以下、実際に行なってるコードです。「libparser.rb」内にあります。

class YahooParser < Parser
	API_SERVER = 'jlp.yahooapis.jp'
	API_URL = '/MAService/V1/parse';
	BOM_UTF8 = [0xef, 0xbb, 0xbf].pack("c3")
	def initialize(api_id = APP_ID)
		@data = "appid=#{api_id}&results=ma&sentence="
	end
	def parse(text)
		http = Net::HTTP.new(API_SERVER);
		resp = http.post(API_URL,@data+URI.encode("#{text}"));
		if resp.code != '200'
			raise "Yahoo! Japan Parser unavailable. Return Code:#{resp.code}"
		end
		body = resp.body;
		doc = REXML::Document.new(body).elements['ResultSet/ma_result/word_list/'];
		text = Text.new();
		doc.elements.each('word') {|item|
			surface = item.elements['surface'].text if item.elements['surface'] != nil
			next if surface.empty? || surface == BOM_UTF8
			reading = item.elements['reading'].text if item.elements['reading'] != nil
			pos = item.elements['pos'].text if item.elements['pos'] != nil
			baseform = item.elements['baseform'].text if item.elements['baseform'] != nil
			text << Word.new(surface,reading,pos,baseform)
		}
		return text;
	end
end

 概ね、’net/http’を使ってAPIのURLにPOSTで文章を送り、結果(XMLで帰ってきます)を’rexml/document’で読み込んで、形態素解析の結果を得るだけです。あえて上げれば、”elements[‘ResultSet/ma_result/word_list/’]”として、DOMを操作する手間を少し省くのがコツ…?

 それぞれの要素の意味は、

  • surface:字面です。「桃色」だったら「桃色」
  • reading:読み方です。「桃色」だったら「ももいろ」
  • pos:品詞です。「桃色」だったら「名詞」
  • baseform:動詞だった場合の”終止形”です。「届け」だったら「届く」。でも、今回の文章生成には使ってません。

マルコフ連鎖のための辞書を作成

 さて、以上の形態素解析は自然言語をコンピュータで扱うなら定番の処理で、ワードサラダ生成の処理はここからが本番です。”markov.rb”内にあります。

class Dic
	def initialize()
		@dic = Hash.new();
		@dic2 = Hash.new();
		@size = 0;
	end
	def add(text)
		if @first == nil
			@first = text[0]
			@second = text[1]
		end
		#二階
		for i in 0..text.size-2
			word = text[i]
			if @dic[word.reading] == nil
				@dic[word.reading] = Array.new
			end
			@dic[word.reading] << text[i+1]
			@size += 1;
		end
		#三階
		for i in 0..text.size-3
			word = text[i]
			word2 = text[i+1]
			if @dic2[word.reading] == nil
				@dic2[word.reading] = Hash.new
			end
			if @dic2[word.reading][word2.reading] == nil
				@dic2[word.reading][word2.reading] = Array.new
			end
			@dic2[word.reading][word2.reading] << text[i+2]
		end
	end
=begin
・・・
(略)
・・・
=end
end

 簡単にいえば、「ある単語の後にはどんな単語が来るか」というインデックスをつくっています。

20100907_louise01.png

 こういう感じの対応表をハッシュと配列を使って記録しています。ハッシュのキーには字面ではなくよみがなを使っていて、これはなんとなくです。なお、この図とは違って同じ単語も何度でも登録していて、一応後で文章を生成したときに、「ルイズ」の後の単語の出現頻度が元の文章と同じになるように調整しています。

 さらに、これだけだと文章があまりにも不安定になるので、「ルイズ/へ」→「届け」、という、ハッシュのキーが二段階になっている辞書もつくっています。これが「三階のマルコフ連鎖」と書かれているところです。

辞書に基づいて実際にマルコフ連鎖して文章を生成

 というわけで、作った辞書を使って実際に文章を生成してみましょう。同じくmarkov.rb内にあります。

class Dic
=begin
・・・
(略)
・・・
=end
	def next(word = nil,word2 = nil)
		if word != nil && word2 != nil
			# 三階の連鎖
			array = @dic2[word.reading][word2.reading];
			if array == nil #辞書に入っていない場合は、二階のマルコフ連鎖を行う
				array = @dic[word2.reading];
			end
			return array[rand(array.length)];
		end
		# 最初
		if word == nil && word2 == nil
			return @first
		end
		# どちらかnullでない方
		left = (word == nil ? word2 : word);
		# 次
		if left == @first
			return @second
		end
		# どっちかが足りない=二階の連鎖を行わざるをえない
		array = @dic[left.reading];
		return array[rand(array.length)];
	end
end

 このdic#next()に、ふたつ前の単語といっこ前の単語を渡すと、今度出力されるべき単語が返されます。

 上で作った辞書からランダムに選ぶだけです。三階のための辞書は場合によっては組み合わせによって該当する辞書が空の場合があるので、その場合は二階の辞書を使います。(二階の辞書は、文章の最後の単語以外は必ず対応する単語があります)

実際につくった文章

% ruby markov.rb <文章>

 とすると実際に文章が生成されます。copipe/内にいくつか文章がすでにあります。

ルイズコピペ

ルイズ!ルイズ!ルイズ・フランソワーズたんの桃色ブロンドの髪をクンカクンカしたいお!モフモフ!髪髪モフモフ!カリカリモフモフ…きゅんきゅい!!!!にゃあああああああ!かわいい!ルイズ!ルイズぅぅうううわぁああああああああああああああああああああああ!!

小説11巻のルイズちゃんは現実じゃないんだねっ!

この!ちきしょ!やめてやる!!

あっあんああっああんあアン様ぁあああ!!いやぁああああああああああああん!!!あぁあ!!俺の想いよルイズへ届け!!

あっあんああっああんあアン様ぁあ!!あ…小説もアニメもよく考えたら…

ルイズちゃんは現実じゃない?にゃああああ…あっあっー!あぁああああああ!!!

あぁ!クンカクンカ!

ルイズルイズぅううぁわぁああああああああああああ!!

スーハースーハー!

吉野家

そんな事より1よ、ボケが。

150円。

お前は本当につゆだくで、それに大盛りギョク(玉子)。これ最強。

そしたらなんか人がめちゃくちゃいっぱいで座れないんです。吉野家。

よーしパパ特盛頼んじゃうぞー、とか言ってるの。もう見てらんない。

そこでまたぶち切れですよ。ボケが。

ねぎだくってなさいってこった。

素人にはお薦め出来ない。

Uの字テーブルの向かいに座った奴といつ喧嘩が始まってもおかしくない、

刺すか刺されるか、そんな雰囲気がいいんじゃねーか。おめでてーな。

お前は本当につゆだくを食いたいのかと。

そこでまたぶち切れですよ。ボケが。

吉野家ってのはな、もっと殺伐としてるべきなんだよ。ボケが。

得意げな顔して何が、つゆだくって言いたいだけ

ステーキを食べたくなったので

ステーキを食べたくなったのでステーキの話を書きますが、とある日僕が気づいたのです!

やっぱりそうだ、確信した!僕の好きな食べ物は、ステーキより高いステーキソースさえあれば、そもそも本体は肉でステーキ。ちょっと新ワードですが。

それ以来、ステーキソースをかけて食べるのでは!?

ってことで、食べる!うわーこれもうまい!!

やっぱりそうだ、確信した!僕の好きな食べ物は、ステーキより高いステーキソースをかけて食べるのでは!?

と、盛り上がったところで本題に行きます。

結果から言えば牛となんら変わりませんでしたYO!

ということで、食べる!うわーこれもうまい!!

という点です。

それ以来、ステーキソースでステーキを食べておりました。

しかし!ようやく今日気づいたのです!

と、

 割とサクサク読めて、でも意味がさっぱり分からない感覚は再現できましたかね?そういえば、難しい本読んだ時とかもそんな気分になるよね…。

 はっ!哲学の論文をこれに掛けたら誰も分からないのでは!?

  • †1: 他の例としてこのサイトを挙げておきます。
  • †2: このBlogだと広告が貼ってませんが…一体なんのために作ったんだ、このBlog。

「一応動く」Linux用デバイスドライバをつくろう

Posted on

 これは「[痛デバドラ] /dev/louise_love作ってみた [Linux]」の解説記事です。

 今回は「Linux2.6系(今回は2.6.32)からドライバとして認識されるには最低限何をしないといけないのか」をまとめてみます。

 えらく貧相な話ですが、最初のとっかかりとしては需要のある話かなあ、と。というかですね、自分自身が欲しかったのですよ。

キャラクタ型とブロック型デバイス

 Linuxのデバイスは、おおよそ二つの種類に分けられる…らしいです。ブロック型というのは固定長の長さずつでしか入出力出来ないデバイスで、キャラクタ型はそれ以外、だそうです。とりあえず、The Linux Kernel APIを見ると別々にAPIが定義されてるので、OSからもかなり別物として定義されているようです。

 今回は、とりあえず情報も多く楽なキャラクタ型デバイスを作ります。

サンプルソースコード

[痛デバドラ] /dev/louise_love作ってみた [Linux]」のソースコードを使って解説します。githubでも公開していて、Webから見るならこちらの方が便利かもしれません。

デバイスドライバに最低限必要な関数

 カーネルモジュールとして名乗るために、名前やライセンスを名乗る必要があります。

MODULE_AUTHOR("PSI");
MODULE_DESCRIPTION("\"I love Louise tan!\" MODULE");
MODULE_LICENSE("GPL");

 なお、”MODULE_LICENSE(“GPL”);”ですが、これがオープンソース系ライセンスでないととロードした時に

Warning: loading /lib/modules/..../***.o will taint the kernel: non-GPL License - Proprietary

という感じのワーニングメッセージが出るそうですが、Linuxantという会社は

MODULE_LICENSE("GPL\0for files in the \"GPL\" directory; for others, only LICENSE file applies");

 としてその汚染メッセージの表示を回避したとか…。よう考えるわ。

 さて。まず、初期化と終了のための関数が必要です。初期化はinit_module、終了処理はcleanup_moduleという関数で行ってください。どうしても別の名前が良い時は、

module_init( 初期化する関数名 );
module_exit( 終了処理をする関数名 );

 というのを関数外に書くことで代用できます。

初期化処理

int  init_module( void ){
	if ( register_chrdev( 0x0721, "louise_love", &louise_fops ) ) {
		printk( KERN_INFO "louise_love : louise chan ha genjitsu ja nai!?\n" );
		return -EBUSY;
	}
	buildDictionary();//ルイズコピペ表示のための辞書作成処理
	printk( KERN_INFO "louise_love : kunka kunka.\n" );
	return 0;
}

 0を返すと初期化に成功したとカーネルが判断し、ロードされます。register_chrdevでデバイスとしてカーネルに登録でき、この時の0x0721はメジャー番号と言って、あとで/dev/louise_loveとドライバの紐付けを行う際に必要な番号、”louise_love”はデバイスドライバの名前(lsmodしたときに見れるやつ)、louise_fopsはfile_operations構造体で、カーネルからデバイスを操作するときに使われる関数で、あとで定義します。

 register_chrdevの詳しい説明はこちらで。

 printkというのが出てきますが、これはprintfのカーネル版で、dmesgした時等に表示されます。フォーマットストリングの前にはKERN_INFO等を付けないと表示されません。詳しくはこちら。

終了処理

void cleanup_module( void ){
	unregister_chrdev( 0x0721, "louise_love" );
	printk( KERN_INFO "louise_love : Harukeginia no louise he todoke !!\n" );
}

 unregister_chrdevでアンロードするだけです。特に説明しません。詳しくはこちら

デバイス操作関数

 カーネルはregister_chrdevに渡すfile_operations構造体に記された関数を通してデバイスを操作します。デバイスドライバを作るには、そのうち最低限以下を実装しなければなりません。

  • open
  • release
  • readかwrite

 ここを見てプロトタイプの通りに実装してください。

 open( struct inode* inode, struct file* filp )のinodeはとりあえず無視していいみたいで、filpのfilp->private_dataに自分でkmallocを使って確保したデータを渡すことで、このデータも使ってwriteやreadが制御できます。

 あとは多分ソース見れば分かるかな…?

デバイスドライバをコンパイルするための最低限のMakefile

 ”-DMODULE -D__KERNEL__”を付ければ普通にコンパイルできるよ!って話もあったんですが出来ませんでした。-Iとかも色々いじったりもしたんですが通りません。昔の話みたいです。

 というわけで、こちらのサイトのMakefileを流用しましょう。

 ファイル名はMakefile(先頭大文字)じゃないとエラーが出るみたいです。

 今回は、このMakefileにこんな行も追加してインストール・アンインストールもできるようになっています。

install: all
	sudo mknod /dev/louise_love c 0x0721 0
	sudo chmod 0666 /dev/louise_love
	sudo insmod louise_love.ko

uninstall:
	sudo rmmod louise_love
	sudo rm -f /dev/louise_love

 mknodで特殊ファイルを作成&0x0721というメジャー番号を使って作成しています。cはキャラクタデバイスで、0x0721はメジャー番号で、register_chrdevしたときの数字とあわせてください。0(マイナー番号)はちょっとよくわかりまへん…。マニュアルはこちら

 chmod 666はただたんに、誰でも読み書きできるようにしているだけです。

 特殊ファイルを作ったあとにinsmodして作ったカーネルモジュールを読み込んで、/dev/louise_loveの制御を作ったドライバに任せています。

 uninstallでrmmod <モジュール名>することでドライバをアンロード、スペシャルファイルは普通にrmdirで削除できます。

 今回分かったんですが、bashでのif文はこういう構造なんですね。

if <条件:[ -e /tmp/...]など>; ←文の句切れ
then コマンド1; ←then~コマンドまでで一文
else コマンド2; 同様 else~コマンドで一文
fi

 いやーこれに気づかずに結構時間が掛かりました…。thenとコマンド1のあいだ、elseとコマンド2のあいだに;をいれるとエラーがでちゃうんだもん。

さらなる情報を得るには(参考サイト一覧)

 デバイスドライバのインターフェーイスは割と変わるみたいなので、他の記事を参考にする場合はバージョン情報や書かれた月日は参考にしたほうがいいです。

 ちなみにこの記事はカーネル2.6.32を対象に書いています。

[痛デバドラ] /dev/louise_love作ってみた [Linux]

Posted on

全自動無限ルイズコピペ生成器搭載!

これは何?

Linux2.6(32bit/64bit)用デバイスドライバです(2.6.32で動作確認しています)。インストールすると/dev/louise_loveが現れ、読み出すとルイズコピペをマルコフ連鎖アルゴリズムに基づいて無限に自動生成し続けます。

ちなみに/dev/louise_loveへ書き込むとすべて書き込みを読み捨てますので、自分の書いたポエムも安心して読んでもらえます。

デモ

ソースコード

使い方

まずはダウンロードして解凍し、フォルダを移動しましょう。

% git clone https://github.com/ledyba/louise_love_driver.git
% cd louise_love_driver/driver

コンパイルするには、普通のプログラムのようにmakeしてください。

% make

デバイスドライバドライバと同時に、ユーザランドで動くアプリケーションとしてもコンパイルされているので、いきなりデバイスドライバとして組み込むのが不安な方は、安全なユーザランドで試すことができます。それには、

% make test
もしくは
% ./userland_louise_love

として実行してください。

では、実際にデバイスドライバとしてインストールしてみましょう。root権限が必ず必要です。

% sudo make install

おめてとうございます、インストールが完了しました。ルイズたんへの愛を得るにはこのようにしてください。

% cat /dev/louise_love

ゆっくりルイズたんへの愛を噛み締めたい場合は、moreコマンドなどを使うと良いでしょう。

ハードディスクやSSD、USBメモリをルイズたんへの愛で埋める場合には、次のようにしてください(注意:これをやるとHDDのデータが壊れます)。

% dd if=/dev/louise_love of=/dev/sda

/dev/louiseのパーミッションは666なので、書き込みも行うことができます。書き込んだデータはすべてスルーしますので、恥ずかしいポエムも安心して書き込むことができます。

% cat my_poem.txt > /dev/louise_love

昨今はアニメが多いですから、ルイズたんへの100年の恋も冷めてしまうかもしれません(一期やってたのもう4年くらい前だし)。でも大丈夫、アンインストールは次のように簡単にできます。

(インストール時に解凍したフォルダで)
% sudo make uninstall

今後の展開

簡単なソースではあるんで、デバドラやマルコフ連鎖の超簡単なサンプルとしてご活用ください。適当に書いたのでソースコードはむちゃくちゃ汚いですがw なお、/dev/yoshinoyaなども(つくろうと思えば)簡単にできます。

任意の文章に置き換えるには、ユーティリティをダウンロードして、

% ruby make_c_source.rb <文章ファイル> > c_source.txt

として出力結果のc_source.txtの中身を、louise_love.cの該当部分に適当に貼りつけてください。

ちなみに、

% ruby markov.rb <文章ファイル>

とするとrubyを使っていくつか文章を作ってくれます。

反省点

あまりカーネルランドをいじった感が無いのがちょっと…。8割のコードはAPIの名前さえ変えればユーザランドでも動きますし、そもそもデバイスドライバなのに、ハードウェアを触っていません。

解説記事

ちなみに:ユーラランドとカーネルランド時のパフォーマンスの違い

ユーザランド時

% ./userland_louise_love | dd of=/dev/null
1130544+0 記録始め
1130544+0 記録終わり
578838528 バイト (579 MB) コピー終了, 25.5481 s, 22.7 MB/s

カーネルランド時†1

% cat /dev/louise_love | dd of=/dev/null
3619712+0 記録始め
3619712+0 記録終わり
1853292544 バイト (1.9 GB) コピー終了, 25.9583 s, 71.4 MB/s

単純比較していいのかわからないけどさすがカーネルランド3倍はえーw

  • †1: 条件を近づける?ために、一回パイプ通してます。でもddで直接やっても変わらなかった。

明日(8/2)東大ニコ研でニコ生!&公式サイト

Posted on

 東大ニコ研の公式サイトが出来ました。こちら。

 8/2の20:00に東大ニコ研で生放送を行うことが決定しました!!私もそのうちの一人として参加するので、ぜひ見てね。まずは、ユーザー生放送からはじめる、という形に落ち着きました( gdgdだと思うけどみんな見てね!!

セキュリティ&プログラミングキャンプ2010の応募用紙を晒してみる

Posted on

 どうしても試験勉強に身が入らないのでちょっと気分転換がてら晒してみるテストでございます。来年度以降セキュリティ&プログラミングキャンプに応募しようと思ってる方はどうぞ。こーんなどーしようもない事書いてても大丈夫です。

セキュリティ&プログラミングキャンプ2010の開催を、何で知りましたか?

  • 公式ホームページ
  • 先生からの紹介(高校時代に高校のサーバ管理者からの紹介を受けました)

前提質問(どちらかに○をつけてください)

  • [A] ソフトウェアの脆弱性、およびそれらによる攻撃・防御の仕組みに興味がありますか[はい]
  • [B] Cやアセンブラによるプログラミングに興味はありますか?[ある]
  • [C]キャンプの公式Webページの講義科目に記載されたこの組の講義科目の[概要]と[詳細]と[補足]をよく読んで納得できましたか?[できた]

この組を希望した自分なりの理由を教えてください。また、何を学びたいか教えてください。(選考上もっとも重視します)

今まで逆アセンブラによる解析を行ったり、それを用いたソフトウェアの移植、ゲーム内データのコンバート、自分のさせたいように処理を改変するパッチの作成、コピープロテクト外し(勿論、ちゃんと買った製品でですよ!;起動時に毎回DVDを入れるのが面倒なもので)、簡単なセキュリティホールの発見や攻撃のデモの作成等を行ってきましたが、どれも攻撃一辺倒で防御側の経験が全くありません。

また、基本的に学習は(ネット上で手に入る教材の多い)コピープロテクト外しやゲームの改造を題材に行ったもので行っており、それ以上の応用は難しく、ウイルスや実際のソフトウェアの脆弱性に基づいた攻撃といった、高度な攻撃手法には全く太刀打ちが出来ませんでした。

そこで、このキャンプに参加することで「実際の攻撃で使われる」実用的な攻撃手法について体系的に学ぶとともに、防御側から見たセキュリティについても考えてみたいと思っています。

正直に言えば、その知識を使って社会の役に立ちたいといった立派な目的とか、あるいは逆に銀行のシステムに侵入して自分の口座に大金を送金したい(笑)といった思いは全くなく、純然たる知識欲、あるいは「ハッカーになりたい」という思いで今回応募させていただきました。実際、プログラムを解析したり、脆弱性の突き方を考えるのが楽しくてしょうがないです。

そういった人の方が純粋な探究心は高いでしょうし、歴史的に言えば、そういった純然たる知識欲からセキュリティ上の悪戯をして逮捕されたハッカーが素晴らしいセキュリティ専門家になることもままありましたから、そういう人が居ても良いんじゃないかと思います。

プログラミング歴を教えて下さい。また、今までに作ったプログラム (特にシステムプログラム†1)があれば、差し障りのない範囲で具体的に教えてください。

プログラミング暦は10年ほど。

アセンブラからシェルスクリプト、ウェブアプリから組み込み系(主にゲームハード用)まで、言語・ジャンルは何でも書きますが、何かしらのパズルを解くような、アルゴリズムが最重視されるようなプログラムは不得意で、ツールやシステムをいじるようなプログラムをよく書きます。

ASLRが有効なWindos Vista以降でも実行可能なreturn-to-libc攻撃のサンプル

ASLR(Address space layout randomization)によってライブラリの関数のアドレスは変わっても、アプリケーション内に存在する関数のアドレスは変わらないことを利用した、return-to-libcの攻撃コードです。

アプリに含まれる任意のコードがすべて実行可能になります。

原理や攻撃コードの中身については上記のページをご覧ください。

はづき

コミケで昔頒布した、HTTP over HTTPなトンネリングソフトです。

高校の時、フィルタリングによって高校のネットワークからニコニコ動画に繋ぐ事が出来なかったので作成しました。

(もちろんニコニコ動画以外にもつなげます)

一回自宅のサーバ(私のblogがおいてあるサーバです)を経由することで、フィルタリングを回避します。

[学校のPC]→→[フィルタリングサーバ]   (アクセス制限)   [ニコニコ動画]
↓(プロキシサーバとしてアクセス)                       ↑
[はづきクライアント]→(暗号化)→[自宅サーバで走るはづきサーバ]→↑(代理アクセス)

このはづきサーバはLinuxのデーモンとして実装してあります。

当時の自宅サーバは諸事項でカーネルverが2.4台だったのでプレフォーク型サーバとして実装してあります。

この後、自宅サーバへの異常なトラフィックからサーバ管理者(このキャンプを紹介してくれた人)に見破られ、自宅サーバへもアクセス制限が掛けられて結局使用不能になりました(笑)。

CGIとして実装しなおして複数のフリーウェブサーバに分散して配置し、それらをラウンドロビンして使うといった事も考えましたが、そこまで気合がなかったというのに加え、さすがに負荷が高くフリーサーバでそこまでするのはどうかという思いから断念しました。

さきゅばす

ニコニコ動画の動画を、コメントを動画に焼きこんで(デフォルトでxvidのaviとして)保存するソフトウェアです。

変換部分はffmpegという有名なオープンソースの動画エンコーダに動画フィルタを追加して実装しています。

この動画フィルタは、ffmpeg.exeに追加したDLLローダからnicovideo.dll(実際のフィルタ処理が書いてある)を動的に呼び出して処理しています。

こうした理由は、ffmpeg.exeが余りにも巨大でリンクに5分以上かかるため、頻繁に更新するフィルタ処理部分をdllで分けたほうが開発時間短縮になるからです。

オープンソース化し、そこそこ人気も出ているようです。

ZERO

昔つくったオセロプログラムです。Javaで書かれていて、一般的なNegaScoutというアルゴリズムで動いていました。

Yahoo!レーティングで1700(結構上級者)くらいまで行きました。

ポケモンセーブデータエディタ

GBAの「ポケットモンスター ルビー/サファイア/エメラルド/ファイヤーレッド/リーフグリーン」に対応した、セーブデータの書き換えツールです。

実装に当たってはゲームのROMを吸い出してエミュレータ上でセーブデータの保存処理を解析し、チェックサムを正しく書き換えています。

巫女が死ぬとファイルが消える東方

ゲームの処理の一部を書き加えた上で自分で書いた処理を付け加え、プレイヤがミスをするとマイドキュメントのファイルが一個ずつ消えていくようにしたジョークプログラムです。緊張感が凄いです(笑)。

注意メッセージの表示部分をつぶしてP2Pに流されると非常に危ないので動画しか公開していません。

なお、脆弱性等は一切使っていません。

証明写真作成工房

Webアプリです。

自分の顔写真をアップロードして、顔の中心・あご下・頭のてっぺんの位置を指定すると、証明写真を印刷するためのPDFが作られて、それを印刷することで自分で証明写真を作れるサービスです。

grails(フレームワーク) + iText(PDF作成ライブラリ)で実装しています。

UFO大好き霊子さん

同様にウェブサービスです。使用者が余りにも居なかったのでサーバ更新時に廃止してしまいましたが…。

UFOや心霊、廃墟や超心理学に関する場所をGoogleMapを使って登録して共有し、現地の写真を投稿したりコメントがつけられるサービスです。

ストリートビューとも連携していて、ストリートビューに写っている心霊写真も登録されていたりしました。

成分解析 for CGI written in C

数年前に流行った「成分解析」という占いプログラムを解析して、CによるCGIに実装したウェブサービスです。

SynFlood攻撃プログラム

システムプログラムと呼べるかどうかは分かりませんが、ioctlとかを使って生パケットを組み立て送信して、synflood攻撃をするプログラムを書いたこともあります。

勿論、外部に向けて送信しようとしてもプロバイダで弾かれるのでLAN内でしか効果が無いのですが。


またちょっと時間が無くて開発は出来ていませんが、以下のようなプログラムを作りかけています。

強制Portable化ランチャ(win32)

USBなどにアプリを入れて持ち運ぶ「PortableApps」が最近人気ですが、レジストリに設定を書き込むソフトはそのままではPortableに出来ませんし、「<アプリのフォルダ>/ユーザ名/config」に設定を書き込むタイプのアプリも、PCがわかってユーザ名が変わるとやはり設定が引き継がれません(毎回設定ファイルをコピーすればよいのですが、面倒)。

そこで以下の手順でAPIをフックする事で、レジストリや設定ファイルの書き込みを制御し、Portable化するソフトです。

  1. スペンドした状態でPortable化するアプリをCreateProcess
  2. エントリーポイントのコードをを無限ループに書き換え
  3. とりあえず実行して定期的にEIPを監視
  4. EIPがエントリーポイントまで行ったらプロセスをサスペンド
  5. 制御用のDLLを注入
  6. IATを書き換えてRegOpenKeyExやFileOpenのようなファイル操作関数をフック
  7. CreteProcessもフックし、Portable化するアプリが子プロセスを作るときも1~6を繰り替えし、子プロセスが読み書きするファイル・レジストリも制御する

フックしたRegOpenKeyExやFileOpenでは、同じフォルダにある設定ファイルに基づいてレジストリやファイルの読み書きを制御し、レジストリはファイルに、設定ファイルもユーザ名の部分を適宜変換して読み書きさせ、他のファイルは普通に元のAPIに処理させます。

XPで1/3開発しただけなのでVista以降だともしかするとUACが必要かもしれません…。

Prolog on FastCGI(マルチプラットフォーム)

Prologでウェブアプリを作ろう、とふと思い立ちProlog用のFastCGIモジュールを作りました。Apache/Lighttpdで動きます。

サンプルプログラムの「成分解析 in Prolog」は動いているのですが、Webアプリにあると便利な様々な述語が実装しきれていないのでまだ未公開です。

これまでに開発したプログラムで経験したバグ、およびその影響について差し障りのない範囲で具体的に教えてください。

公開はしていないのですが、開発したシューティングゲームで何故か特定の弾(1~2発程度)の速度が異常に速くなるバグがありました。

原因はいわゆるOff-by-oneで、メモリの配置がちょうど弾の構造体の前のほうにあったデータを長さを超えて書き込んでしまい、ちょうどその「書き込みすぎた」データが弾の速度の領域に被っていて、その書いたデータを速度として読み取ると高速になる、というバグでした。

(静的に確保した領域だったので、メモリの配置が毎回ほぼ一緒でした)

デバッガーを使ってメモリの状態を監視することでやっと発見することが出来ました。

他には「成分解析 for CGI written in C」で入力したテキストの<や>を実態参照に変換し忘れて表示していて、XSSが可能になっていたというバグがありましたが、使われる前に気づいたので無事でした。

あとは条件分岐でa == b && (e == c || d == f)の、括弧を付け忘れて分岐が狂ったり、

void** ptr;
Object* ptr2 = (Object*)ptr;

と*を付け忘れてクラッシュしたり、malloc(size)としたらsize = 0のときにNULLが帰ってきてクラッシュしたり、といったバグは経験した事がありますが、脆弱性となるようなバグは今のところ経験した事がありません。(たぶん発見されていないだけですが)

このように、全体的に防御する側の経験が不足しています。

セキュリティホールは放置しておくとなぜ危険なのでしょうか。自分の言葉で説明してください。

それは、コンピュータはプログラマの忠実なしもべであるはずだからだと思います。

つまり、コンピュータはプログラマという主人の命令に忠実に働く、信頼できる最高の奴隷である、と私は考えています。

その信頼関係があるからこそ、勝手にレジのお金を盗むアルバイトと違って大事なデータも預けられるし、大事なお仕事も代行させられるのだと思います。

それが脆弱性によってコンピュータが攻撃者の命令も聞くようになってしまったり、喋ってはいけない情報を無理やり喋らされてしまったりすることで、主人(プログラマやプログラムを使う人)と奴隷の信頼関係の前提が根本から失われてしまうから、ではないでしょうか。

(逆に、だからこそセキュリティホールを突いたりゲームを改造したりコピープロテクトを外したりするのが楽しいと感じる人が多いのだと思います)

ソフトウェアの脆弱性をなくすには何が必要でしょうか。

短期的には、ソフトウェアを開発するときはできるだけリッチで枯れたライブラリに任せ、”できるだけプログラムを書かない”ことだと思います。

これは車輪の再発明による開発効率の低下を防ぐ意味もありますが、何よりプログラムが短ければそれだけバグも生まれなくなるはずです。

特にソートやデータ構造や文字列操作は自分で書く利点はありませんし(とくにマルチバイト文字列)、絶対にライブラリ任せにした方が良いと思います。

(練習として書いてみる分には悪くないとおもいますが)

長期的には、プログラマはミスをする、という事を前提に対策するしかないと思います。

バッファオーバーフローならJavaやC#みたいに毎回配列を超えていないかをチェックする事で完全に防げますし、NXビットを使えば仮にスタックオーバーフローしてもスタック上にシェルコードを置いて実行させる手法は非常に難しくなります。

ハードウェアやカーネル、実行処理系で注意深く対策し、その上で動く大多数のプログラムはバグが発生してもセキュリティ上の問題までは至らない、という方向に持っていくほか無いように思います。

これでも防げない攻撃はあると思います。

前調べたあるWebの予約管理システムで、ユーザIDとパスワードのチェックはログイン時にしかしておらず、その上さらセッションIDもなく、GETリクエストにユーザIDを入れてユーザを識別しあとはノーチェック(だからそのGETリクエスト先に直接アクセスすればパスワード無しで他人のアカウントをのっとり放題)という、にわかには信じがたいシステムがありました。

この問題自体は確かにWebアプリのフレームワークを用いれば解決できますが、この問題の本質はフレームワークを使っていない事でも、セッションIDがない事でも、ログイン時にしか認証していない事でもなく、プログラマの想像(この場合は「ログインページで認証したのだから、ユーザの個別ページには入れないはずだ」)を超えた、正規の手段(「別にログインページを通過しなくてもユーザ別のページにアクセスできる」)が実は存在した事なのだと思います。

フレームワークの範疇を超えた範囲でのこういった、プログラマの想像を超えるようなセキュリティホールは無くならないだろうと感じました。

これに関してはまだ解決策が見えていないというのが率直なところです。

あなたがある程度読み書きできるプログラミング言語を書いてください。(いくつでも可)

手続き型でしたら、他の言語に移植する程度であれば大体読めます。

特にある程度頑張って読み書きした事があるのは以下でしょうか。

アセンブラ:x86 / ARM / H8

Java / C / C++(「何でも出来すぎる」ので機能を絞って利用している) / Objective-C / Ruby / PHP /

Groovy / SQL / JavaScript / ActiveBasic

Prolog

Brainfuck(笑)

ニワン語(現在処理系を実装中)

そのほかアピールしたいこと、書き足りないことがあれば自由に書いてください。

小さいときに魔法少女アニメを見て魔法使いになりたいと思ったものの、現実世界に魔法は存在しなかったので、変わりに電脳世界の魔法使いだと思ったハッカーになりたいと思い、コンピュータを始めました(笑)。

「電脳コイル」が現実になり、電脳世界と現実世界の境界が曖昧になってくれば私の最初の夢に近づいていくのに。

こういう変り種が居ると面白くなると思いますよ!

  • †1: システムプログラムとは、WindowsのDLLやLinuxのデーモン、各種デバイスドライバやカーネルモジュールなどを指します。

プログラミング&セキュリティキャンプ2010参加のおしらせ

Posted on

独立行政法人情報処理推進機構(IPA)の主催する「プログラミング&セキュリティキャンプ2010」の「セキュリティコース/ソフトウェアセキュリティ組」への参加が決定したのでお知らせします。

 てめーらの税金使って遊んでくる†1からwwwwwwwうへえwwwwwwww

 応募用紙に「社会の役に立ちたいといった目的はありません、純然たる知識欲、あるいはハッカーになりたいという思いから応募しました」とはっきり書いた上で選考されたのだから多分問題ないと思います(キリッ

 高校の時から参加したかったんですが受験で参加できず、大学入ってからやっとこさの参加でございます。浮かないかなあ?

 税金で思い出しましたが、大学のMacでアニメ見るとなかなか画面も大きくて迫力があって良いですよ!!なぜ誰も見ていない!!最近は忙しくてなかなか出来ないのですが…orz

 9月にも試験があると書いたばかり…なんか自分で自分の首を絞めている気がする(

 小学校の同窓会と思いっきり被ってるんですが気にしない事にしました(キリッ

 結局ネットがあるし、同窓会っても本当に8年ぶりに会う人って稀なんだよなあ。

  • †1: プログラミング&セキュリティキャンプなら、送料(交通費)・手数料(宿泊費その他)もIPAが負担!!