示例#1
0
function xxtea_decrypt($str, $key) {
    if ($str == "") {
        return "";
    }
    $v = str2long($str, false);
    $k = str2long($key, false);
    if (count($k) < 4) {
        for ($i = count($k); $i < 4; $i++) {
            $k[$i] = 0;
        }
    }
    $n = count($v) - 1;

    $z = $v[$n];
    $y = $v[0];
    $delta = 0x9E3779B9;
    $q = floor(6 + 52 / ($n + 1));
    $sum = int32($q * $delta);
    while ($sum != 0) {
        $e = $sum >> 2 & 3;
        for ($p = $n; $p > 0; $p--) {
            $z = $v[$p - 1];
            $mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
            $y = $v[$p] = int32($v[$p] - $mx);
        }
        $z = $v[$n];
        $mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
        $y = $v[0] = int32($v[0] - $mx);
        $sum = int32($sum - $delta);
    }
    return long2str($v, true);
}
示例#2
0
/** Decipher
* @param string binary cipher
* @param string
* @return string plain-text password
*/
function decrypt_string($str, $key)
{
    if ($str == "") {
        return "";
    }
    $key = array_values(unpack("V*", pack("H*", md5($key))));
    $v = str2long($str, false);
    $n = count($v) - 1;
    $z = $v[$n];
    $y = $v[0];
    $q = floor(6 + 52 / ($n + 1));
    $sum = int32($q * 0x9e3779b9);
    while ($sum) {
        $e = $sum >> 2 & 3;
        for ($p = $n; $p > 0; $p--) {
            $z = $v[$p - 1];
            $mx = xxtea_mx($z, $y, $sum, $key[$p & 3 ^ $e]);
            $y = int32($v[$p] - $mx);
            $v[$p] = $y;
        }
        $z = $v[$n];
        $mx = xxtea_mx($z, $y, $sum, $key[$p & 3 ^ $e]);
        $y = int32($v[0] - $mx);
        $v[0] = $y;
        $sum = int32($sum - 0x9e3779b9);
    }
    return long2str($v, true);
}
示例#3
0
 /**
  * Parse workbook
  */
 function parse_workbook($f_header, $dp)
 {
     /*DBG*/
     $this->dbglog->debug("parse_workbook() function");
     $root_entry_block = $f_header->getLong(0x30);
     $num_fat_blocks = $f_header->getLong(0x2c);
     /*TRC*/
     $this->dbglog->trace("Header parsed");
     $this->fat = array();
     $num_fat_blocks1 = $num_fat_blocks > 108 ? 109 : $num_fat_blocks;
     $pos = 0x4c;
     for ($i = 0; $i < $num_fat_blocks1; $i++) {
         /*TRC*/
         $this->dbglog->trace("FOR LOOP iteration i =" . $i . " of " . $num_fat_blocks);
         $fat_block = $f_header->getLong($pos);
         $fatbuf = $dp->get($fat_block * 0x200, 0x200);
         $fat = new DataProvider($fatbuf, DP_STRING_SOURCE);
         if ($fat->getSize() < 0x200) {
             /*DBG*/
             $this->dbglog->debug("parse_workbook() function found (strlen({$fat}) < 0x200) returns 6");
             return 6;
         }
         for ($j = 0; $j < 0x80; $j++) {
             $this->fat[] = $fat->getLong($j * 4);
         }
         $fat->close();
         unset($fat_block, $fatbuf, $fat);
         $pos += 4;
     }
     // read XBAT
     $pos = $f_header->getLong(XBAT_START) * 512;
     $blockstart = 109;
     for ($j = 0; $j < $f_header->getLong(XBAT_COUNT); $j++) {
         $nblocks = min($f_header->getLong(BAT_COUNT) - $blockstart, 127);
         for ($i = $blockstart; $i < $nblocks + $blockstart; $i++) {
             /*TRC*/
             $this->dbglog->trace("FOR LOOP iteration (XBAT) i =" . $i . " of " . $num_fat_blocks);
             $fat_block = $dp->getLong($pos);
             $fatbuf = $dp->get($fat_block * 0x200, 0x200);
             $fat = new DataProvider($fatbuf, DP_STRING_SOURCE);
             if ($fat->getSize() < 0x200) {
                 /*DBG*/
                 $this->dbglog->debug("parse_workbook() function found (strlen({$fat}) < 0x200) returns 6");
                 return 6;
             }
             for ($j = 0; $j < 0x80; $j++) {
                 $this->fat[] = $fat->getLong($j * 4);
             }
             $fat->close();
             unset($fat_block, $fatbuf, $fat);
             $pos += 4;
         }
         $blockstart += $nblocks;
         if ($blockstart < $f_header->getLong(BAT_COUNT)) {
             //         $pos = getlong($pos);
         }
     }
     /*DBG*/
     $this->dbglog->dump($this->fat, "\$fat");
     if (count($this->fat) < $num_fat_blocks) {
         /*DBG*/
         $this->dbglog->debug("parse_workbook() function found (count({$this->fat}) < {$num_fat_blocks}) returns 6");
         return 6;
     }
     $chain = $this->get_blocks_chain($root_entry_block);
     $dir = new DataProvider($dp->ReadFromFat($chain), DP_STRING_SOURCE);
     unset($chain);
     $this->sfat = array();
     $small_block = $f_header->getLong(0x3c);
     if ($small_block != 0xfeffffff) {
         $root_entry_index = $this->find_stream($dir, 'Root Entry');
         // Deleted for support MAC files
         //if( $root_entry_index < 0 ) {
         /*DBG*/
         //$this->dbglog->debug("parse_workbook() function dont found Root Entry returns 6");
         //return 6;
         //}
         $sdc_start_block = $dir->getLong($root_entry_index * 0x80 + 0x74);
         $small_data_chain = $this->get_blocks_chain($sdc_start_block);
         $this->max_sblocks = count($small_data_chain) * 8;
         $schain = $this->get_blocks_chain($small_block);
         for ($i = 0; $i < count($schain); $i++) {
             $sfatbuf = $dp->get($schain[$i] * 0x200, 0x200);
             $sfat = new DataProvider($sfatbuf, DP_STRING_SOURCE);
             //$this->dbglog->dump( strlen($sfatbuf), "strlen(\$sftabuf)");
             //$this->dbglog->dump( $sfat, "\$sfat");
             if ($sfat->getSize() < 0x200) {
                 /*DBG*/
                 $this->dbglog->debug("parse_workbook() function found (strlen({$sfat}) < 0x200)  returns 6");
                 return 6;
             }
             for ($j = 0; $j < 0x80; $j++) {
                 $this->sfat[] = $sfat->getLong($j * 4);
             }
             $sfat->close();
             unset($sfatbuf, $sfat);
         }
         unset($schain);
         $sfcbuf = $dp->ReadFromFat($small_data_chain);
         $sdp = new DataProvider($sfcbuf, DP_STRING_SOURCE);
         unset($sfcbuf, $small_data_chain);
     }
     $workbook_index = $this->find_stream($dir, 'Workbook');
     if ($workbook_index < 0) {
         $workbook_index = $this->find_stream($dir, 'Book');
         if ($workbook_index < 0) {
             /*DBG*/
             $this->dbglog->debug("parse_workbook() function workbook index not found returns 7");
             return 7;
         }
     }
     $workbook_start_block = $dir->getLong($workbook_index * 0x80 + 0x74);
     $workbook_length = $dir->getLong($workbook_index * 0x80 + 0x78);
     $wb = '';
     if ($workbook_length > 0) {
         if ($workbook_length >= 0x1000) {
             $chain = $this->get_blocks_chain($workbook_start_block);
             $wb = $dp->ReadFromFat($chain);
         } else {
             $chain = $this->get_blocks_chain($workbook_start_block, true);
             $wb = $sdp->ReadFromFat($chain, 0x40);
             unset($sdp);
         }
         $wb = substr($wb, 0, $workbook_length);
         if (strlen($wb) != $workbook_length) {
             return 6;
         }
         unset($chain);
     }
     // Unset fat arrays
     unset($this->fat, $this->sfat);
     if (strlen($wb) <= 0) {
         /*DBG*/
         $this->dbglog->debug("parse_workbook() function workbook found (strlen({$wb}) <= 0) returns 7");
         return 7;
     }
     if (strlen($wb) < 4) {
         /*DBG*/
         $this->dbglog->debug("parse_workbook() function workbook found (strlen({$wb}) < 4) returns 6");
         return 6;
     }
     // parse workbook header
     if (strlen($wb) < 256 * ord($wb[3]) + ord($wb[2])) {
         /*DBG*/
         $this->dbglog->debug("parse_workbook() function workbook found (strlen({$wb}) < 256*ord({$wb['3']})+ord({$wb['2']})) < 4) returns 6");
         return 6;
     }
     if (ord($wb[0]) != 0x9) {
         /*DBG*/
         $this->dbglog->debug("parse_workbook() function workbook found (ord({$wb['0']}) != 0x09) returns 6");
         return 6;
     }
     $vers = ord($wb[1]);
     if ($vers != 0 && $vers != 2 && $vers != 4 && $vers != 8) {
         return 8;
     }
     if ($vers != 8) {
         $biff_ver = ($ver + 4) / 2;
     } else {
         if (strlen($wb) < 12) {
             return 6;
         }
         switch (ord($wb[4]) + 256 * ord($wb[5])) {
             case 0x500:
                 if (ord($wb[0xa]) + 256 * ord($wb[0xb]) < 1994) {
                     $biff_ver = 5;
                 } else {
                     switch (ord($wb[8]) + 256 * ord($wb[9])) {
                         case 2412:
                         case 3218:
                         case 3321:
                             $biff_ver = 5;
                             break;
                         default:
                             $biff_ver = 7;
                             break;
                     }
                 }
                 break;
             case 0x600:
                 $biff_ver = 8;
                 break;
             default:
                 return 8;
         }
     }
     if ($biff_ver < 5) {
         return 8;
     }
     $ptr = 0;
     $this->worksheet['offset'] = array();
     $this->worksheet['options'] = array();
     $this->worksheet['unicode'] = array();
     $this->worksheet['name'] = array();
     $this->worksheet['data'] = array();
     $this->format = $this->populateFormat();
     $this->fonts = array();
     $this->fonts[0] = ExcelFont::basicFontRecord();
     $this->xf = array();
     $this->xf['format'] = array();
     $this->xf['font'] = array();
     $this->xf['type_prot'] = array();
     $this->xf['alignment'] = array();
     $this->xf['decoration'] = array();
     $xf_cnt = 0;
     $this->sst['unicode'] = array();
     $this->sst['data'] = array();
     $opcode = 0;
     $sst_defined = false;
     $wblen = strlen($wb);
     while (ord($wb[$ptr]) != 0xa && $ptr < $wblen) {
         $oc = ord($wb[$ptr]) + 256 * ord($wb[$ptr + 1]);
         if ($oc != 0x3c) {
             $opcode = $oc;
         }
         switch ($opcode) {
             case 0x85:
                 $ofs = str2long(substr($wb, $ptr + 4, 4));
                 $this->worksheet['offset'][] = $ofs;
                 $this->worksheet['options'][] = ord($wb[$ptr + 8]) + 256 * ord($wb[$ptr + 9]);
                 if ($biff_ver == 8) {
                     $len = ord($wb[$ptr + 10]);
                     if ((ord($wb[$ptr + 11]) & 1) > 0) {
                         $this->worksheet['unicode'][] = true;
                         $len = $len * 2;
                     } else {
                         $this->worksheet['unicode'][] = false;
                     }
                     $this->worksheet['name'][] = substr($wb, $ptr + 12, $len);
                 } else {
                     $this->worksheet['unicode'][] = false;
                     $len = ord($wb[$ptr + 10]);
                     $this->worksheet['name'][] = substr($wb, $ptr + 11, $len);
                 }
                 $pws = $this->parse_worksheet(substr($wb, $ofs));
                 if (is_array($pws)) {
                     $this->worksheet['data'][] = $pws;
                 } else {
                     return $pws;
                 }
                 break;
                 // Format
             // Format
             case 0x41e:
                 $fidx = ord($wb[$ptr + 4]) + 256 * ord($wb[$ptr + 5]);
                 if ($fidx < 0x31 || $fidx == 0x31) {
                     break;
                 } elseif ($biff_ver > 7) {
                     $this->format[$fidx] = $this->getUnicodeString($wb, $ptr + 6);
                 }
                 //			  	  	echo $wb."---".$this->format[$fidx]."*****<br>";
                 // FONT 0x31
             //			  	  	echo $wb."---".$this->format[$fidx]."*****<br>";
             // FONT 0x31
             case EXCEL_FONT_RID:
                 $rec = ExcelFont::getFontRecord($wb, $ptr + 4);
                 $this->fonts[count($this->fonts)] = $rec;
                 /*echo str_replace("\n","<br>\n",ExcelFont::toString($rec,count($this->fonts)-1));
                 echo "FontRecord<br>" */
                 break;
                 // XF
             // XF
             case 0xe0:
                 $this->xf['font'][$xf_cnt] = ord($wb[$ptr + 4]) + 256 * ord($wb[$ptr + 5]);
                 $this->xf['format'][$xf_cnt] = ord($wb[$ptr + 6]) + 256 * ord($wb[$ptr + 7]);
                 $this->xf['type'][$xf_cnt] = "1";
                 $this->xf['bitmask'][$xf_cnt] = "1";
                 $xf_cnt++;
                 break;
                 // SST
             // SST
             case 0xfc:
                 if ($biff_ver < 8) {
                     break;
                 }
                 $sbuflen = ord($wb[$ptr + 2]) + 256 * ord($wb[$ptr + 3]);
                 if ($oc != 0x3c) {
                     if ($sst_defined) {
                         return 6;
                     }
                     $snum = str2long(substr($wb, $ptr + 8, 4));
                     $sptr = $ptr + 12;
                     $sst_defined = true;
                 } else {
                     if ($rslen > $slen) {
                         $sptr = $ptr + 4;
                         $rslen -= $slen;
                         $slen = $rslen;
                         if ((ord($wb[$sptr]) & 1) > 0) {
                             if ($char_bytes == 1) {
                                 $sstr = '';
                                 for ($i = 0; $i < strlen($str); $i++) {
                                     $sstr .= $str[$i] . chr(0);
                                 }
                                 $str = $sstr;
                                 $char_bytes = 2;
                             }
                             $schar_bytes = 2;
                         } else {
                             $schar_bytes = 1;
                         }
                         if ($sptr + $slen * $schar_bytes > $ptr + 4 + $sbuflen) {
                             $slen = ($ptr + $sbuflen - $sptr + 3) / $schar_bytes;
                         }
                         $sstr = substr($wb, $sptr + 1, $slen * $schar_bytes);
                         if ($char_bytes == 2 && $schar_bytes == 1) {
                             $sstr2 = '';
                             for ($i = 0; $i < strlen($sstr); $i++) {
                                 $sstr2 .= $sstr[$i] . chr(0);
                             }
                             $sstr = $sstr2;
                         }
                         $str .= $sstr;
                         $sptr += $slen * $schar_bytes + 1 + 4 * $rt + $fesz;
                         if ($slen < $rslen) {
                             if ($sptr >= strlen($wb) || $sptr < $ptr + 4 + $sbuflen || ord($wb[$sptr]) != 0x3c) {
                                 return 6;
                             }
                             break;
                         } else {
                             if ($char_bytes == 2) {
                                 $this->sst['unicode'][] = true;
                             } else {
                                 $this->sst['unicode'][] = false;
                             }
                             $this->sst['data'][] = $str;
                             $snum--;
                         }
                     } else {
                         $sptr = $ptr + 4;
                         if ($sptr > $ptr) {
                             $sptr += 4 * $rt + $fesz;
                         }
                     }
                 }
                 while ($sptr < $ptr + 4 + $sbuflen && $sptr < strlen($wb) && $snum > 0) {
                     $rslen = ord($wb[$sptr]) + 256 * ord($wb[$sptr + 1]);
                     $slen = $rslen;
                     if ((ord($wb[$sptr + 2]) & 1) > 0) {
                         $char_bytes = 2;
                     } else {
                         $char_bytes = 1;
                     }
                     $rt = 0;
                     $fesz = 0;
                     switch (ord($wb[$sptr + 2]) & 0xc) {
                         // Rich-Text with Far-East
                         case 0xc:
                             $rt = ord($wb[$sptr + 3]) + 256 * ord($wb[$sptr + 4]);
                             $fesz = str2long(substr($wb, $sptr + 5, 4));
                             if ($sptr + 9 + $slen * $char_bytes > $ptr + 4 + $sbuflen) {
                                 $slen = ($ptr + $sbuflen - $sptr - 5) / $char_bytes;
                             }
                             $str = substr($wb, $sptr + 9, $slen * $char_bytes);
                             $sptr += $slen * $char_bytes + 9;
                             break;
                             // Rich-Text
                         // Rich-Text
                         case 8:
                             $rt = ord($wb[$sptr + 3]) + 256 * ord($wb[$sptr + 4]);
                             if ($sptr + 5 + $slen * $char_bytes > $ptr + 4 + $sbuflen) {
                                 $slen = ($ptr + $sbuflen - $sptr - 1) / $char_bytes;
                             }
                             $str = substr($wb, $sptr + 5, $slen * $char_bytes);
                             $sptr += $slen * $char_bytes + 5;
                             break;
                             // Far-East
                         // Far-East
                         case 4:
                             $fesz = str2long(substr($wb, $sptr + 3, 4));
                             if ($sptr + 7 + $slen * $char_bytes > $ptr + 4 + $sbuflen) {
                                 $slen = ($ptr + $sbuflen - $sptr - 3) / $char_bytes;
                             }
                             $str = substr($wb, $sptr + 7, $slen * $char_bytes);
                             $sptr += $slen * $char_bytes + 7;
                             break;
                             // Compressed or uncompressed unicode
                         // Compressed or uncompressed unicode
                         case 0:
                             if ($sptr + 3 + $slen * $char_bytes > $ptr + 4 + $sbuflen) {
                                 $slen = ($ptr + $sbuflen - $sptr + 1) / $char_bytes;
                             }
                             $str = substr($wb, $sptr + 3, $slen * $char_bytes);
                             $sptr += $slen * $char_bytes + 3;
                             break;
                     }
                     if ($slen < $rslen) {
                         if ($sptr >= strlen($wb) || $sptr < $ptr + 4 + $sbuflen || ord($wb[$sptr]) != 0x3c) {
                             return 6;
                         }
                     } else {
                         if ($char_bytes == 2) {
                             $this->sst['unicode'][] = true;
                         } else {
                             $this->sst['unicode'][] = false;
                         }
                         $sptr += 4 * $rt + $fesz;
                         $this->sst['data'][] = $str;
                         $snum--;
                     }
                 }
                 // switch
                 break;
         }
         // switch
         // !!! Optimization:
         //  $this->wsb[] = substr($wb,$ptr,4+256*ord($wb[$ptr+3])+ord($wb[$ptr+2]));
         $ptr += 4 + 256 * ord($wb[$ptr + 3]) + ord($wb[$ptr + 2]);
     }
     // while
     // !!! Optimization:
     //  $this->workbook = $wb;
     $this->biff_version = $biff_ver;
     /*DBG*/
     $this->dbglog->debug("parse_workbook() function returns 0");
     return 0;
 }
示例#4
0
function TEAdecrypt($str, $key = EW_RANDOM_KEY)
{
    $str = ew_UrlDecode($str);
    if ($str == "") {
        return "";
    }
    $v = str2long($str, false);
    $k = str2long($key, false);
    $cntk = count($k);
    if ($cntk < 4) {
        for ($i = $cntk; $i < 4; $i++) {
            $k[$i] = 0;
        }
    }
    $n = count($v) - 1;
    $z = $v[$n];
    $y = $v[0];
    $delta = 0.0;
    $q = floor(6 + 52 / ($n + 1));
    $sum = int32($q * $delta);
    while ($sum != 0) {
        $e = $sum >> 2 & 3;
        for ($p = $n; $p > 0; $p--) {
            $z = $v[$p - 1];
            $mx = int32(($z >> 5 & 0x7ffffff ^ $y << 2) + ($y >> 3 & 0x1fffffff ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
            $y = $v[$p] = int32($v[$p] - $mx);
        }
        $z = $v[$n];
        $mx = int32(($z >> 5 & 0x7ffffff ^ $y << 2) + ($y >> 3 & 0x1fffffff ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
        $y = $v[0] = int32($v[0] - $mx);
        $sum = int32($sum - $delta);
    }
    return long2str($v, true);
}