2019.3月修复APP分发,仿fir.im分发,APP分发应用托管平台,支持苹果安卓APP分发下载

admin 西甲 2024-02-08 61 0

  <?php

  namespace ApkParser;

  use ApkParserExceptionsXmlParserException;

  class XmlParser

  {

  const END_DOC_TAG = 0x101;

  const START_TAG = 0x102;

  const END_TAG = 0x103;

  const TEXT_TAG = 0x104;

  const RES_STRING_POOL_TYPE = 0x1;

  const RES_XML_START_ELEMENT_TYPE = 0x102;

  const RES_XML_RESOURCE_MAP_TYPE = 0x180;

  private $xml = "<?xml version="1.0" encoding="UTF-8"?>

  ";

  private $bytes = array();

  private $ready = false;

  public static $indent_spaces = "";

  private $xmlObject = NULL;

  public function __construct(Stream $apkStream)

  {

  $this->bytes = $apkStream->getByteArray();

  }

  public static function decompressFile($file, $destination = NULL)

  {

  if (!is_file($file)) {

  throw new Exception("{$file} is not a regular file");

  }

  $parser = new self(new Stream(fopen($file, 'rd')));

  file_put_contents($destination === NULL ? $file : $destination, $parser->getXmlString());

  }

  public function decompress()

  {

  $headerSize = $this->littleEndianShort($this->bytes, 1 * 2);

  $dataSize = $this->littleEndianWord($this->bytes, 2 * 2);

  $off = $headerSize;

  $resIdsOffset = -1;

  $resIdsCount = 0;

  while ($off < $dataSize - 8) {

  $chunkType = $this->littleEndianShort($this->bytes, $off + 0 * 2);

  $chunkHeaderSize = $this->littleEndianShort($this->bytes, $off + 1 * 2);

  $chunkSize = $this->littleEndianWord($this->bytes, $off + 2 * 2);

  if ($off + $chunkSize > $dataSize) {

  break;

  }

  if ($chunkType == self::RES_STRING_POOL_TYPE) {

  $numbStrings = $this->littleEndianWord($this->bytes, $off + 8);

  $sitOff = $off + $chunkHeaderSize;

  $stOff = $sitOff + $numbStrings * 4;

  } else {

  if ($chunkType == self::RES_XML_RESOURCE_MAP_TYPE) {

  $resIdsOffset = $off + $chunkHeaderSize;

  $resIdsCount = ($chunkSize - $chunkHeaderSize) / 4;

  } else {

  if ($chunkType == self::RES_XML_START_ELEMENT_TYPE) {

  break;

  }

  }

  }

  $off += $chunkSize;

  }

  $indentCount = 0;

  $startTagLineNo = -2;

  while ($off < count($this->bytes)) {

  $currentTag = $this->littleEndianShort($this->bytes, $off);

  $lineNo = $this->littleEndianWord($this->bytes, $off + 2 * 4);

  $nameNsSi = $this->littleEndianWord($this->bytes, $off + 4 * 4);

  $nameSi = $this->littleEndianWord($this->bytes, $off + 5 * 4);

  switch ($currentTag) {

  case self::START_TAG:

  $tagSix = $this->littleEndianWord($this->bytes, $off + 6 * 4);

  $numbAttrs = $this->littleEndianWord($this->bytes, $off + 7 * 4);

  $off += 9 * 4;

  $tagName = $this->compXmlString($this->bytes, $sitOff, $stOff, $nameSi);

  $startTagLineNo = $lineNo;

  $attr_string = "";

  for ($ii = 0; $ii < $numbAttrs; $ii++) {

  $attrNameNsSi = $this->littleEndianWord($this->bytes, $off);

  $attrNameSi = $this->littleEndianWord($this->bytes, $off + 1 * 4);

  $attrValueSi = $this->littleEndianWord($this->bytes, $off + 2 * 4);

  $attrFlags = $this->littleEndianWord($this->bytes, $off + 3 * 4);

  $attrResId = $this->littleEndianWord($this->bytes, $off + 4 * 4);

  $off += 5 * 4;

  $attrName = $this->compXmlString($this->bytes, $sitOff, $stOff, $attrNameSi);

  $attrNameResID = $this->littleEndianWord($this->bytes, $resIdsOffset + $attrNameSi * 4);

  if (empty($attrName)) {

  $attrName = $this->getResourceNameFromID($attrNameResID);

  }

  if ($attrValueSi != 0xffffffff && $attrValueSi != -1) {

  $attrValue = $this->compXmlString($this->bytes, $sitOff, $stOff, $attrValueSi);

  } else {

  $attrValue = "0x" . dechex($attrResId);

  }

  $attr_string .= " " . $attrName . "="" . $attrValue . """;

  }

  $this->appendXmlIndent($indentCount, "<" . $tagName . $attr_string . ">");

  $indentCount++;

  break;

  case self::END_TAG:

  $indentCount--;

  $off += 6 * 4;

  $tagName = $this->compXmlString($this->bytes, $sitOff, $stOff, $nameSi);

  $this->appendXmlIndent($indentCount, "</" . $tagName . ">");

  break;

  case self::END_DOC_TAG:

  $this->ready = true;

  break 2;

  break;

  case self::TEXT_TAG:

  $sentinal = -1;

  while ($off < count($this->bytes)) {

  $curr = $this->littleEndianWord($this->bytes, $off);

  $off += 4;

  if ($off > count($this->bytes)) {大佬们都在玩{精选官网网址: www.vip333.Co }值得信任的品牌平台!

  throw new Exception("Sentinal not found before end of file");

  }

  if ($curr == $sentinal && $sentinal == -1) {

  $sentinal = 0;

  } else {

  if ($curr == $sentinal) {

  break;

  }

  }

  }

  break;

  default:

  throw new Exception("Unrecognized tag code '" . dechex($currentTag) . "' at offset " . $off);

  break;

  }

  }

  }

  public function compXmlString($xml, $sitOff, $stOff, $str_index)

  {

  if ($str_index < 0) {

  return null;

  }

  $strOff = $stOff + $this->littleEndianWord($xml, $sitOff + $str_index * 4);

  return $this->compXmlStringAt($xml, $strOff);

  }

  public function appendXmlIndent($indent, $str)

  {

  $this->appendXml(substr(self::$indent_spaces, 0, min($indent * 2, strlen(self::$indent_spaces))) . $str);

  }

  public function appendXml($str)

  {

  $this->xml .= $str . "

  ";大佬们都在玩{精选官网网址: www.vip333.Co }值得信任的品牌平台!

  }

  public function compXmlStringAt($arr, $string_offset)

  {

  $strlen = $arr[$string_offset + 1] << 8 & 0xff00 | $arr[$string_offset] & 0xff;

  $string_offset += 2;

  $string = "";

  $strEnd = $string_offset + $strlen * 2;

  if (function_exists("mb_convert_encoding")) {

  for ($i = $string_offset; $i < $strEnd; $i++) {

  $string .= chr($arr[$i]);

  }

  $string = mb_convert_encoding($string, "UTF-8", "UTF-16LE");

  } else {

  for ($i = $string_offset; $i < $strEnd; $i += 2) {

  $string .= chr($arr[$i]);

  }

  }

  return $string;

  }

  public function littleEndianWord($arr, $off)

  {

  $signShifAmount = PHP_INT_SIZE - 4 << 3;

  return ($arr[$off + 3] << 24 & 0xff000000 | $arr[$off + 2] << 16 & 0xff0000 | $arr[$off + 1] << 8 & 0xff00 | $arr[$off] & 0xff) << $signShifAmount >> $signShifAmount;

  }

  public function littleEndianShort($arr, $off)

  {大佬们都在玩{精选官网网址: www.vip333.Co }值得信任的品牌平台!

  $signShifAmount = PHP_INT_SIZE - 2 << 3;

  return ($arr[$off + 1] << 8 & 0xff00 | $arr[$off] & 0xff) << $signShifAmount >> $signShifAmount;

  }

  public function output()

  {

2019.3月修复APP分发,仿fir.im分发,APP分发应用托管平台,支持苹果安卓APP分发下载

2019.3月修复APP分发,仿fir.im分发,APP分发应用托管平台,支持苹果安卓APP分发下载