Guest User

Untitled

a guest
Jun 24th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.08 KB | None | 0 0
  1. <?PHP
  2.  
  3. if ($argc != 2)
  4. {
  5. echo "Need a file parameter.\n";
  6. exit ();
  7. }
  8.  
  9. class x86VM
  10. {
  11. // Some registers.
  12. private $ax, $bx, $cx, $dx;
  13. private $ah, $bh, $ch, $dh;
  14. private $al, $bl, $cl, $dl;
  15. private $sp;
  16.  
  17. private $mode = ".CODE";
  18.  
  19. private $data = array ();
  20. private $dataAddressesByObject = array();
  21. private $dataAddressesByAddress = array();
  22. private $dataAddressesOffset = 0;
  23.  
  24. private $debugMode = false;
  25.  
  26. public function dEcho ($text)
  27. {
  28. if ($this -> debugMode)
  29. {
  30. echo $text;
  31. }
  32. }
  33.  
  34. public function __construct ()
  35. {
  36. $this -> ax = $this -> bx = $this -> cx = $this -> dx = 0;
  37. $this -> refresh ();
  38. $this -> sp = 0;
  39. }
  40.  
  41. public function refresh ()
  42. {
  43. $this -> ah = ($this -> ax) >> 8;
  44. $this -> al = ($this -> ax) - ($this -> ah * 256);
  45. $this -> bh = ($this -> bx) >> 8;
  46. $this -> bl = ($this -> bx) - ($this -> bh * 256);
  47. $this -> ch = ($this -> cx) >> 8;
  48. $this -> cl = ($this -> cx) - ($this -> ch * 256);
  49. $this -> dh = ($this -> dx) >> 8;
  50. $this -> dl = ($this -> dx) - ($this -> dh * 256);
  51.  
  52. $vars = array ("ax", "ah", "al", "bx", "bh", "bl", "cx", "ch", "cl", "dx", "dh", "dl");
  53.  
  54. foreach ($vars as $thisvar)
  55. {
  56. $this -> dEcho ($thisvar . " => " . $this -> $thisvar . "\n");
  57. }
  58. $this -> dEcho ("\n");
  59. }
  60.  
  61. public function readString ($strIn)
  62. {
  63. $finalString = null;
  64. $readingString = false;
  65.  
  66. // This will do more to the string, like actually parse its contents.
  67. $del = substr ($strIn, 0, 1);
  68. for ($i = 0; $i < strlen ($strIn); $i++)
  69. {
  70. if ($strIn[$i] == $del)
  71. {
  72. $readingString = !$readingString;
  73. }
  74. else
  75. {
  76. if ($strIn[$i] == "\\")
  77. {
  78. switch ($strIn[$i + 1])
  79. {
  80. case "r":
  81. $finalString .= "\r";
  82. break;
  83. case "n":
  84. $finalString .= "\n";
  85. break;
  86. case "\\":
  87. $finalString .= "\\";
  88. break;
  89. case "'":
  90. $finalString .= "'";
  91. break;
  92. case "\"":
  93. $finalString .= "\"";
  94. break;
  95. default:
  96. $finalString .= $strIn[$i + 1];
  97. break;
  98. }
  99. $i++;
  100. }
  101. else if ($strIn[$i] == "$")
  102. {
  103. // The string is terminated.
  104. // Read additional characters.
  105.  
  106. // Last terminator...
  107. $i++;
  108.  
  109. // Remaining
  110. $remaining = substr ($strIn, $i);
  111. $remainingValues = explode (",", $remaining);
  112.  
  113. // Start at 1 to ignore initial string
  114. for ($vx = 1; $vx < count ($remainingValues); $vx++)
  115. {
  116. $finalString .= chr (hexdec ($remainingValues[$vx]));
  117. }
  118.  
  119. // Terminate the job.
  120. $i = strlen ($strIn);
  121. }
  122. else
  123. {
  124. $finalString .= $strIn[$i];
  125. }
  126. }
  127.  
  128. }
  129.  
  130. return $finalString;
  131. }
  132.  
  133. public function exec ($arguments)
  134. {
  135. if ($arguments != null)
  136. {
  137. // print_r ($arguments);
  138.  
  139. if (($this -> mode == ".DATA") && ($arguments[1] == "db"))
  140. {
  141. $this -> data[$arguments[0]] = $this -> readString ($arguments[2]);
  142. $this -> dataAddressesByObject[$arguments[0]] = $this -> dataAddressesOffset;
  143. $this -> dataAddressesByAddress[$this -> dataAddressesOffset] = $arguments[0];
  144. $this -> dataAddressesOffset += strlen ($this -> data[$arguments[0]]);
  145.  
  146. return null;
  147. }
  148.  
  149. switch ($arguments[0])
  150. {
  151. case ".MODEL":
  152. case ".STACK":
  153. $this -> dEcho ("* Ignoring these calls for now.\n");
  154. return null;
  155. case ".CODE":
  156. case ".DATA":
  157. $this -> set_mode ($arguments[0]);
  158. return null;
  159. case "int":
  160. $this -> interrupt ($this -> parse_num ($arguments[1]));
  161. return null;
  162. case "mov":
  163. $reg = $this -> strip_comma ($arguments[1]);
  164. $this -> dEcho ("Have $reg \n");
  165. if (($reg == "ax") || ($reg == "bx") || ($reg == "cx") || ($reg == "dx"))
  166. {
  167. $this -> mov_xreg_val ($reg, $this -> parse_num ($arguments[2]));
  168. return null;
  169. }
  170. else if (($reg == "ah") || ($reg == "bh") || ($reg == "ch") || ($reg == "dh"))
  171. {
  172. $this -> mov_hreg_val ($reg, $this -> parse_num ($arguments[2]));
  173. return null;
  174. }
  175. else if (($reg == "al") || ($reg == "bl") || ($reg == "cl") || ($reg == "dl"))
  176. {
  177. $this -> dEcho ("Unhandled al/bl/cl/dl...\n");
  178. return null;
  179. }
  180. break;
  181. case "lea":
  182. $reg = $this -> strip_comma ($arguments[1]);
  183. $this -> $reg = $this -> dataAddressesByObject[$arguments[2]];
  184. $this -> dEcho ("* Loading " . $reg . " with " . $this -> $reg . "\n");
  185. return null;
  186. default:
  187. $this -> dEcho ("Failure -- Unhandled instruction:\n");
  188. exit ();
  189. }
  190. }
  191. }
  192.  
  193. public function strip_comma ($reg)
  194. {
  195. return substr ($reg, 0, -1);
  196. }
  197.  
  198. public function parse_num ($val2)
  199. {
  200. $val = trim ($val2);
  201. // check for h
  202. if (strtolower(substr($val, -1)) == "h")
  203. {
  204. // Convert it from hex to decimal.
  205. return hexdec (substr ($val, 0, -1));
  206. }
  207. else
  208. {
  209. return intval ($val);
  210. }
  211. }
  212.  
  213. public function set_mode ($mode)
  214. {
  215. $this -> dEcho ("* Setting mode to: " . $mode . "\n");
  216. $this -> mode = $mode;
  217. }
  218.  
  219. public function mov_xreg_val ($register, $value)
  220. {
  221. $this -> dEcho ("Setting $register to $value \n");
  222. $wi = $value;
  223. if ($wi > 65535) $wi = 65535;
  224. if ($wi < 0) $wi = 0;
  225. $this -> $register = $wi;
  226. $this -> refresh();
  227. return null;
  228. }
  229.  
  230. public function mov_hreg_val ($register, $value)
  231. {
  232. $wi = $value;
  233. if ($wi > 255) $wi = 255;
  234. if ($wi < 0) $wi = 0;
  235.  
  236. $low = substr($register, 0, -1) . "l";
  237. $all = substr($register, 0, -1) . "x";
  238.  
  239. $v = ($value * 256) + $this -> $low;
  240.  
  241. $this -> $all = $v;
  242.  
  243. $this -> refresh();
  244.  
  245. return null;
  246. }
  247.  
  248. public function interrupt ($interrupt)
  249. {
  250. switch ($interrupt)
  251. {
  252. case 33:
  253. // Check what we have in AH as our primary interrupt checker.
  254. switch ($this -> ah)
  255. {
  256. case 0x09:
  257. // Print the contents of DX as a string.
  258. echo $this -> data[$this -> dataAddressesByAddress[$this -> dx]];
  259. break;
  260. case 0x4c:
  261. $this -> dEcho ("* Terminate with code " . $this -> al . "\n");
  262. exit ($this -> al);
  263. }
  264. break;
  265. default:
  266. echo "Failure -- Unhandled interrupt: " . $interrupt . "\n";
  267. exit ();
  268. break;
  269. }
  270. }
  271. }
  272.  
  273. function read ($line)
  274. {
  275. $code = explode (";", $line); // Split by the comment.
  276. $thisCode = trim($code[0]);
  277. if (strlen($code[0]) == 0) return null;
  278. $args = explode (" ", $code[0], 3);
  279.  
  280. // Clean the args up
  281. for ($i = 0; $i < count ($args); $i++)
  282. {
  283. $args[$i] = trim ($args[$i]);
  284. }
  285.  
  286. if ($args[0] != NULL)
  287. {
  288. return $args;
  289. }
  290. return null;
  291. }
  292.  
  293. $vm = new x86VM();
  294.  
  295. $data = file_get_contents ($argv[1]);
  296. $lines = explode ("\n", $data);
  297.  
  298. foreach ($lines as $aLine)
  299. {
  300. // echo ">> " . $aLine . "\n";
  301. $vm -> exec (read ($aLine));
  302. // echo "\n";
  303. }
  304.  
  305.  
  306. ?>
Add Comment
Please, Sign In to add comment