U xxxでオフセットアドレスに格納されている機械語を逆アセンブルすることができるので、これを利用して簡単な自己書き換えコードを書いてみました。
まず、メインの処理。
-A 100
1857:0100 MOV AX, 00FF
1857:0103 MOV DX, 0001
1857:0106 CALL 200
1857:0109
1857:0100 MOV AX, 00FF
1857:0103 MOV DX, 0001
1857:0106 CALL 200
1857:0109
アキュミュレータに00FF、データレジスタに0001をロードして、オフセットアドレス200に記述されたサブルーチンを呼び出します。オフセットアドレス200には加算を行う関数を記述します。
-A 200
1857:0200 ADD AX, DX
1857:0202 RET
1857:0203
足算を引算に書き換えます。203番に引算処理を書いてみて対応する機械語を調べてみます。
-A 203
1857:0203 SUB AX, DX
1857:0205
-U 203 203
1857:0203 29D0 SUB AX,DX
足算の機械語も見ます。
-U 200 200
1857:0200 01D0 ADD AX,DX
オフセットアドレス200を29に書きかえれば、ADDがSUBになるみたいです。ということで、オフセットアドレス200の処理を以下のように書きなおします。
-A 200
1857:0200 ADD AX, DX
1857:0202 MOV BYTE PTR [200], 29
1857:0207 RET
1857:0208
これで、足算をしたあと自分自身の処理が書かれた命令を書きなおし、引算をする関数へと変わるはずです。
以下実行結果。
-G = 100 109
AX=0100 BX=0000 CX=0000 DX=0001 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1857 ES=1857 SS=1857 CS=1857 IP=0109 NV UP EI PL NZ AC PE NC
1857:0109 0000 ADD [BX+SI],AL DS:0000=CD
-G = 100 109
AX=00FE BX=0000 CX=0000 DX=0001 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1857 ES=1857 SS=1857 CS=1857 IP=0109 NV UP EI PL NZ NA PO NC
1857:0109 0000 ADD [BX+SI],AL DS:0000=CD
一回目の呼び出しでは足算が行われています。二回目の呼び出しでは思惑どおり引算が行われます。
0 件のコメント:
コメントを投稿