MBCompilerOnline/classes/bas.class.php

404 lines
13 KiB
PHP
Raw Normal View History

2024-05-11 17:47:33 +03:00
<?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;
}
}