5

我希望能够将一行 ASM 转换为 shellcode。IE:

CALL EBX

我该如何去做,并且能够正确地转换这个 shellcode,以便我可以将它存储在一个 delphi 应用程序的变量中。IE:

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

3 回答 3

5

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

只需在代码后面使用一个虚拟程序并减去两者,例如:

procedure Code
asm
   call ebx;
end;

procedure CodeEnd;
asm end;

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

请注意,在您使用的代码中,只要您不调用其他代码(函数/过程/rtl),您也可以使用 Delphi 代码而不是 asm

编辑:作为对 Serg 和 David Heffernan 评论的回答,我在发布模式下使用 Delphi 2010 验证了结果。

我使用了以下代码:

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),对齐 4 是 2 个字节(8B C0),总共是 8 个。

于 2012-11-07T21:47:45.377 回答