読者です 読者をやめる 読者になる 読者になる

【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

PEの.idataを図解(ILTなし)

昨日.idataの記事を書きましたが、その図を眺めていて「ILTがなくても起動するのではないか?」と思ったので、試しに削ったら起動しました。図も少し簡単になります。これについてつぶやいたところコメントをいただきました。@7shi Delphi で作られたアプリ…

PEの.idataを図解

以前PE勉強会を開催したとき、.idataの構造をうまく説明できませんでした。最近また説明する機会があったので、改めて図を描いてみました。バイナリと並べて構造をフラットに描きました。この描き方は、Excel VBAで作成したコンパイラで使っていたものです。…

MonoDevelopでHello World!

MonoDevelopとGtk#の最初の一歩として、ハローワールドの作成手順をまとめました。 mdev-hello.docx

Gtk#でBrainf*ckのGUIシミュレータ

MonoDevelopの練習の一環としてBrainf*ckのGUIシミュレータの作成手順をまとめました。Gtk#とBrainf*ckの両方が一度に勉強できる内容となっています。 mdev-bf.docx

Pythonでスクレイピング

Pythonでスクレイピングをやってみました。個人的にはプル型パーサが使いやすいのですが、pulldomは妥当性チェックが厳しくHTMLにはそのまま使えないことが多いため、自作パーサを移植しました。 Python移植版 https://gist.github.com/3021786 元の自作パー…

文字列配列を作る (3)

前回、Pythonで文字列配列をJITで表示しました。 文字列配列を作る (2) マーシャリング(ポインタの変換など)はctypesに任せていたので、そこを手動でやってみます。前回と共通の部分(JIT)は、前回のコードを呼び出して処理しています。 mkstr2.py from m…

文字列配列を作る (2)

前回、C言語のargc, argvをJITで表示しました。 文字列配列を作る (1) これをそのままPythonに移植しました。jitモジュールは以下を使用しています。 PythonによるJITで関数呼び出し mkstr1.py import sys from jit import * # for (i = 0; i < argc; i++) {…

Genieのサンプルコード

Genieは絶望的にサンプルコードがありません。仕方ないので、手始めにチュートリアルからコードを抜粋しました。せめてValaからトランスレートできれば良いのですが、逆(Genie→Vala)しかできないようです。 Is there any way to compile between Vala and …

MSYSでValaをビルド

MSYSでValaという言語をビルドしてみました。C言語へのトランスレータで、C#風の構文からGObjectの定型的なコードを出力します。 Vala - Compiler for the GObject type system 先にglibとpkg-configをビルドします。詳細は以下を参照してください。 MSYSでG…

MinGWでwaitpid()とkill()

MinGWでUNIXのプログラムをビルドしていると、waitpid()やkill()でよく引っ掛かります。とりあえずコンパイルを通すため、代わりの関数を実装してみました。※ サポートできない引数は無視しています。 #include <windows.h> #include <process.h> int waitpid(pid_t pid, int *stat</process.h></windows.h>…

classファイルの注釈付きバイナリダンプ

前回の記事で解析したclassファイルのバイナリダンプに注釈を付けました。

classファイルの解析

Javaでハローワールドをコンパイルしてclassファイルを解析してみました。※ 仕様書を参照したため、リバースエンジニアリングではありません。 Hello.java class Hello { public static void main(String[] args) { System.out.println("hello"); } } 実行結…

void *とintptr_t

今まで何度かvoid *の説明を求められましたが、なかなか納得してもらえませんでした。説明を工夫するだけでは限界があると感じたので、別の方法でどうにかならないかを考えてみました。前回の記事の延長線上で説明します。サンプルコードを再掲します。 mov …

メモリ書き込み構文

対象環境を限定できる場合、バイト配列にリトルエンディアンで32bit値を書き込むときに、私は以下のように書いていました。 char buf[32]; *(int *)&buf[6] = 0x12345678; 非常に分かりにくいとご指摘を受けて色々と変形しましたが、どれもしっくり来ません…

odcctoolsの修正 (3)

Mac OS XのasはIntel記法で同じラベルが2度出るとエラーになります。 $ cat intel.s .intel_syntax noprefix call foo call foo $ i386-darwin-as intel.s intel.s:3:suffix or operands invalid for `call'この問題を修正するパッチを作成しました。 --- od…

odcctoolsの修正 (2)

前回、ようやくodcctoolsのアセンブラが動くようになりましたが、odcctoolsに手を出すようになった経緯を書きます。 Mach-O遊びを調査中。Mac OS Xではbinutilsではなくcctoolsを使う。cctoolsは他のOSで使うことは考慮されていないので、クロスでやるときは…

odcctoolsの修正 (1)

前回まででNetBSDとMSYSでodcctoolsをビルドしました。どちらも同じ問題でi386用のアセンブラが起動しませんでした。 http://7shi.hateblo.jp/entry/2012/06/13/005958 (NetBSD) http://7shi.hateblo.jp/entry/2012/06/13/013702 (MSYS) 問題を修正するパッ…

MSYSでodcctools(一部)

前回、NetBSDでodcctoolsをビルドしました。 http://7shi.hateblo.jp/entry/2012/06/13/005958 そこで問題になったのはi386のアセンブラです。問題の切り分けのため、MSYSでもビルドを試みました。ただしすべてのビルドを通すのはかなり大変なので、i386のア…

NetBSDでodcctools

Mac OS Xではバイナリ処理にGNU binutilsではなくcctoolsという独自のものを用いています(asはbinutils派生)。Appleはソースを以下で公開しています。 http://www.opensource.apple.com/ (Developer Tools) Appleが公開しているものはMac OS Xでビルドする…

文字列配列を作る (1)

数回に分けて文字列配列を作ってみます。手始めに検証用サブルーチンをJITで作ってみます。 strarray.c #include <stdio.h> #include <string.h> #include <windows.h> // for (i = 0; i < argc; i++) { // printf(argv[i]); // putchar(' '); // } char buf[] = { 0x56, // push esi 0x8b,</windows.h></string.h></stdio.h>…

C#でJITからコールバック

C#でJITからコールバックさせてみました。PythonのコードをC#に移植したものです。 using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpA…

C#でJIT

PythonでやったJITをC#に移植しました。32bit専用です。 using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, int f…

void*とオフセット

C++

第6回 コンパイラ実装会で出た話題です。以下のコードがエラーになります。なぜ? test.cpp #include <stdlib.h> int main(void) { void *p = malloc(100); *(void **)&p[10] = reinterpret_cast<void *>(free); return 0; } コンパイル結果 $ g++ test.cpp test.cpp: In funct</void></stdlib.h>…

関数のサイズ

第6回 コンパイラ実装会で出た話題です。関数のサイズを取ろうとしたら1になりました。なぜ? test.c #include <stdio.h> int main(void) { printf("%d\n", sizeof(putchar)); return 0; } 実行結果 $ gcc test.c $ ./a.exe 1int aへのポインタが&aであるように、putc</stdio.h>…

jeとjz

x86

第6回 コンパイラ実装会で出た話題です。jzをアセンブルして逆アセンブルしたらjeになると指摘されました。なぜ変わるのか?jeとjzは別名(エイリアス)でまったく同じため、どちらを使っても同じマシン語が出力されます。理由としては、cmp命令による比較は…

第7回 コンパイラ実装会

みんなでコンパイラの実装に挑戦する勉強会です。バイナリいじりの基礎から始めて、実行ファイルを自前のコンパイラで作って動かすことを目標にします。コンパイラをきっかけにして、各種マシンコードやOSのメモリ管理について理解を深めるのが狙いです。 20…

Brainf*ckの分岐をJIT

x86の分岐命令は相対アドレス指定のため、分岐元と分岐先のアドレスが決まらなければ相対アドレスを求められません。Brainf*ckではループの先頭と末尾で分岐が出てきます。相互に分岐しているので少し複雑です。 ループの先頭 loop_begin: cmp byte ptr[esi]…

PythonによるJITで関数呼び出し

前回、Pythonでポインタアクセスする方法が分かりました。 Pythonでポインタ経由のメモリアクセス これを使ってC言語で書いたJITをPythonに移植してみます。コードの詳細は以下を参照してください。 JITで関数呼び出し 共通部 (jit.py) import sys, struct f…

Pythonでポインタ経由のメモリアクセス

Pythonでmalloc()したメモリへのアクセスを試しました。戻り値を POINTER(c_ubyte) へキャストするとアクセスできます。※ 例は32bit Windows限定のコードです。UNIX系ではlibcのロード方法が少し違います。 from ctypes import * malloc = cdll.msvcrt.mallo…

第6回 コンパイラ実装会

みんなでコンパイラの実装に挑戦する勉強会です。バイナリいじりの基礎から始めて、実行ファイルを自前のコンパイラで作って動かすことを目標にします。コンパイラをきっかけにして、各種マシンコードやOSのメモリ管理について理解を深めるのが狙いです。 20…

JITで関数呼び出し

第4回 コンパイラ実装会で出た質問です。※ 例は32bit Windows限定のコードです。【追記】Python版は以下を参照してください。 PythonによるJITで関数呼び出し 相対アドレス i386のcall命令は相対アドレスで指定するため、JITで呼ぼうとすると少し苦労します…

Brainf*ckでループ展開

第3回 コンパイラ実装会で@uho_iiotokoさんがBrainf*ckのトランスレータを実装されているとき、ちょっと面白いことが起きました。元はC言語で実装されたBrainf*ckからアセンブラへのトランスレータです。トランスレート対象がC言語でも同じ結果となるため、P…

CFunctionTypeから関数ポインタを取り出す

Pythonでは関数のアドレスを指定して呼び出せます。以下の例は適当なアドレスなので、呼び出してもエラーになります。 >>> from ctypes import * >>> f = CFUNCTYPE(None)(0x1234) >>> f() Traceback (most recent call last): File "<stdin>", line 1, in <module> Windows</module></stdin>…

Windows x64用のクロスgcc

Windows x64用のクロスgccをビルドしました。MSYSで作業しましたが、他のUNIX系OSでも同じ手順が使えるはずです。 GCC for both x64 & x86 Windows! - MinGW-w64http://mingw-w64.sourceforge.net/ 今回はmultilibを使用せずにx64専用とします。gccが依存す…

Windows NT/Alpha用のクロスgcc

32bitのAlphaのコードがどのようなものか見たくなり、Windows NT/Alpha用のクロスgccをビルドしてみました。ビルドに成功したのはgcc-3.0.4です。binutilsはビルドできるバージョンが見つからなかったため、PEバイナリは出力できません。gcc -Sでアセンブリ…

MSYSでGtk#をビルド

MSYSでのGTK+のビルドと、コマンドライン引数の問題が解決したので、ようやくGtk#のビルドに成功しました。 MSYSでGTK+をビルド (2)http://7shi.hateblo.jp/entry/2012/05/02/120012 MSYSでGTK+をビルド (3)http://7shi.hateblo.jp/entry/2012/05/06/110555 …

MSYSでGTK+をビルド (3)

先日、MSYSでGTK+ 2.24.10をビルドしました。 MSYSでGTK+をビルド (2)http://7shi.hateblo.jp/entry/2012/05/02/120012 このままでもGtk#のビルドはできますが、Gtk#のバイナリ配布物(GTK# for .NET 2.12.10)に含まれるのはGTK+ 2.16.6です。バージョンを…

MSYSのPOSIX互換レイヤをビルド

前回、MSYSのPOSIX互換レイヤをバイナリインストールして利用する方法を取り上げました。 MSYSのPOSIX互換レイヤと引数http://7shi.hateblo.jp/entry/2012/05/05/220750 今回はソースからビルドする方法です。互換レイヤを利用するだけならビルドは不要です…

MSYSのPOSIX互換レイヤと引数

MSYSのコマンド群はPOSIX互換レイヤで動いています。Cygwinから派生したGPLのライブラリで、実体は以下にあります。 /bin/msys-1.0.dll MSYSと一緒に配布されているgcc(MinGW)の出力は互換レイヤを使用しません。通常のWin32バイナリです。この挙動はCygwin…

MSYSでGTK+をビルド (2)

MSYSでGTK+をビルドする手順をまとめました。ビルド後のパッケージ一覧は前回の記事を参照してください。 MSYSでGTK+をビルド (1)http://7shi.hateblo.jp/entry/2012/04/30/181459 ビルドには非常に時間と手間が掛かります。自分でビルドしなくても本家でWin…

MSYSでGTK+をビルド (1)

Gtk#の挙動でよく分からない点があったので、GTK+を調べてみようと思い、MSYSでビルドしてみました。依存関係がとても複雑で、まるで初期のGNOMEをビルドしているような気分でした。【追記】ビルド手順をまとめました。 MSYSでGTK+をビルド (2)http://7shi.h…

MonoDevelopの衝撃

MonoDevelopを試しました。バージョンは2.8.8.4です。 http://monodevelop.com/ 予想以上にパワーアップしていて驚きました。 MonoなしにMicrosoft .NET上で動く。作成したGtk#アプリも同様。 ソリューションはVisual Studio互換。そのままVisual Studioで開…

putchar()とバッファリング

UNIX V6のprintf()は内部で1文字ずつputchar()を呼んでいます。通常は1文字ずつwriteシステムコールが呼ばれますが、特殊な細工をするとバッファリングされるようになります。今回はnmとputchar()のソースを取り上げます。 http://minnie.tuhs.org/cgi-bin/u…

PythonでJIT (Mac OS X 64bit)

先日、PythonでJITをやりましたが、32bitのWindowsに依存していました。 http://7shi.hateblo.jp/entry/2012/04/19/224650 64bitのMac OS Xに移植しました。mmapの戻り値や、munmapの引数に型を指定しているのがポイントです。指定しないとc_int(32bit)とし…

Mac OS X 64bitでシステムコール

64bitのMac OS Xでシステムコールを呼ぼうとしてハマりました。結論から言うと、システムコール番号に0x2000000を足す必要があります。詳細は以下を参照しました。 http://thexploit.com/secdev/mac-os-x-64-bit-assembly-system-calls/ exitシステムコール…

PythonでJITからコールバック

PythonでJITから文字出力するため、sys.stdout.writeのラッパーを定義してコールバックさせてみました。ラッパーのアドレスを引数で渡しています。ctypesチュートリアルにも記載されているように、libcの標準出力関数を使うとIDLEなどで正常に動作しません。…

IronPythonでJIT

前回、PythonでJITという遊びをやりました。 http://7shi.hateblo.jp/entry/2012/04/19/224650 IronPythonでもそのまま動きました。思った以上に互換性があるので驚きました。当初、バッファは(c_ubyte *32)ではなく(c_byte * 32)を使用していました。CPytho…

PythonでJIT

PythonでJITをしてみました。32bit Windowsに依存したコードです。【注】PyPyのようにPythonのコードをJITコンパイルしたわけではありません。CPythonからバイナリ直書きでネイティブコードを生成して実行しました。VBAでも同じことをやりましたが、それに比…

VBAでJITからコールバック

VBA

VBAでJITから文字出力するため、Debug.Printのラッパーを定義してコールバックさせてみました。ラッパーのアドレスを引数で渡しています。簡単に見えますが、結構ハマりました。 pushでespがずれたのを忘れて[esp+8]で引数を取ろうとした。 PutCharの引数にB…

VBAでJIT

VBA

VBAでJITをしてみました。 生成したマシン語を直接呼び出すことができないため、EnumWindows()のコールバックとして呼び出しています。 コールバックには1つだけ引数を指定できます。配列のポインタを渡して、その配列で引数と戻り値をやり取りしています。 …