5

ASM の 1 行をシェルコードに変換できるようにしたいと考えています。いいえ:

CALL EBX

これを行うにはどうすればよいですか。また、このシェルコードを適切に変換して、Delphi アプリケーションの変数に格納できるようにするにはどうすればよいですか。いいえ:

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

3 に答える 3

5

正しければ、CALL EBXDelphiの組み込みアセンブラを使用して単一のアセンブラ命令のマシンコードを取得する必要があります。

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;
于 2012-11-07T21:03:52.133 に答える
1

コードの後に​​ダミーの手順を使用して、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です。

于 2012-11-07T21:47:45.377 に答える
1

価値があるので、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;

もちろん、開始ラベルと終了ラベルの間に好きなものを貼り付けることができます。

于 2012-11-07T21:24:42.847 に答える