2012-11-07 12 views
5

ASMの1行をシェルコードに変換できます。すなわち:コンパイル時に既知のアセンブリ命令のマシンコードを取得するにはどうすればよいですか?

CALL EBX 

がどのように私はこれをやって、そしてまた、私はDelphiアプリケーションで変数に格納できるように、適切に、このシェルコードを変換することができることについては行くのですか。すなわち:私は右のあなたを取得する場合

var ShellCodeArray: array[0..3] of Byte = ($55,$8B,$EC,$81); 
+2

アセンブラが組み込まれた言語を使用している場合は、そのアセンブラを使用しないでください。 – hvd

+0

さまざまな理由があります。しかし、あなたの返事に感謝します。 –

+1

そのようなものを探していますか? http://www.delphibasics.info/home/delphibasicssnippets/executingpreparedshellcodeindelphi – bummi

答えて

5

、あなたは、Delphi組み込みアセンブラを使用して、単一のアセンブラ命令CALL EBXのマシンコードを取得します。

function CodeToBytes: TBytes; 
var 
    StartAddr, EndAddr: Pointer; 
begin 
    asm 
    LEA EAX, @@start 
    MOV StartAddr, EAX 
    LEA EAX, @@end 
    MOV EndAddr, EAX 
    JMP @@end 
    @@start: 
    CALL EBX 
    @@end: 
    end; 
    SetLength(Result, Integer(EndAddr)-Integer(StartAddr)); 
    Move(StartAddr^, Pointer(Result)^, Length(Result)); 
end; 

はもちろん、あなたが開始と終了ラベルの間で好きな固執することができます:それは価値があるものを、私はSergの答えの重複を避けるだろうし、このようにそれを書くために

function CodeSize: Integer; 
asm 
    lea EAX, @@end 
    lea EDX, @@start 
    sub EAX, EDX 
    JMP @@end 
@@start: 
    call EBX 
@@end: 
end; 

procedure Code; 
asm 
    call EBX 
end; 

function CodeToBytes: TBytes; 
var 
    I, N: Integer; 
    P: PByte; 

begin 
    N:= CodeSize; 
    SetLength(Result, N); 
    P:= @Code; 
    for I:= 0 to N - 1 do begin 
    Result[I]:= P^; 
    Inc(P); 
    end; 
end; 
+0

asmブロックのインスタンスが1つだけになるように記述してください。 –

+0

@DavidHeffernan - なぜですか? – kludg

+0

二度ではなく一度だけ何かを書く方が良い。非常に簡単です。 –

1

1

ただ、例えば、次のコードにダミーの手順を使用して2をsubstract:あなたが使用したコードでも、限り、あなたは他のコードに呼び出さないよう代わりに、ASMのDelphiのコードを使用することを

procedure Code 
asm 
    call ebx; 
end; 

procedure CodeEnd; 
asm end; 

CodeSize := DWORD_PTR(@CodeEnd) - DWORD_PTR(@Code); 
CopyMemory(@MyByteArray[0], @Code, CodeSize); 

注意を(関数/プロシージャ/ RTL)

EDIT:SergとDavid Heffernanのコメントに対する回答として、リリースモードでDelphi 2010の結果を確認しました。

Iは、次のコード使用:

procedure Code; 
asm 
    mov eax, 0; 
end; 

procedure CodeEnd; 
asm end; 


procedure TForm4.Button1Click(Sender: TObject); 
begin 
    ShowMessageFmt('CodeSize=%d', [DWORD_PTR(@CodeEnd) - DWORD_PTR(@Code)]); 
end; 

報告コードサイズは、私は、その後イダプロ(実行に逆アセンブラ)を使用して確認、8バイトである:

.text:004B3344     Code   proc near    
.text:004B3344               
.text:004B3344 B8 00 00 00 00     mov  eax, 0 
.text:004B3349 C3        retn 
.text:004B3349     Code   endp 
.text:004B3349 
.text:004B3349     ; ----------------------------- 
.text:004B334A 8B C0       align 4 

したがって、この例のMOV EAX内を0は5バイト(B8 00 00 00 00)、retn(コンパイラによって追加)は1バイト(C3)、アライメント4は2バイト(8B C0)で合計8です。

+0

コンパイラがダミープロシージャの開始点を揃えることができるので、安全であるかどうかはわかりません。そのため、私は 'CodeSize'関数を使用しました。 – kludg

+0

@Serg:もしそれが整列していれば(コンパイラはそれをしますか?私は決してそれを見たことがありません)コンパイラがNOPを挿入することを確信しています:-) – Remko

+0

よくノップですが、ランダムなバイトであっても、プロシージャーコードがretnで終了する – Remko

関連する問題