2010年2月24日水曜日

SBCLでバイト列を逆アセンブルする

Kernel/VM探検隊に参加しました。皆さんスペック高すぎです。参加したおかげで上がったテンションのまま、SBCLで遊んでみた。

1.SBCLにはネイティブコードコンパイラが備わっている。

2.CommonLispでは仕様でdisassemble関数が定義されている。

つまり、SBCLでバイト列を逆アセンブルことは簡単。たぶん。

ということでやってみた。

(defun disassemble-u8-list (u8-list)
(let ((len (length u8-list)))
(let ((alien (sb-alien:make-alien sb-alien:unsigned-char len)))
(unwind-protect
(progn
(loop :for i from 0
:for u in u8-list
:do (setf (sb-alien:deref alien i) u))
(sb-disassem:disassemble-memory (sb-alien:alien-sap alien) len))
(sb-alien:free-alien alien)))))

準備として、アセンブラで適当にコードを書く。

bits 32
section .text

global _start
_start:
mov eax, 4 ;write
mov ebx, 1 ;fd
mov ecx, ptr ;buf
mov edx, 6 ;size
int 0x80
mov eax, 1 ;exit
mov ebx, 0
int 0x80
ptr db 'Hello',10
>nasm -f elf32 test.asm
>ld -o test test.o
>./test
Hello
>nasm -f bin -o test.bin test.asm
>hd test.bin
00000000 b8 04 00 00 00 bb 01 00 00 00 b9 22 00 00 00 ba |..........."....|
00000010 06 00 00 00 cd 80 b8 01 00 00 00 bb 00 00 00 00 |................|
00000020 cd 80 48 65 6c 6c 6f 0a |..Hello.|
00000028

このバイト列を逆アセンブルしてみる。

>(disassemble-u8-list
'(#xb8 #x04 #x00 #x00 #x00 #xbb #x01 #x00 #x00 #x00
#xb9 #x22 #x00 #x00 #x00 #xba #x06 #x00 #x00 #x00
#xcd #x80 #xb8 #x01 #x00 #x00 #x00 #xbb #x00 #x00
#x00 #x00 #xcd #x80 #x48 #x65 #x6c #x6c #x6f #x0a))
; 08089CA8: B804000000 MOV EAX, 4
; AD: BB01000000 MOV EBX, 1
; B2: B922000000 MOV ECX, 34
; B7: BA06000000 MOV EDX, 6
; BC: CD80 INT 128
; BE: B801000000 MOV EAX, 1
; C3: BB00000000 MOV EBX, 0
; C8: CD80 INT 128
; CA: 48 DEC EAX
; CB: 65 GS-SEGMENT-PREFIX
; CC: 6C INSB
; CD: 6C INSB
; CE: 6F OUTSD
; CF: 0A00 OR AL, [EAX]
NIL

2回目のINT命令以降は文字列。objdumpの結果とくらべても間違いはなさそう。最後の0x0Aが0A00とされているが、メモリ上の次の値を読んでいそう。

0 件のコメント:

コメントを投稿