Arrays 将整数转换为字节数组

Arrays 将整数转换为字节数组,arrays,delphi,cheat-engine,Arrays,Delphi,Cheat Engine,我试图将10位整数值转换为字节,但函数只返回4个值,我需要6个点,如何求解 我用来转换整数字节的函数 var i, j: integer; bbI : array[1.. sizeof(integer)] of byte; begin i := 2337669003; Move(i, bbI[1], SizeOf(Integer)); for j := Low(bbI) to High(bbI) do Memo1.Lines.Append(IntToHex(bbI[j],

我试图将10位整数值转换为字节,但函数只返回4个值,我需要6个点,如何求解

我用来转换整数字节的函数

var
  i, j: integer;
  bbI : array[1.. sizeof(integer)] of byte;
begin
  i := 2337669003;
  Move(i, bbI[1], SizeOf(Integer));
  for j := Low(bbI) to High(bbI) do
  Memo1.Lines.Append(IntToHex(bbI[j],2))
end;
函数返回我

8B FF 55 8B

但我需要更多的2个值

欧共体 五十一

函数应该返回给我

8B FF 55 8B 欧共体 五十一


您可以使用变体记录。在这种情况下,记录的两个字段共享相同的内存:

program Test;
uses
  System.SysUtils;

type
  TInteger = record
    case Byte of
      0: (AsValue: Integer);
      1: (AsArray: array [0..3] of Byte);
  end;

var
  X: TInteger;
begin
  X.AsValue := 123456;
  Writeln(X.AsArray[0]);
  Writeln(X.AsArray[1]);
  Writeln(X.AsArray[2]);
  Writeln(X.AsArray[3]);
end.

您可以使用以下指令:

我试图将10位整数值转换为字节,但函数只返回4个值,我需要6个点,如何求解

你不能。
整数的大小只有4个字节。
Integer
2337669003
是字节序列
8B FF 55 8B
。您无法从中获得额外的
ec51
字节

Int64
的大小为8字节。字节序列
8B FF 55 8B EC 51
将是
5903246413051658240
Int64
值,其高2个字节(
00
)被截断

从屏幕截图中,我们可以清楚地看到字节序列
8B FF 55 8B EC 51
实际上对应于Win32
BitBlt()函数的前4条x86汇编指令。为什么要使用整数值来表示汇编指令?这不是一个好办法。您了解x86指令集实际上是如何工作的吗?你知道整数是怎么工作的吗

在这种情况下,我建议使用实际的字节数组而不是整数数组:

var
  Instructions: array[0..5] of byte;
  i: Integer;
begin
  // mov edi,edi
  Instructions[0] := $8B;
  Instructions[1] := $FF;

  // push ebp
  Instructions[2] := $55;

  // mov ebp,esp
  Instructions[3] := $8B;
  Instructions[4] := $EC;

  // push ecx
  Instructions[5] := $51;

  for i := Low(Instructions) to High(Instructions) do
    Memo1.Lines.Append(IntToHex(Instructions[i], 2));
end;
或者甚至使用记录来代替:

type
  BitBltInstructions = packed record
    MovEdiEdi: array[0..1] of byte; // $8B $FF
    PushEbp: byte; // $55
    MovEbpEsp: array[0..1] of byte; // $8B $EC
    PushEcx: byte; // $51
  end;

var
  Instructions: BitBltInstructions;
  bytes: array[0..Sizeof(BitBltInstructions)-1] of byte absolute Instructions;
  i: Integer;
begin
  Instructions.MovEdiEdi[0] := $8B;
  Instructions.MovEdiEdi[1] := $FF;
  Instructions.PushEbp      := $55;
  Instructions.MovEbpEsp[0] := $8B;
  Instructions.MovEbpEsp[1] := $EC;
  Instructions.PushEcx      := $51;

  for i := Low(bytes) to High(bytes) do
    Memo1.Lines.Append(IntToHex(bytes[i], 2));
end;

整数是4字节长的,根据计算机的长度进行调整。从哪里可以得到EC51?2337669003(dec)正好是8B FF 55 8B(十六进制)。问题是值2.337.669.003大于MaxInt(2.147.483.647),必须使用Int64。@mezen 1)2 337 669 003适合无符号32位整数。2) Int64不是6字节,所以OP的问题中仍然缺少一些内容。不要重新声明此类型。它已经在
SysUtils
中声明为
LongRec
。您提供的答案与问题中的代码行为相同,这也有点奇怪。您不能为LongRec变量指定整数值!我不重新申报那种类型。LongRec=0的压缩记录大小写整数:(Lo,Hi:Word);1:(字:字的数组[0..1];2:(字节:字节的数组[0..3];结束;我主要是向他展示了一种可能的方法,它可以用于任何固定的二进制结构。@ZesNAN你完全错了。您完全可以在lhs和rhs上将
整数
变量强制转换为
LongRec
。否则,它究竟为什么存在?在您的例子中,代码如下所示:
var X:Integer;X:=123456;Writeln(LongRec(X).Bytes[0])l
。再说一次,你为什么不说明你答案中的代码与问题中的代码的行为相同呢?@DavidHeffernan:同意。你是对的。我没有像那样使用过LongRec,因为我从来不需要像问题的作者那样做任务(我的意思是使用整数)。我只是展示了实现这一目标的简单方法之一。感谢您的评论。这与问题中的代码行为相同,只是在这段代码中没有复制内存的移动操作,并且直接访问这些值。@DavidHeffernan-Oh。。“行为”(漏掉了那个词)。是的,那是肯定的。谢谢你的解释。我想这次我得到了它。起初我以为我必须写6个字节,但我错了,我只需要写4个,告诉我一件事,所有x86指令都有固定字节,不管Windows版本如何,对吗?在这种情况下,只写4个字节是没有意义的,那样的话,您将只编写
mov ebp,esp
指令的一半。你到底想完成什么?至于x86指令集,是的,它的许多指令使用固定字节(有些指令具有可变字节)。x86与Windows没有任何关系。你知道x86是什么,不是吗?它是直接在CPU本身上运行的指令,与操作系统无关。软件在我的函数中创建WINAPI挂钩(在本例中为BitBlt),我在FormCreate中捕获原始值(另一个程序需要几秒钟才能挂钩)如果你的目标是阻止钩子被安装,那么你为什么要为你所问的方法而烦恼呢?您已经有了原始字节,只需将它们保存到变量中,然后在需要时将它们写回函数地址。或者,更好的方法是,首先使用它来防止安装钩子。我使用的是另一个函数来写入字节,我没有使用WPM,你有一些东西我可以学习使用VirtualProtect()来阻止钩子被安装吗?
type
  BitBltInstructions = packed record
    MovEdiEdi: array[0..1] of byte; // $8B $FF
    PushEbp: byte; // $55
    MovEbpEsp: array[0..1] of byte; // $8B $EC
    PushEcx: byte; // $51
  end;

var
  Instructions: BitBltInstructions;
  bytes: array[0..Sizeof(BitBltInstructions)-1] of byte absolute Instructions;
  i: Integer;
begin
  Instructions.MovEdiEdi[0] := $8B;
  Instructions.MovEdiEdi[1] := $FF;
  Instructions.PushEbp      := $55;
  Instructions.MovEbpEsp[0] := $8B;
  Instructions.MovEbpEsp[1] := $EC;
  Instructions.PushEcx      := $51;

  for i := Low(bytes) to High(bytes) do
    Memo1.Lines.Append(IntToHex(bytes[i], 2));
end;