MASMでQuine。

世の中のハッカーはDOSもMASMも嫌いなんだろう。x86なアセンブラのクワインを探すとLinuxでとか、Bootableだとか、gnu asでとか、NASMでとか、DB(Define Bytes)だけのとかは出てくるのに純粋なDOSのMASM文法準拠のは、どうやっても見つけられなかったので書いた。MSCで書けるならMSアセンブラだってできるはず。(ウィルスのような)自己増殖コードを書く時でなければ、あまり役にも立たないことは分かっているのでやっつけ。動くだけ。特に短かくもない。むしろ長い。

参考 : クワイン – Wikipedia

先に結果から。

quinmasm

 

アセンブリコード quin.asm (実際にはスクリーンキャプチャのq2.asm)

code segment          
 assume cs:code       
 assume ds:code       
llen equ 22           
nlen equ 65           
 org 100h             
sta:                  
 mov dx,offset sr     
 mov di,nlen-2        
lp1: mov bx,1         
 mov cx,llen          
 mov ah,40h           
 int 21h              
 add dx,cx            
 mov si,dx            
 mov dx,offset crlf   
 mov cx,2             
 mov ah,40h           
 int 21h              
 mov dx,si            
 dec di               
 jnz lp1              
 mov si,offset sr     
 mov di,nlen          
 mov bx,1             
lp2:                  
 mov dx,offset dstr   
 mov cx,5             
 mov ah,40h           
 int 21h              
 mov dx,si            
 mov cx,llen          
 mov ah,40h           
 int 21h              
 add dx,cx            
 mov si,dx            
 mov dx,offset qstr   
 mov cx,3             
 mov ah,40h           
 int 21h              
 dec di               
 jnz lp2              
 mov si,offset sr+1386
 mov di,2             
lp3:                  
 mov dx,si            
 mov cx,llen          
 mov ah,40h           
 int 21h              
 add dx,llen          
 mov si,dx            
 mov dx,offset crlf   
 mov cx,2             
 mov ah,40h           
 int 21h              
 dec di               
 jnz lp3              
 mov ax,4c00h         
 int 21h              
qstr db 39            
crlf db 0dh,0ah       
dstr db " db ",39     
sr:                   
 db 'code segment          '
 db ' assume cs:code       '
 db ' assume ds:code       '
 db 'llen equ 22           '
 db 'nlen equ 65           '
 db ' org 100h             '
 db 'sta:                  '
 db ' mov dx,offset sr     '
 db ' mov di,nlen-2        '
 db 'lp1: mov bx,1         '
 db ' mov cx,llen          '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' add dx,cx            '
 db ' mov si,dx            '
 db ' mov dx,offset crlf   '
 db ' mov cx,2             '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' mov dx,si            '
 db ' dec di               '
 db ' jnz lp1              '
 db ' mov si,offset sr     '
 db ' mov di,nlen          '
 db ' mov bx,1             '
 db 'lp2:                  '
 db ' mov dx,offset dstr   '
 db ' mov cx,5             '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' mov dx,si            '
 db ' mov cx,llen          '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' add dx,cx            '
 db ' mov si,dx            '
 db ' mov dx,offset qstr   '
 db ' mov cx,3             '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' dec di               '
 db ' jnz lp2              '
 db ' mov si,offset sr+1386'
 db ' mov di,2             '
 db 'lp3:                  '
 db ' mov dx,si            '
 db ' mov cx,llen          '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' add dx,llen          '
 db ' mov si,dx            '
 db ' mov dx,offset crlf   '
 db ' mov cx,2             '
 db ' mov ah,40h           '
 db ' int 21h              '
 db ' dec di               '
 db ' jnz lp3              '
 db ' mov ax,4c00h         '
 db ' int 21h              '
 db 'qstr db 39            '
 db 'crlf db 0dh,0ah       '
 db 'dstr db " db ",39     '
 db 'sr:                   '
 db 'code ends             '
 db ' end sta              '
code ends             
 end sta              

asm.bat はよくあるアセンブル-リンクのバッチ。

@echo off
masm %1;
link %1;
exe2bin %1 %1.com

アセンブラでのクワインは結構自由に書けてしまってDOSのCOM形式ならば次のような方式はすぐに思いつく。

・自分自身のメモリイメージをダンプ表示する。
・自分自身を逆アセンブルする。

これだとcat $0したみたいで手抜き感があって嫌だ。それにメモリイメージをダンプせずに他の.comか.exeに書き出せば自己複製ウィルスの出来上がりっていうのも嫌な感じ。

ここではそれ以外の方法で、以前MSVC++で書いたような「普通の手続き」でやった。アセンブラの場合は「文字列置換」みたいな軟弱なことができないから、自分自身のコードを db ‘…’ に埋め込んでおき、通常のコードとして表示する部分と、それ自身のデータ部として db ‘ と ‘ で挟んで表示するように、前半部、db表示部、後半部の3パート構成とした。 db部は手抜きするために固定長にしてある。長さはllenで定義してるのに式にすると長すぎるoffset sr+1386のところハードコーディングなのがダサい。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中