404 lines
13 KiB
PHP
404 lines
13 KiB
PHP
<?php
|
|
|
|
/* CREATE BY HoldFast
|
|
//Андрей Рейгант
|
|
//MBTEAM.RU
|
|
|
|
Коды ответов:
|
|
-1: неверный BAS-файЛ
|
|
-2: файл нельзя декмопилировать, поскольку он обфусцирован
|
|
0: файл успешно обфусцирован
|
|
*/
|
|
|
|
class BAS {
|
|
|
|
public $file;
|
|
public $data;
|
|
|
|
/* EXAMPLE, $bas->new BAS("Autorun.bas"); */
|
|
|
|
function __construct($files) {
|
|
$this->file = $files;
|
|
$this->init();
|
|
}
|
|
|
|
function init() {
|
|
$this->data = file_get_contents($this->file);
|
|
}
|
|
|
|
/* EXAMPLE, $output = $bas->decompile(); */
|
|
|
|
function decompile() {
|
|
$ops = array(
|
|
" STOP ",
|
|
" POP ",
|
|
" RETURN ",
|
|
" END ",
|
|
" NEW ",
|
|
" RUN ",
|
|
" DIR ",
|
|
" DEG ",
|
|
" RAD ",
|
|
" BYE ",
|
|
" GOTO ",
|
|
" GOSUB ",
|
|
" SLEEP ",
|
|
" PRINT ",
|
|
" REM ",
|
|
" DIM ",
|
|
" IF",
|
|
" THEN ",
|
|
" CLS ",
|
|
" PLOT ",
|
|
" DRAWLINE ",
|
|
" FILLRECT ",
|
|
" DRAWRECT ",
|
|
" FILLROUNDRECT ",
|
|
" DRAWROUNDRECT ",
|
|
" FILLARC ",
|
|
" DRAWARC ",
|
|
" DRAWSTRING ",
|
|
" SETCOLOR ",
|
|
" BLIT ",
|
|
" FOR ",
|
|
" TO ",
|
|
" STEP ",
|
|
" NEXT ",
|
|
" INPUT ",
|
|
" LIST ",
|
|
" ENTER ",
|
|
" LOAD ",
|
|
" SAVE ",
|
|
" DELETE ",
|
|
" EDIT ",
|
|
" TRAP ",
|
|
" OPEN ",
|
|
" CLOSE ",
|
|
" NOTE ",
|
|
" POINT ",
|
|
" PUT ",
|
|
" GET ",
|
|
" DATA ",
|
|
" RESTORE ",
|
|
" READ ",
|
|
"=",
|
|
"<>",
|
|
"<",
|
|
"<=",
|
|
">",
|
|
">=",
|
|
"(",
|
|
")",
|
|
",",
|
|
"+",
|
|
"-",
|
|
"-",
|
|
"*",
|
|
"/",
|
|
"^",
|
|
" BITAND ",
|
|
" BITOR ",
|
|
" BITXOR ",
|
|
" NOT ",
|
|
" AND ",
|
|
" OR ",
|
|
"SCREENWIDTH",
|
|
"SCREENHEIGHT",
|
|
" ISCOLOR ",
|
|
" NUMCOLORS ",
|
|
"STRINGWIDTH",
|
|
"STRINGHEIGHT",
|
|
"LEFT$",
|
|
"MID$",
|
|
"RIGHT$",
|
|
"CHR$",
|
|
"STR$",
|
|
"LEN",
|
|
"ASC",
|
|
"VAL",
|
|
" UP ",
|
|
" DOWN ",
|
|
" LEFT ",
|
|
" RIGHT ",
|
|
" FIRE ",
|
|
" GAMEA ",
|
|
" GAMEB ",
|
|
" GAMEC ",
|
|
" GAMED ",
|
|
" DAYS ",
|
|
" MILLISECONDS ",
|
|
" YEAR ",
|
|
" MONTH ",
|
|
" DAY ",
|
|
" HOUR ",
|
|
" MINUTE ",
|
|
" SECOND ",
|
|
" MILLISECOND ",
|
|
"RND",
|
|
" ERR ",
|
|
" FRE ",
|
|
"MOD",
|
|
"EDITFORM ",
|
|
"GAUGEFORM ",
|
|
"CHOICEFORM",
|
|
"DATEFORM",
|
|
"MESSAGEFORM",
|
|
"LOG",
|
|
"EXP",
|
|
"SQR",
|
|
"SIN",
|
|
"COS",
|
|
"TAN",
|
|
"ASIN",
|
|
"ACOS",
|
|
"ATAN",
|
|
"ABS",
|
|
"=",
|
|
"#",
|
|
" PRINT ",
|
|
" INPUT ",
|
|
":",
|
|
" GELGRAB ",
|
|
" DRAWGEL ",
|
|
" SPRITEGEL ",
|
|
" SPRITEMOVE ",
|
|
" SPRITEHIT ",
|
|
"READDIR$",
|
|
"PROPERTY$",
|
|
" GELLOAD ",
|
|
" GELWIDTH",
|
|
" GELHEIGHT",
|
|
" PLAYWAV ",
|
|
" PLAYTONE ",
|
|
" INKEY",
|
|
"SELECT",
|
|
"ALERT ",
|
|
" SETFONT ",
|
|
" MENUADD ",
|
|
" MENUITEM",
|
|
" MENUREMOVE ",
|
|
" CALL ",
|
|
" ENDSUB "
|
|
);
|
|
if ($this->readInt($this->data) != "4d420001") {
|
|
// $this->init();
|
|
return -1;
|
|
} else {
|
|
$isDIM = false;
|
|
$varnum = hexdec($this->readShort($this->data)); ///количество переменных
|
|
$varname = [];
|
|
$main = '';
|
|
//чтение имен переменных
|
|
for ($i = 0; $i < $varnum; $i++) {
|
|
$num = hexdec($this->readShort($this->data)); ///длина имени переменной
|
|
for ($ii = 0; $ii < $num; $ii++) {
|
|
$varname[$i] = $varname[$i] ?? '';
|
|
$varname[$i] .= substr($this->data, 0, 1);
|
|
$this->readByte($this->data);
|
|
}
|
|
$this->readByte($this->data);
|
|
}
|
|
///echo $varname[0];
|
|
$codeln = hexdec($this->readShort($this->data)); //длина остального кода
|
|
if ($codeln != strlen($this->data)) {
|
|
$this->init();
|
|
return -2;
|
|
}
|
|
//for($i=0; $i<$codeln; $i++) ///чтение кода
|
|
while (strlen($this->data) > 0) {
|
|
$line = "";
|
|
$line .= hexdec($this->readShort($this->data)); //пишем номер строки
|
|
$lineS = hexdec($this->readByte($this->data)); //длина строки
|
|
$isl = 1;
|
|
unset($lims);
|
|
for ($ii = 0; $ii < $lineS - 4; $ii++) { ///читаем операторы строки в массив
|
|
$lims[$ii] = $this->readByte($this->data);
|
|
}
|
|
$cur = 0; //позиция чтения
|
|
while ($cur < count($lims)) { //декомпилятор
|
|
$opType = $lims[$cur];
|
|
$cur++;
|
|
if (hexdec($opType) == 0xfc) { ///присваивание
|
|
$varNum = hexdec($lims[$cur]);
|
|
|
|
$limsIndex = $cur - 2;
|
|
if (array_key_exists($limsIndex, $lims) && hexdec($lims[$limsIndex]) == 16)
|
|
$line .= " ";
|
|
|
|
if ($isl == 1) {
|
|
$line .= " " . $varname[$varNum];
|
|
} else
|
|
$line .= $varname[$varNum];
|
|
|
|
|
|
$cur++;
|
|
} else { ///оператор
|
|
$isl = 0;
|
|
switch (hexdec($opType)) {
|
|
case 0x0e:
|
|
$line .= " REM \"";
|
|
$str = hexdec($lims[$cur]); ///длина
|
|
$cur++;
|
|
for ($i = 0; $i < $str; $i++) {
|
|
$line .= iconv("WINDOWS-1251", "UTF-8", chr(hexdec($lims[$cur])));
|
|
$cur++;
|
|
}
|
|
$line .= "\"";
|
|
break;
|
|
case 0xfd:
|
|
$line .= "\"";
|
|
$str = hexdec($lims[$cur]); ///длина
|
|
$cur++;
|
|
for ($i = 0; $i < $str; $i++) {
|
|
$line .= iconv("WINDOWS-1251", "UTF-8", chr(hexdec($lims[$cur])));
|
|
$cur++;
|
|
}
|
|
$line .= "\"";
|
|
break;
|
|
case 0x30:
|
|
$line .= " DATA ";
|
|
$str = hexdec($lims[$cur]); ///длина
|
|
$cur++;
|
|
for ($i = 0; $i < $str; $i++) {
|
|
$line .= iconv("WINDOWS-1251", "UTF-8", chr(hexdec($lims[$cur])));
|
|
$cur++;
|
|
}
|
|
break;
|
|
case 0xf6:
|
|
$line .= "=";
|
|
break;
|
|
case 0xf8:
|
|
$line .= hexdec($lims[$cur]);
|
|
$cur++;
|
|
break;
|
|
case 0xf7:
|
|
$line .= "(";
|
|
continue 2;
|
|
case 0xf9:
|
|
$line .= hexdec($lims[$cur]);
|
|
$cur++;
|
|
break;
|
|
case 0xfa:
|
|
$line .= (hexdec($lims[$cur]) * 256 + hexdec($lims[$cur + 1]));
|
|
$cur = $cur + 2;
|
|
break;
|
|
case 0xfb:
|
|
$line .= (hexdec($lims[$cur]) * 16777216 + hexdec($lims[$cur + 1]) * 65536 + hexdec($lims[$cur + 2]) * 256 + hexdec($lims[$cur + 3]));
|
|
$cur = $cur + 4;
|
|
break;
|
|
case 0xfe:
|
|
(int) $exp = $this->tosbyte(hexdec($lims[$cur + 3]));
|
|
$m = (hexdec($lims[$cur]) * 65536 + hexdec($lims[$cur + 1]) * 256 + hexdec($lims[$cur + 2])) / 500000;
|
|
$e = 1;
|
|
if ($exp > 0) {
|
|
$d = 1;
|
|
for ($i = 0; $i < $exp; $i++)
|
|
$d = $d * 10;
|
|
$e = $d;
|
|
}
|
|
if ($exp < 0) {
|
|
$d = 1;
|
|
for ($i = $exp; $i < 0; $i++)
|
|
$d = $d / 10;
|
|
$e = $d;
|
|
}
|
|
$line .= (float) ($m * $e);
|
|
|
|
$cur = $cur + 4;
|
|
break;
|
|
default:
|
|
$line .= $ops[hexdec($opType)];
|
|
if ($opType == 15 || ($ops[$opType] ?? '') == ' READ ') {
|
|
$isDIM = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$this->readByte($this->data);
|
|
$line .= "\r\n";
|
|
$main .= $line;
|
|
}
|
|
|
|
$this->init();
|
|
return $main;
|
|
}
|
|
}
|
|
|
|
function obfuscation($name) {
|
|
if ($this->readInt($this->data) != "4d420001") {
|
|
/// $this->init();
|
|
return -1;
|
|
} else {
|
|
$main = "";
|
|
$main .= pack('H*', "4d420001"); //writeHex
|
|
|
|
$varnum = hexdec($this->readShort($this->data));
|
|
$main .= pack('n*', $varnum); //writeShort
|
|
// $main.= $this->writeUTF("hello");
|
|
/// echo hexdec($this->readShort($this->data));
|
|
for ($i = 0; $i < $varnum; $i++) { //пропуск переменных
|
|
$this->readUTF($this->data);
|
|
$main .= $this->writeUTF(" ");
|
|
$main .= pack('H*', $this->readByte($this->data));
|
|
}
|
|
$leng = hexdec($this->readShort($this->data));
|
|
$main .= pack('n*', $leng + 7);
|
|
|
|
for ($i = 0; $i < $leng; $i++) {
|
|
$main .= pack('H*', $this->readByte($this->data));
|
|
}
|
|
|
|
$main .= pack('H*', "FFFF");
|
|
|
|
file_put_contents($name, $main);
|
|
}
|
|
|
|
$this->init();
|
|
return 0;
|
|
}
|
|
|
|
function tosbyte($byte) {
|
|
if (0 <= $byte && $byte <= 63)
|
|
return (int) $byte;
|
|
if (64 <= $byte && $byte <= 191)
|
|
return (int) (-(128 - $byte));
|
|
if (192 <= $byte && $byte <= 255)
|
|
return (int) (-(256 - $byte));
|
|
return 0;
|
|
}
|
|
|
|
function readInt($text) {
|
|
$this->data = substr($text, 4, strlen($text));
|
|
return bin2hex(substr($text, 0, 4));
|
|
}
|
|
|
|
function readShort($text) {
|
|
$this->data = substr($text, 2, strlen($text));
|
|
return bin2hex(substr($text, 0, 2));
|
|
}
|
|
|
|
function readByte($text) {
|
|
$this->data = substr($text, 1, strlen($text));
|
|
return bin2hex(substr($text, 0, 1));
|
|
}
|
|
|
|
function readUTF() {
|
|
// $this->data = substr($text, 1, strlen($text));
|
|
// return bin2hex(substr($text, 0, 1));
|
|
$to = hexdec($this->readShort($this->data));
|
|
$bombom = "";
|
|
while ($to <> 0) {
|
|
$bombom .= iconv("WINDOWS-1251", "UTF-8", chr(hexdec($this->readByte($this->data))));
|
|
$to--;
|
|
}
|
|
// $this->readByte($this->data);
|
|
return $bombom;
|
|
}
|
|
|
|
function writeUTF($text) {
|
|
$pack = pack('n*', mb_strlen($text));
|
|
$pack .= pack('a*', $text);
|
|
return $pack;
|
|
}
|
|
} |