file = $file; } public function isValid(): bool { // Get first 4 bytes $fh = fopen($this->file, 'r'); if ($fh === false) { throw new \RuntimeException("Failed to open file '{$this->file}'"); } $header = fread($fh, 4); if ($header === false) { throw new \RuntimeException("Failed to read file '{$this->file}'"); } fclose($fh); // Check if uploaded file is a valid ZIP file if ($header !== "PK\x03\x04") { return false; } $zip = new \ZipArchive(); $zip->open($this->file); $valid = $zip->statName("AndroidManifest.xml") !== false && $zip->statName("resources.arsc"); $zip->close(); return $valid; } public function getManifest(): SimpleXMLElement { if ($this->manifest === null) { $xml = $this->cmd('androguard', 'axml', '-o', '/dev/stdout', $this->file); $simpleXml = simplexml_load_string($xml); if ($simpleXml === false) { throw new \RuntimeException("Failed to parse AndroidManifest.xml from '{$this->file}'"); } $this->manifest = $simpleXml; } return $this->manifest; } private function getAttribute(string $name, ?string $namespace = null): string { if ($namespace !== null) { return (string)$this->getManifest()->attributes($namespace, true)[$name]; } return (string)$this->getManifest()[$name]; } public function getPackageName(): string { return $this->getAttribute('package'); } public function getVersionCode(): int { return intval($this->getAttribute('versionCode', 'android'), 10); } public function getVersionName(): string { return $this->getAttribute('versionName', 'android'); } public function getLabel(): string { $code = (string)$this->getManifest()->application->attributes('android', true)['label']; $output = $this->cmd('androguard', 'arsc', '--id', $code, $this->file); preg_match(':\ = \'(.*)\'$:m', $output, $matches); return stripslashes($matches[1]); } private function cmd(string $cmd, string... $args): string { $fullCommand = $cmd . ' ' . implode(' ', array_map('escapeshellarg', $args)); $proc = popen($fullCommand, 'r'); if ($proc === false) { throw new \RuntimeException("Failed running: $fullCommand"); } $data = ''; while ($text = fread($proc, 1024)) { $data .= $text; } pclose($proc); return $data; } }