首页 > 其他分享 >uleb128编码的解析

uleb128编码的解析

时间:2022-08-19 20:44:22浏览次数:57  
标签:Count 编码 字节 0x7f 80 解析 uleb128 Size

uleb128编码,是一种可变长度的编码,长度大小为1-5字节。
uleb128通过字节的最高位来决定是否用到下一个字节。
如果最高位为1,则用到下一个字节,直到某个字节最高位为0或已经读取了5个字节为止。
接下来通过一个实例来理解uleb128编码。

假设有以下经过uleb128编码的数据(都为16进制)--81 80 04
首先来看第一个字节81,他的二进制为10000001,他的最高位为1,则说明还要用到下一个字节,它存放的数据则为0000001;
再来看第二个字节80,它的二进制为10000000,它的最高位为1,则说明还需要用到第三个字节,存放的数据为0000000;
再来看第三个字节04,它的二进制为00000100,最高位为0,说明一共使用了三个字节,它存放的数据为0000100;
通过上面的数据我们已经获取了存放的数据,接下来就是把这些bit组合起来获取解码后的数据。
dex文件里面的数据都是采用的小端序的方式,uleb128也不例外,在这三个字节,也不例外,
第三个字节04存放的数据0000100作为解码后的数据的高7位,
第二个字节80存放的数据0000000作为解码后的数据的中7位,
第一个字节81存放的数据0000001作为解码后的数据的低7位;
那么解码后的数据二进制则为0000100 0000000 0000001,转换为16进制则为0x10001。其他使用5个字节、4个字节照此类推即可。

在举个简单例子:
uleb128p1类型很简单,值为uleb128的值加1。
C0 83 92 25计算uleb128值:
第1个字节0xc0大于0x7f,表示需要用到第2个字节。result1 = 0xC0 & 0x7F <<0
第2个字节0x83大于0x7f,表示需要用到第3个字节。result2 = result1 + (0x83 & 0x7f) << 7
第3个字节0x92大于0x7f,表示需要用到第4个字节。result3 = result2 + (0x92 & 0x7f) << 14
第4个字节0x25小于0x7f,表示到了结尾。result4 = result3 + (0x25 & 0x7f) << 21
最后计算结果为0x40 + 0x180 + 0x48000 + 0x4a00000 = 0x4a481c0

Delphi 下的简单计算代码

const
  uleb128ByteArray: array[0..2] of Byte=($81, $80, $04);
var
  uleb128ByteArray2: array[0..4] of Byte=($00, $00, $00, $00, $00);

function Uleb128ToInt(pb: PByteArray): Integer;
var
  i: integer;
  ByteSize: integer;
begin
  Result:=0;
  for i:= 0 to 4 do
  begin
    Result := Result or ( (pb[i] and $7F) shl (i * 7) );
    ByteSize:=i+1;
    if (pb[i] and $80)=0 then break;
  end;
  //Result:= ByteSize;
end;

function IntToUleb128(Size: integer): integer;
var
  Count: integer;
begin
  Count:=0;
  while Size<>0 do
  begin
    if Size>$7F then
      uleb128ByteArray2[Count] := $80 or (Size and $FF)
    else
      uleb128ByteArray2[Count] := Size and $FF;

    Inc(Count);
    Size := Size shr 7;
  end;
  Result:= Count;
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  Caption:= IntToStr(Uleb128ToInt(@uleb128ByteArray));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  PacketData: TPacketData;
begin
  PacketData.Size:= IntToUleb128(65537);
  CopyMemory(@PacketData.data, @uleb128ByteArray2, PacketData.Size);
  Caption:= PacketDataToStr(PacketData);
end;

标签:Count,编码,字节,0x7f,80,解析,uleb128,Size
From: https://www.cnblogs.com/YXGust/p/16603267.html

相关文章