Arrays 将整数转换为字节数组
我试图将10位整数值转换为字节,但函数只返回4个值,我需要6个点,如何求解 我用来转换整数字节的函数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],
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
实际上对应于Win32BitBlt()函数的前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;