我希望能够将单行ASM转换为shellcode。即:
CALL EBX
如何进行此操作,并且能够正确转换此shellcode,以便将其存储在delphi应用程序的变量中。即:
var ShellCodeArray: array[0..3] of Byte = ($55,$8B,$EC,$81);
答案 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个字节。