ASM の 1 行をシェルコードに変換できるようにしたいと考えています。いいえ:
CALL EBX
これを行うにはどうすればよいですか。また、このシェルコードを適切に変換して、Delphi アプリケーションの変数に格納できるようにするにはどうすればよいですか。いいえ:
var ShellCodeArray: array[0..3] of Byte = ($55,$8B,$EC,$81);
正しければ、CALL EBX
Delphiの組み込みアセンブラを使用して単一のアセンブラ命令のマシンコードを取得する必要があります。
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;
コードの後にダミーの手順を使用して、2つを減算します。例:
procedure Code
asm
call ebx;
end;
procedure CodeEnd;
asm end;
CodeSize := DWORD_PTR(@CodeEnd) - DWORD_PTR(@Code);
CopyMemory(@MyByteArray[0], @Code, CodeSize);
コードでは、他のコード(functions / procedure / rtl)を呼び出さない限り、asmの代わりにDelphiコードも使用することに注意してください。
編集:SergとDavid Heffernanからのコメントへの回答として、リリースモードのDelphi2010で結果を確認しました。
次のコードを使用しました。
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;
報告されたCodeSizeは8バイトです。次に、Ida Pro(実行可能ファイルの逆アセンブラ)を使用して検証しました。
.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)、align 4は2バイト(8B C0)、合計8です。
価値があるので、Sergの答えの重複を避け、次のように書きます。
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;
もちろん、開始ラベルと終了ラベルの間に好きなものを貼り付けることができます。