2012/06/29

Windowsでファジング用のファイルを一気に作成するプログラムとバッチスクリプト

Bugハンター日記」という、プログラムの脆弱性の発見方法について書いた本を買いました。

その中にiPhoneをハックする章があります。

そこでは、

  • 特定のフォーマットの正常なファイルを一つ用意
  • ファイルの中の1バイトだけが異なるファイルを何パターンも作成
  • それを自動でアプリに開かせる

このように網羅的なアタックでアクセス違反が起こるかどうかを見るという方法が使われていました。

こういうテスト手法はファジングと言うらしいです。

さて、このファジングのためにファイルを1バイトだけ書き換えるプログラムが、ソースは載っているのですが、Windowsでは動かない関数が使われていました。

なので Windows環境でコンパイルできるCプログラムを書きました。

gcc -o fuzz fuzz.c

もしgccがない場合はMinGWなどをインストールしてください。

fuzz.c

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
 int hdl;
 char *name = NULL;
 unsigned int file_offset = 0;
 unsigned int file_value = 0;

 if(argc<2){
  printf("Error: not enough arguments\n");
  return 1;
 }else{
  file_offset = atol(argv[1]);
  file_value = atol(argv[2]);
  name = argv[3];
 }

 hdl = open(name, O_RDWR | O_BINARY);
 if(hdl==-1){
  perror("open");
  exit(1);
 }

 if(lseek(hdl, file_offset, 0)==-1){
  perror("lseek");
  exit(1);
 }

 printf("file offset: 0x%08x (value: 0x%08x)\n", file_offset, file_value);

 if(write(hdl, &file_value, 1)==-1){
  perror("write");
  exit(1);
 }
 
 close(hdl);

 return 0;
}

ちなみにあまり引数の正しさをチェックしてません。オフセットに変な値を渡したりしないほうがいいです。

引数は以下のように渡します。

fuzz.exe funny.doc 10 255

この場合、funny.docの10バイト目を255にして上書き保存します。

また、これを使って次々にファイルを生成させるバッチファイルも作成しました。

go.bat "C:\music\test.ogg" 10 -1

のように使います。

この例では、test.oggを、10バイト目から終端まで(-1を指定すると終端までになります)、1バイトずつ変えては保存します。test10.ogg test11.ogg ... といったファイルが出力されます。

go.bat

@echo off
REM 書式: go.bat "元ファイルへのパス" オフセット 終了するオフセット
REM 例 : go.bat "c:\hoge.doc" 0 100

REM forの中で変数をカウントしながら使えるようにする
REM (遅延環境変数という。%x%のかわりに!x!のように使う)
setlocal ENABLEDELAYEDEXPANSION

REM 環境変数を汚さないように一時的なモードにする
setlocal

REM ファジングをはじめる位置。10進数
set /A off=%2
set /A max=%3
REM ファジングで上書きするときの値。0?255。10進数
set val=255

REM 元にするファイルが存在しない場合エラーを出して終了
if not exist "%~f1" (
 echo "loading...%~f1"
 echo "Error: source file is not found"
 goto destructor
)

REM 位置(オフセット)と終了位置が範囲内にあるか
if "%max%" EQU "-1" (set /A max=%~z1)
if %~z1 LSS %off% (goto invalidoffset)
if %off% LSS 0 (goto invalidoffset)
if %off% GTR %max% (goto invalidoffset)

for /l %%i in (%off%,1,%max%) do (
 cp "%~p1%~n1%~x1" "%~n1%%i%~x1"
 set /A off=off+1
 fuzz !off! %val% "%~n1%%i%~x1"
)

goto destructor

:invalidoffset
echo "Error: invalid offset(%off%) or max(%max%)"
echo "filesize: (%~z1)"
goto destructor

:destructor
REM 使い終わったので元に戻しておく
endlocal

2012/06/13

Three.jsとPhysijsで3D物理演算

three.jsという3Dのライブラリなどを使って、簡単に3Dの物理演算を行うための記事が本当に簡単だったので、翻訳させてもらいました。

著者のJerome Etienneさんはブログ「Learning Three.js」でさらにThree.jsやphysijs他色々な記事を公開されてます。記事で使用するThree.jsのエクステンションtQueryの開発者でもあります。

元の記事: 3D Physics With Three.js and Physijs


これは物理演算に関するさらに別の記事になる。この記事は、physijsというChandler Prall氏によるライブラリについての記事だ。このphysijsでは、ammo.jsthree.js を簡単に連携させることができる。以下で、それを使ったサンプルのコードを見てみることにする。3Dグラフィックスにおいて、物理演算はいつも重要なものだ。物理演算をすると、空間がよりリアルなものになる。ただ何かのオブジェクトをもってくるだけで、素敵に、リアルに動いてくれるだろう。なので一つ一つの動きを調整するなんてことに時間を費やす必要が少なくなる。とてもズボラな筆者には、ここは大事なところなんだ。ちなみに、screencast は、デモ(今回の記事で書くもの)のほか、ammo.jsを使って何ができるかがわかる様々なサンプルを公開しているよ。

物理演算エンジンについて

前回までに、three.js と物理演算についてみてきた。marblesoccerのミニゲームにmicrophysics.jsを使うというものだった。microphysics.jsは、3D物理演算を実装している非常に小さなライブラリだ。それについては、“Lets Make a 3D Game: microphysics.js”“Lets Make a 3D Game: microphysics.js, Even Easier”の記事でほんのちょっとふれたとおりである。microphysics.jsは、たった500行のライブラリなんだよ!ただ残念なことに、このきわめて少ない行数はいくつかの制限を生んでしまっている。

今日は、Chandler Prall氏のphysijsを使う予定だ。これは非常に素敵なライブラリで、three.jsとともにammo.jsを使うのを簡単なことにしてくれる。ammo.jsは、Bullet物理演算エンジンをEmscripten を使ってJavaScriptへ直接移植したもので、そのソースコードは自動でJavaScriptに変換されているため、機能的にはオリジナルのBulletとまったく同じものなのだ。

bulletは、3Dの世界ではよくしられた本格的な物理演算エンジンだ。ドキュメントをみるとわかるのだが、できることは多い。そしてammo.jsは、高機能な3D物理演算エンジンに期待される機能をすべて実装している。@ccliffe氏ことCharles J.Cliffe氏は、ammo.jsを使ったいくつかのデモをみせてくれている。一つは、heighfieldだ。あとstunt trackを見てほしい!なお、この二つは@ccliffe氏のライブラリであるcubicvrを使っている。

physijsはパフォーマンスを考慮して書かれている。ammo.jswebworkerの内部で実行されるので、だいたいの場合はマルチコアCPUを生かせるだろう。つまり二倍以上のCPU処理能力を作成するjavascriptにもたせることができるということなんだ。3Dの座標のデータは使用できるようになると、所有権の譲渡ができるオブジェクト(transferable objects)に交換される。「所有権の譲渡ができるオブジェクト」とは、メインスレッドとwebworkerの間で、データをコピーすることなくデータを移すことができるオブジェクトの特別な型のことだ。ということは、データがどんなに巨大であっても、待ち時間は非常に少なくなるだろう。

はじめよう

今日紹介するコードは、physijsに付属している衝突デモのサンプルをコピーしたものになる。あるプログラムを、同じ方法で実行できると確かにするために再び書き直してみるのは、役に立つこともある:) お試しあれ。というわけで、オブジェクトが地面に落ち、そこでわずかに反発するようにした。それじゃ、やってみよう。

まず典型的なところからさわろう。tQuery.Worldを作成すると、scene(空間)、レンダラ、カメラとカメラをコントロールするものといったオブジェクトがすぐに使えるようになる。これらには、適当な初期値が最初から設定されている。.boilerplate()とすると、“three.jsのひな型(boilerplate)”が追加される。これは去年記事にした。カメラコントロール(cameraControls)は使えないようにする。そして、レンダラの描画ループを動かすため.start()を実行する。

var world   = tQuery.createWorld().boilerplate({cameraControls: false}).start();

さて、sceneの中央から少し離れたところにカメラをセットする。そうすると、さらに大きなオブジェクトをおいてもちゃんと見られるようになった。

world.tCamera().position.set( 70, 40, 70 );
world.tCamera().lookAt( world.tScene().position );

さて、影付け処理が必要であるとレンダラに伝える必要がある。それは以下のシンプルな何行かのコードで実現できる。詳しくは“Casting Shadows”という記事で見たとおりだ。

world.tRenderer().shadowMapEnabled  = true;
world.tRenderer().shadowMapSoft     = true;
world.tRenderer().setClearColorHex( 0xffffff, 1 );

この空間に物理演算を適用することができるようになった。ここは重要なところだ。たった今から、この空間にある物理演算をするよう設定したオブジェクトは、リアルな物理法則にしたがって動くことになる。

world.enablePhysics();

ライトをつけよう

次はライトの設定をしよう。話を簡単にするために、一方向ライトのみを使用しよう。まず好みにあわせて配置位置と色を変える。感覚をつかむためにパラメーターを色々いじってみるといい。では、影についての設定を調整する。場合によっては難しいかもしれない。詳細は、"Casting Shadow"という記事で書いてあるので、それを見てもらってもいい。シャドウカメラ(訳注:カメラのように視野角などで設定できる影付けの方法がある)を可視化するときに便利だ。それには.shadowCameraVisible(true)を使う。

tQuery.createDirectionalLight().addTo(world)
    .position(20, 40, -15).color(0xffffff)
    .castShadow(true).shadowMap(512*2,512*2)
    .shadowCamera(60, -60, 60, -60, 20, 200)
    .shadowDarkness(0.7).shadowBias(.002)

地面を作ろう

まず地面にはるテクスチャを作ろう。岩の感じをだすためにrocks.jpgを使おう。面の上でテクスチャを繰り返すには.RepeatWrappingを使う。それから、適切な大きさにしよう。

var texture = THREE.ImageUtils.loadTexture( "images/rocks.jpg" );
texture.wrapS   = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 3, 3 );

まあ実際には、地面は広くて平坦な立方体だ。昔の人が信じていた地球平面説とちょっと似ている:) それはいまや普通のことだね。さてここまでで、配置位置、材質、影について設定できた。

var ground  = tQuery.createCube(100, 1, 100).addTo(world)
    .position(0, -10, 0)
    .setLambertMaterial().map(texture).back()
    .receiveShadow(true)

さて、地面の物理演算について設定をしないといけない。これは.enablePhysics()で設定できる。引数massで、この物理空間でのこのオブジェクトの重さを定義している。ちなみにデフォルトでは、オブジェクトの大きさから自動的に計算される。ここでmassを0にしているのは、特別な意味があり、「常に重さは無限大であり、動くこともない(静的オブジェクトである)」ことを意味している。

ground.enablePhysics({
    mass    : 0
});

3D空間でオブジェクトを生成する

この空間でオブジェクトを生成するのはいつも、デリケートな問題だ。しかしまず、生成するオブジェクトのテクスチャを読み込んでしまおう。これはオブジェクトを生成するループの外で読み込むので、データが一度だけメモリに読み込まれ、残りは再利用される。よく知られているように、すべてのオブジェクトに対し、データは一度だけGPUへ送られる。パフォーマンス性を考えると、ここは重要なポイントだ。去年、"Performance: Caching Material"という記事でこれに関する話題をちょうどやった。

var cTexture    = THREE.ImageUtils.loadTexture( "images/plywood.jpg" );

さて、オブジェクトを生成する関数としてspawnObject()を宣言した。立方体を作り、配置や回転している角度・材質を設定した。いい感じだよ。あっ、シャドウマッピングが使えるように.castShadow()を使うのを忘れないようにしよう。

var spawnObject = function(){
    var object  = tQuery.createCube(4,4,4).addTo(world)
        .rotation(Math.random()*Math.PI*2, Math.random()*Math.PI*2, Math.random()*Math.PI*2)
        .position(Math.random()*15-7.5, 25, Math.random()*15-7.5)
        .setLambertMaterial().map(cTexture).back()
        .castShadow(true)

オブジェクトに対し物理演算を適用してみる。たった今から、この空間はすべての動きをコントロールできるようになる。独自に設定したパラメーターを使うと、それは物理の法則に反するだろう。以下のfriction(摩擦)は、二つのオブジェクトがお互いにこすれあうときにおこる反発の力だ。次のrestitution(反発)は、オブジェクトがどう跳ね返るかのパラメーター。学術的な定義は、本で見てね:)

object.enablePhysics({
        friction    : 0.4,
        restitution : 0.6
    });

さて、次は「衝突」のイベントをいじってみようと思う。Physijsはあるオブジェクトが別のオブジェクトに衝突したときに教えてくれる。それにはただ.addEventListener()を「衝突」のときに使えばいい。ここでは、何かに衝突した回数によってオブジェクトの色を変えてみることにする。

var nCollisions = 0;
    object.physics().addEventListener('collision', function(){
        var colliColors = [0xcc8855, 0xbb9955, 0xaaaa55, 0x99bb55, 0x88cc55, 0x77dd55];
        if( ++nCollisions < colliColors.length ){
            var color   = colliColors[nCollisions];
            object.get(0).material.color.setHex( color );
        }
    })
}

さて、一秒毎にオブジェクトを生成するのには、シンプルにsetInterval()を使うことにしよう。

setInterval(spawnObject, 1000);

これで終わり!リアルな3D物理演算をすることができた!やあ、悪くないね:)

まとめ

そんなわけで、今はphysijsがあるので、three.jstQueryを使えば、本格的でリアルな物理演算をすることができる。それは空間をよりリアルにするのには単純な方法だ。使ってみるのもいいだろう。また何かこの話題について書くと思う。

どうもありがとう。それじゃお楽しみください。:)


誤訳かな?と思われたら@ikaflower3ikaflowerあっとcrna.sakura.ne.jpまで教えていただけると大変嬉しいです。

three.jsのサンプルを求めてこられる方が多いので追記

three.jsのサンプルはこちらもオススメです。

http://yomotsu.github.com/threejs-examples/

2012/06/01

Three.jsで水滴シミュレータを作った話

この間、Three.jsをつかって簡単なプログラムを作った。(→RainDrops
盤面の水滴が動く3Dの画面が見られる。マウスで回転させて表示することもできる。

簡単に3D表示ができるThree.jsの話

Three.jsというライブラリのおかげで、あまり3Dの用語を勉強しなくても3D表示をすることができた。

なかでも、右クリックで表示しているものを回転させる部分は、とても便利な TrackballControls というのがあって、
controls = new THREE.TrackballControls(camera, renderer.domElement);
//renderer.domElementでは、回転などのマウス操作を有効にする範囲をDOMエレメントで指定している

controls.rotateSpeed = 5.0; //回転するときのスピード
controls.zoomSpeed = 5; //ズームするときのスピード
controls.panSpeed = 2; //パンするときのスピード
controls.noZoom = false; //ズームしない設定をOFF
controls.noPan = false; //パンしない設定をOFF

最低限、この最初の一行をinit()関数なりにいれておけば、3Dをグリグリ回しながら見られるようになるみたいだ。
簡単すぎてびっくりした。

少なくともちょっとした3Dのデータを見せることにも使えるし、夢がひろがる。

アルゴリズムの話

水滴シミュレータのアルゴリズムの方は、boids(ボイド)なんかを見て作った。

boidsは3つのルールで鳥の群れの飛行をシミュレートするもので、Three.jsにもサンプルがあったりする。

このRainDropsは、窓につく水滴が落ちていく様子を同様に3つのルール(boidsとはまた違うルール)でシミュレートする。

まず、水滴が落ちる「ガラス面」を二次元の碁盤のような平面に見立てる。水滴は一滴で一マスとして、水滴をその大きさで表すことにして「重み(weight)」と名づける。そして以下のルールで動かしていく。

  1. 雨が降る ランダムでマスに重みをつける。
  2. まとまる 隣接マスに水滴があるとき、マスすべての重みを足し合わせ、一つのマスにまとまる。
  3. 落ちる 一マスが一定の重さ以上のとき、一マス下へ移動する。

本当に単純なモデル化でシミュレートできるのかな、という疑問を解決するために書いた。

単純なルールで生き物のように動くことで有名なライフゲームも、最初はかなり複雑なルールでつくられていたらしい。

意外とお手軽にシミュレーションできるんだなと思った。