如何在编译时获取汇编指令的机器代码?

时间:2012-11-07 18:34:07

标签: delphi assembly shellcode basm

我希望能够将单行ASM转换为shellcode。即:

CALL EBX

如何进行此操作,并且能够正确转换此shellcode,以便将其存储在delphi应用程序的变量中。即:

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

3 个答案:

答案 0 :(得分:5)

如果我说得对,你想使用Delphi内置汇编程序获得单个汇编程序指令CALL EBX的机器代码。

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;

答案 1 :(得分: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;

显然,你可以在开始和结束标签之间粘贴任何你喜欢的东西。

答案 2 :(得分: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个字节。