<?<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: #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 style=
"color: #0000ff;"
>
private
</span> <span style=
"color: #800080;"
>
$filename
</span> =
''
; <span style=
"color: #008000;"
>
<span style=
"color: #0000ff;"
>
private
</span> <span style=
"color: #800080;"
>
$_header
</span> = <span style=
"color: #0000ff;"
>
array
</span>(); <span style=
"color: #008000;"
>
<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: #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: #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: #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: #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 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: #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 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 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: #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: #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: #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>