次のコードをシェルコードに入れることができるように、次の命令のヌルなしの代替を見つける必要があります。
null フリーに変換する必要がある最初の命令は次のとおりです。
mov ebx, str ; the string containing /dev/zero
文字列 str は、私の .data セクションで定義されています。2 つ目は次のとおりです。
mov eax,0x5a
ありがとう!
学習したいのは、アセンブリ コードがどのように構成されているか、特定のプロパティを持つアセンブリ コードでどのような種類の命令が選択されるかということであると仮定すると、(x86/x64 では) 次の手順を実行します。
Intel の命令セット リファレンス マニュアルを入手してください (この記事を書いている時点で 4 冊あると思います)。これらには、オペコード テーブル (命令のバイナリ形式) と、特定のアセンブリ ニーモニック (命令名) に対して許可されているすべてのオペコードの詳細なリストが含まれています。
それらに精通し、それらを2つのグループに精神的に分けます-予想されるプロパティに一致するグループ(「x」文字を含まない...またはその他の特定のプロパティなど)と一致しないグループ. 存在する場合、コードから削除する必要がある 2 番目のカテゴリ。
コンパイル中間体を破棄しないようにコンパイラに指示して、コードをコンパイルします。
gcc -save-temps -c csource.c
objdump -d csource.o
からの逆アセンブリ出力objdump
には、バイナリ命令(オペコード) と命令名 (ニーモニック) が含まれます。つまり、どのオペコード形式が選択されたかを正確に確認できます。上記の 1. に従って、そこにあるオペコードが 2 番目のセットからのものであるかどうかを確認できるようになりました。
仕事の創造的なビットが今入ってきます。逆アセンブル出力で期待/要件に一致しない命令を見つけた場合は、同じ最終結果をもたらす代替 (または、多くの場合、複数の命令の代替シーケンス) を検索/作成します。必要なものに一致する指示のみで構成されています。
上記のコンパイル中間体に戻り、csource.s
アセンブリを見つけ、変更を加え、再アセンブル/再リンクし、テストします。
アセンブリ コードをスタンドアロンにする (つまり、システム ランタイム ライブラリを使用しない/システム コールを直接作成する) 場合は、オペレーティング システムの内部に関するドキュメント (syscall の作成方法) を参照するか、通常はオペレーティング システムで実行するランタイム ライブラリを逆アセンブルします。代わりに、それがどのように行われたかを学びます。
5. は間違いなく宿題なので、与えられたloopに相当するC ループを作成するfor()
while()
のと同じようなものなので、そこにあまり助けを期待しないでください。ここで必要なのは、命令セットのリファレンス マニュアルと (逆) アセンブラの実験です。
さらに、勉強している場合は、コンパイラの仕組みやコンパイラの書き方に関するレッスンに参加してください。コンパイラによるアセンブリ命令の選択方法についても説明されています。出力に文字 ' ?
' ( 0x3f
) が含まれるが決して ' !
' ( )は含まれないことが保証されているコンパイラ0x21
。あなたはアイデアを得る。
xor
プラスをクリアinc
し、必要なshl
ビットのセットを取得するために、一定の負荷について言及しています。
未知の定数 (あなたの unknown str
)をロードするために私が考えることができる最も脆弱な方法は、次のxor
ような値で定数をロードし、0xAAAAAAAA
それxor
を後続の命令で元に戻すことです。たとえば、ロードするには0x1234
:
0: 89 1d 9e b8 aa aa mov %ebx,0xaaaab89e
6: 31 1d aa aa aa aa xor %ebx,0xaaaaaaaa
0xAAAAAAAA
興味深いアスキーを選択することもできます!