此类中实现了从crx文件获取扩展的appid、获取manifest.json文件内容、将crx文件转换为一般zip文件
代码如下:
<?<span style="color: #000000;">php
</span><span style="color: #0000ff;">class</span> CrxParserException <span style="color: #0000ff;">extends</span> <span style="color: #0000ff;">Exception</span><span style="color: #000000;"> {
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* Chrome crx 解析器,用于获取扩展、皮肤ID
*
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">class</span><span style="color: #000000;"> CrxParser {
</span><span style="color: #0000ff;">const</span> MAX_PUBLIC_KEY_SIZE = 65535<span style="color: #000000;">;
</span><span style="color: #0000ff;">const</span> MAX_SIGNATURE_SIZE = 65535<span style="color: #000000;">;
</span><span style="color: #0000ff;">const</span> HEADER_MAGIC_PREFIX = 'Cr24'<span style="color: #000000;">;
</span><span style="color: #0000ff;">const</span> CURRENT_VERSION = 2<span style="color: #000000;">;
</span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$fp</span> = <span style="color: #0000ff;">null</span>; <span style="color: #008000;">//</span><span style="color: #008000;">文件指针</span>
<span style="color: #0000ff;">private</span> <span style="color: #800080;">$filename</span> = ''; <span style="color: #008000;">//</span><span style="color: #008000;">文件路径</span>
<span style="color: #0000ff;">private</span> <span style="color: #800080;">$_header</span> = <span style="color: #0000ff;">array</span>(); <span style="color: #008000;">//</span><span style="color: #008000;">crx 文件的头信息</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$filename</span><span style="color: #000000;">){
</span><span style="color: #800080;">$this</span>->parse(<span style="color: #800080;">$filename</span><span style="color: #000000;">);
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 获取此应用的ID
* @return string
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getAppid() {
</span><span style="color: #800080;">$hash</span> = hash('sha256',<span style="color: #800080;">$this</span>-><span style="color: #000000;">_key);
</span><span style="color: #800080;">$hash</span> = <span style="color: #008080;">substr</span>(<span style="color: #800080;">$hash</span>,0,32<span style="color: #000000;">);
</span><span style="color: #800080;">$length</span> = <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$hash</span><span style="color: #000000;">);
</span><span style="color: #800080;">$ascii_0</span> = <span style="color: #008080;">ord</span>('0'<span style="color: #000000;">);
</span><span style="color: #800080;">$ascii_9</span> = <span style="color: #008080;">ord</span>('9'<span style="color: #000000;">);
</span><span style="color: #800080;">$ascii_a</span> = <span style="color: #008080;">ord</span>('a'<span style="color: #000000;">);
</span><span style="color: #800080;">$data</span> = ''<span style="color: #000000;">;
</span><span style="color: #0000ff;">for</span>(<span style="color: #800080;">$i</span>=0;<span style="color: #800080;">$i</span><<span style="color: #800080;">$length</span>;<span style="color: #800080;">$i</span>++<span style="color: #000000;">) {
</span><span style="color: #800080;">$c</span> = <span style="color: #008080;">ord</span>(<span style="color: #800080;">$hash</span>[<span style="color: #800080;">$i</span><span style="color: #000000;">]);
</span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$c</span> >= <span style="color: #800080;">$ascii_0</span> && <span style="color: #800080;">$c</span> <= <span style="color: #800080;">$ascii_9</span><span style="color: #000000;">) {
</span><span style="color: #800080;">$d</span> = <span style="color: #008080;">chr</span>(<span style="color: #800080;">$ascii_a</span> + <span style="color: #800080;">$c</span> - <span style="color: #800080;">$ascii_0</span><span style="color: #000000;">);
} </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(<span style="color: #800080;">$c</span> >= <span style="color: #800080;">$ascii_a</span> && <span style="color: #800080;">$c</span> < <span style="color: #800080;">$ascii_a</span> + 6<span style="color: #000000;">) {
</span><span style="color: #800080;">$d</span> = <span style="color: #008080;">chr</span>(<span style="color: #800080;">$ascii_a</span> + <span style="color: #800080;">$c</span> - <span style="color: #800080;">$ascii_a</span> + 10<span style="color: #000000;">);
} </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
</span><span style="color: #800080;">$d</span> = 'a'<span style="color: #000000;">;
}
</span><span style="color: #800080;">$data</span> .= <span style="color: #800080;">$d</span><span style="color: #000000;">;
}
</span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$data</span><span style="color: #000000;">;
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 从crx文件中获取manifest.json文件的配置信息
* @param unknown $zip_file
* @return mixed[]
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">function</span> getConfig(<span style="color: #800080;">$key</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
</span><span style="color: #800080;">$zip_file</span>=<span style="color: #008080;">tempnam</span>(<span style="color: #008080;">dirname</span>(<span style="color: #800080;">$this</span>->filename),'zip'<span style="color: #000000;">);
</span><span style="color: #800080;">$manifest_arr</span>=<span style="color: #0000ff;">array</span><span style="color: #000000;">();
</span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->convertToZip(<span style="color: #800080;">$zip_file</span><span style="color: #000000;">)){
</span><span style="color: #800080;">$zip</span>=zip_open(<span style="color: #800080;">$zip_file</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">is_resource</span>(<span style="color: #800080;">$zip</span><span style="color: #000000;">)){
</span><span style="color: #0000ff;">while</span>(<span style="color: #800080;">$zip_entry</span>=zip_read(<span style="color: #800080;">$zip</span><span style="color: #000000;">)){
</span><span style="color: #800080;">$entry_name</span>=zip_entry_name(<span style="color: #800080;">$zip_entry</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">preg_match</span>('/manifest\.json$/', <span style="color: #800080;">$entry_name</span><span style="color: #000000;">)){
</span><span style="color: #800080;">$content</span>=zip_entry_read(<span style="color: #800080;">$zip_entry</span>, zip_entry_filesize(<span style="color: #800080;">$zip_entry</span><span style="color: #000000;">));
</span><span style="color: #800080;">$content_j</span>=json_decode(<span style="color: #800080;">$content</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$content_j</span><span style="color: #000000;">)){
</span><span style="color: #800080;">$manifest_arr</span>=<span style="color: #800080;">$content_j</span><span style="color: #000000;">;
}
}
}
}
zip_close(</span><span style="color: #800080;">$zip</span><span style="color: #000000;">);
</span><span style="color: #008080;">unlink</span>(<span style="color: #800080;">$zip_file</span><span style="color: #000000;">);
}
</span><span style="color: #0000ff;">return</span> <span style="color: #008080;">is_null</span>(<span style="color: #800080;">$key</span>) ? <span style="color: #800080;">$manifest_arr</span> : <span style="color: #800080;">$manifest_arr</span>[<span style="color: #800080;">$key</span><span style="color: #000000;">];
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 将文件转换为zip文件
* @param unknown $target_path
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> convertToZip(<span style="color: #800080;">$target_path</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
</span><span style="color: #800080;">$offset</span>=16+<span style="color: #800080;">$this</span>->_header['key_size']+<span style="color: #800080;">$this</span>->_header['sig_size'<span style="color: #000000;">];
</span><span style="color: #800080;">$data</span>=<span style="color: #800080;">$this</span>->getContent(<span style="color: #800080;">$this</span>->filename,<span style="color: #800080;">$offset</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">return</span> !<span style="color: #008080;">is_null</span>(<span style="color: #800080;">$target_path</span>) ? <span style="color: #008080;">file_put_contents</span>(<span style="color: #800080;">$target_path</span>, <span style="color: #800080;">$data</span>) : <span style="color: #800080;">$data</span><span style="color: #000000;">;
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 开始解析该 crx 文件
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> parse(<span style="color: #800080;">$filename</span><span style="color: #000000;">) {
</span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">strpos</span>(<span style="color: #800080;">$filename</span>, '://')!==<span style="color: #0000ff;">false</span> && !<span style="color: #008080;">file_exists</span>(<span style="color: #800080;">$filename</span><span style="color: #000000;">)) {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("parser init: crx file does not exisit"<span style="color: #000000;">);
}
</span><span style="color: #800080;">$this</span>->filename=<span style="color: #800080;">$filename</span><span style="color: #000000;">;
</span><span style="color: #800080;">$this</span>->fp = <span style="color: #008080;">fopen</span>(<span style="color: #800080;">$filename</span>, 'r'<span style="color: #000000;">);
</span><span style="color: #800080;">$this</span>->parse_header(); <span style="color: #008000;">//</span><span style="color: #008000;"> 解析头部信息</span>
<span style="color: #800080;">$this</span>-><span style="color: #000000;">parse_key();
</span><span style="color: #800080;">$this</span>-><span style="color: #000000;">parse_sig();
</span><span style="color: #008080;">fclose</span>(<span style="color: #800080;">$this</span>-><span style="color: #000000;">fp);
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 解析头部信息,并设置 $_header 数组
* @throws CrxParserException 解析错误抛出异常
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> parse_header() {
</span><span style="color: #800080;">$data</span> = <span style="color: #008080;">fread</span>(<span style="color: #800080;">$this</span>->fp, 16); <span style="color: #008000;">//</span><span style="color: #008000;"> HEADER 头信息有16个字节</span>
<span style="color: #0000ff;">if</span>(<span style="color: #800080;">$data</span><span style="color: #000000;">) {
</span><span style="color: #800080;">$data</span> = @<span style="color: #008080;">unpack</span>('C4prefix/Vversion/Vkey_size/Vsig_size',<span style="color: #800080;">$data</span><span style="color: #000000;">);
}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("header parse: error reading header"<span style="color: #000000;">);
}
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 前四个字节拼合 prefix</span>
<span style="color: #800080;">$data</span>['prefix'] = <span style="color: #008080;">chr</span>( <span style="color: #800080;">$data</span>['prefix1'] ).<span style="color: #008080;">chr</span>( <span style="color: #800080;">$data</span>['prefix2'] ).<span style="color: #008080;">chr</span>( <span style="color: #800080;">$data</span>['prefix3'] ).<span style="color: #008080;">chr</span>( <span style="color: #800080;">$data</span>['prefix4'<span style="color: #000000;">] );
</span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$data</span>['prefix1'],<span style="color: #800080;">$data</span>['prefix2'],<span style="color: #800080;">$data</span>['prefix3'],<span style="color: #800080;">$data</span>['prefix4'<span style="color: #000000;">]);
</span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$data</span>['prefix'] != self::<span style="color: #000000;">HEADER_MAGIC_PREFIX) {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("header parse: illegal prefix"<span style="color: #000000;">);
}
</span><span style="color: #0000ff;">if</span>( <span style="color: #800080;">$data</span>['version'] != self::<span style="color: #000000;">CURRENT_VERSION ) {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("header parse: illegal version"<span style="color: #000000;">);
}
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(
</span><span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$data</span>['key_size']) || <span style="color: #800080;">$data</span>['key_size'] > self::MAX_PUBLIC_KEY_SIZE ||
<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$data</span>['sig_size']) || <span style="color: #800080;">$data</span>['sig_size'] > self::<span style="color: #000000;">MAX_SIGNATURE_SIZE
){
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("header parse: illegal public key size or signature size"<span style="color: #000000;">);
}
</span><span style="color: #800080;">$this</span>->_header = <span style="color: #800080;">$data</span><span style="color: #000000;">;
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 解析key
* @throws CrxParserException
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> parse_key() {
</span><span style="color: #800080;">$key</span> = <span style="color: #008080;">fread</span>(<span style="color: #800080;">$this</span>->fp,<span style="color: #800080;">$this</span>->_header['key_size'<span style="color: #000000;">]);
</span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$key</span><span style="color: #000000;">) {
</span><span style="color: #800080;">$this</span>->_key = <span style="color: #800080;">$key</span><span style="color: #000000;">;
}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("key parse: error reading key"<span style="color: #000000;">);
}
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 解析sig
* @throws CrxParserException
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> parse_sig() {
</span><span style="color: #800080;">$sig</span> = <span style="color: #008080;">fread</span>(<span style="color: #800080;">$this</span>->fp,<span style="color: #800080;">$this</span>->_header['sig_size'<span style="color: #000000;">]);
</span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$sig</span><span style="color: #000000;">) {
</span><span style="color: #800080;">$this</span>->_sig = <span style="color: #800080;">$sig</span><span style="color: #000000;">;
}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CrxParserException("sig parse: error reading sig"<span style="color: #000000;">);
}
}
</span><span style="color: #008000;">/*</span><span style="color: #008000;">*
* 从文件中获取指定位置及大小的内容
* @param unknown $filename
* @param number $offset
* @param unknown $length
* @return string
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getContent(<span style="color: #800080;">$filename</span>,<span style="color: #800080;">$offset</span>=0,<span style="color: #800080;">$length</span>=-1<span style="color: #000000;">){
</span><span style="color: #800080;">$stream</span> = <span style="color: #008080;">fopen</span>(<span style="color: #800080;">$filename</span>, 'rb'<span style="color: #000000;">);
</span><span style="color: #800080;">$content</span> = <span style="color: #008080;">stream_get_contents</span>(<span style="color: #800080;">$stream</span>, <span style="color: #800080;">$length</span>, <span style="color: #800080;">$offset</span><span style="color: #000000;">);
</span><span style="color: #008080;">fclose</span>(<span style="color: #800080;">$stream</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$content</span><span style="color: #000000;">;
}
}</span>
立即学习“PHP免费学习笔记(深入)”;
使用方法:
<?<span style="color: #000000;">php
</span><span style="color: #800080;">$crxParser</span>=<span style="color: #0000ff;">new</span> CrxParser('abc.crx'<span style="color: #000000;">);
</span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$crxParser</span>-><span style="color: #000000;">getAppid();
</span><span style="color: #008080;">var_dump</span>(<span style="color: #800080;">$crxParser</span>-><span style="color: #000000;">getConfig());
</span><span style="color: #008000;">//</span><span style="color: #008000;">$crxParser->convertToZip('abc.zip');</span>
立即学习“PHP免费学习笔记(深入)”;
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号