Advertisement
nicopow

Untitled

Jun 26th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.51 KB | None | 0 0
  1. local data = {'\27','\76','\117','\97','\81','\0','\1','\4','\4','\4','\8','\0','\29','\0','\0','\0','\61','\87','\111','\114',
  2. '\107','\115','\112','\97','\99','\101','\46','\83','\111','\117','\114','\99','\101','\32','\69','\110','\99','\114','\121',
  3. '\112','\116','\105','\111','\110','\0','\1','\0','\0','\0','\21','\0','\0','\0','\0','\0','\0','\2','\4','\0','\0','\0',
  4. '\5','\0','\0','\0','\65','\64','\0','\0','\28','\64','\0','\1','\30','\0','\128','\0','\2','\0','\0','\0','\4','\6','\0',
  5. '\0','\0','\112','\114','\105','\110','\116','\0','\4','\9','\0','\0','\0','\117','\32','\119','\111','\116','\32','\109',
  6. '\56','\0','\0','\0','\0','\0','\4','\0','\0','\0','\13','\0','\0','\0','\13','\0','\0','\0','\13','\0','\0','\0','\21','\0',
  7. '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}
  8.  
  9. local lua_opcode_types = {
  10. "ABC", "ABx", "ABC", "ABC",
  11. "ABC", "ABx", "ABC", "ABx",
  12. "ABC", "ABC", "ABC", "ABC",
  13. "ABC", "ABC", "ABC", "ABC",
  14. "ABC", "ABC", "ABC", "ABC",
  15. "ABC", "ABC", "AsBx", "ABC",
  16. "ABC", "ABC", "ABC", "ABC",
  17. "ABC", "ABC", "ABC", "AsBx",
  18. "AsBx", "ABC", "ABC", "ABC",
  19. "ABx", "ABC",
  20. }
  21. local lua_opcode_names = {
  22. "MOVE", "LOADK", "LOADBOOL", "LOADNIL",
  23. "GETUPVAL", "GETGLOBAL", "GETTABLE", "SETGLOBAL",
  24. "SETUPVAL", "SETTABLE", "NEWTABLE", "SELF",
  25. "ADD", "SUB", "MUL", "DIV",
  26. "MOD", "POW", "UNM", "NOT",
  27. "LEN", "CONCAT", "JMP", "EQ",
  28. "LT", "LE", "TEST", "TESTSET",
  29. "CALL", "TAILCALL", "RETURN", "FORLOOP",
  30. "FORPREP", "TFORLOOP", "SETLIST", "CLOSE",
  31. "CLOSURE", "VARARG"
  32. };
  33. local function get_bits(input, n, n2)
  34. if n2 then
  35. local total = 0
  36. local digitn = 0
  37. for i = n, n2 do
  38. total = total + 2^digitn*get_bits(input, i)
  39. digitn = digitn + 1
  40. end
  41. return total
  42. else
  43. local pn = 2^(n-1)
  44. return (input % (pn + pn) >= pn) and 1 or 0
  45. end
  46. end
  47. local function decode_bytecode(bytecode)
  48. local index = 1
  49. local big_endian = false
  50. local int_size;
  51. local size_t;
  52. local get_int, get_size_t;
  53. local get_int8, get_int32, get_int64, get_float64, get_string;
  54. do
  55. function get_int8()
  56. local a = bytecode:byte(index, index);
  57. index = index + 1
  58. return a
  59. end
  60. function get_int32()
  61. local a, b, c, d = bytecode:byte(index, index + 3);
  62. index = index + 4;
  63. return d*16777216 + c*65536 + b*256 + a
  64. end
  65. function get_int64()
  66. local a = get_int32();
  67. local b = get_int32();
  68. return b*4294967296 + a;
  69. end
  70. function get_float64()
  71. local a = get_int32()
  72. local b = get_int32()
  73. return (-2*get_bits(b, 32)+1)*(2^(get_bits(b, 21, 31)-1023))*
  74. ((get_bits(b, 1, 20)*(2^32) + a)/(2^52)+1)
  75. end
  76. function get_string(len)
  77. local str;
  78. if len then
  79. str = bytecode:sub(index, index + len - 1);
  80. index = index + len;
  81. else
  82. len = get_size_t();
  83. if len == 0 then return; end
  84. str = bytecode:sub(index, index + len - 1);
  85. index = index + len;
  86. end
  87. return str;
  88. end
  89. end
  90. local function decode_chunk()
  91. local chunk;
  92. local instructions = {};
  93. local constants = {};
  94. local prototypes = {};
  95. local debug = {
  96. lines = {};
  97. };
  98. chunk = {
  99. instructions = instructions;
  100. constants = constants;
  101. prototypes = prototypes;
  102. debug = debug;
  103. };
  104. local num;
  105. chunk.name = get_string();
  106. chunk.first_line = get_int();
  107. chunk.last_line = get_int();
  108. if chunk.name then chunk.name = chunk.name:sub(1, -2); end
  109. chunk.upvalues = get_int8();
  110. chunk.arguments = get_int8();
  111. chunk.varg = get_int8();
  112. chunk.stack = get_int8();
  113. do
  114. num = get_int();
  115. for i = 1, num do
  116. local instruction = {
  117. };
  118. local data = get_int32();
  119. local opcode = get_bits(data, 1, 6);
  120. local type = lua_opcode_types[opcode + 1];
  121. instruction.opcode = opcode;
  122. instruction.type = type;
  123. instruction.A = get_bits(data, 7, 14);
  124. if type == "ABC" then
  125. instruction.B = get_bits(data, 24, 32);
  126. instruction.C = get_bits(data, 15, 23);
  127. elseif type == "ABx" then
  128. instruction.Bx = get_bits(data, 15, 32);
  129. elseif type == "AsBx" then
  130. instruction.sBx = get_bits(data, 15, 32) - 131071;
  131. end
  132. instructions[i] = instruction;
  133. end
  134. end
  135. do
  136. num = get_int();
  137. for i = 1, num do
  138. local constant = {
  139. };
  140. local type = get_int8();
  141. constant.type = type;
  142. if type == 1 then
  143. constant.data = (get_int8() ~= 0);
  144. elseif type == 3 then
  145. constant.data = get_float64();
  146. elseif type == 4 then
  147. constant.data = get_string():sub(1, -2);
  148. end
  149. constants[i-1] = constant;
  150. end
  151. end
  152. do
  153. num = get_int();
  154. for i = 1, num do
  155. prototypes[i-1] = decode_chunk();
  156. end
  157. end
  158. do
  159. local data = debug.lines
  160. num = get_int();
  161. for i = 1, num do
  162. data[i] = get_int32();
  163. end
  164. num = get_int();
  165. for i = 1, num do
  166. get_string():sub(1, -2);
  167. get_int32();
  168. get_int32();
  169. end
  170. num = get_int();
  171. for i = 1, num do
  172. get_string();
  173. end
  174. end
  175. return chunk;
  176. end
  177. do
  178. assert(get_string(4) == "\27Lua", "Lua bytecode expected.");
  179. assert(get_int8() == 0x51, "Only Lua 5.1 is supported.");
  180. get_int8();
  181. big_endian = (get_int8() == 0);
  182. int_size = get_int8();
  183. size_t = get_int8();
  184. if int_size == 4 then
  185. get_int = get_int32;
  186. elseif int_size == 8 then
  187. get_int = get_int64;
  188. else
  189. error("Unsupported bytecode target platform");
  190. end
  191. if size_t == 4 then
  192. get_size_t = get_int32;
  193. elseif size_t == 8 then
  194. get_size_t = get_int64;
  195. else
  196. error("Unsupported bytecode target platform");
  197. end
  198. assert(get_string(3) == "\4\8\0",
  199. "Unsupported bytecode target platform");
  200. end
  201. return decode_chunk();
  202. end
  203. local function handle_return(...)
  204. local c = select("#", ...)
  205. local t = {...}
  206. return c, t
  207. end
  208. local function create_wrapper(cache, upvalues)
  209. local instructions = cache.instructions;
  210. local constants = cache.constants;
  211. local prototypes = cache.prototypes;
  212.  
  213. local stack, top
  214. local environment
  215. local IP = 1;
  216. local vararg, vararg_size
  217.  
  218. local opcode_funcs = {
  219. [0] = function(instruction)
  220. stack[instruction.A] = stack[instruction.B];
  221. end,
  222. [1] = function(instruction)
  223. stack[instruction.A] = constants[instruction.Bx].data;
  224. end,
  225. [2] = function(instruction)
  226. stack[instruction.A] = instruction.B ~= 0
  227. if instruction.C ~= 0 then
  228. IP = IP + 1
  229. end
  230. end,
  231. [3] = function(instruction)
  232. local stack = stack
  233. for i = instruction.A, instruction.B do
  234. stack[i] = nil
  235. end
  236. end,
  237. [4] = function(instruction)
  238. stack[instruction.A] = upvalues[instruction.B]
  239. end,
  240. [5] = function(instruction)
  241. local key = constants[instruction.Bx].data;
  242. stack[instruction.A] = environment[key];
  243. end,
  244. [6] = function(instruction)
  245. local C = instruction.C
  246. local stack = stack
  247. C = C > 255 and constants[C-256].data or stack[C]
  248. stack[instruction.A] = stack[instruction.B][C];
  249. end,
  250. [7] = function(instruction)
  251. local key = constants[instruction.Bx].data;
  252. environment[key] = stack[instruction.A];
  253. end,
  254. [8] = function (instruction)
  255. upvalues[instruction.B] = stack[instruction.A]
  256. end,
  257. [9] = function (instruction)
  258. local B = instruction.B;
  259. local C = instruction.C;
  260. local stack, constants = stack, constants;
  261. B = B > 255 and constants[B-256].data or stack[B];
  262. C = C > 255 and constants[C-256].data or stack[C];
  263. stack[instruction.A][B] = C
  264. end,
  265. [10] = function (instruction)
  266. stack[instruction.A] = {}
  267. end,
  268. [11] = function (instruction)
  269. local A = instruction.A
  270. local B = instruction.B
  271. local C = instruction.C
  272. local stack = stack
  273. B = stack[B]
  274. C = C > 255 and constants[C-256].data or stack[C]
  275. stack[A+1] = B
  276. stack[A] = B[C]
  277. end,
  278. [12] = function(instruction)
  279. local B = instruction.B;
  280. local C = instruction.C;
  281. local stack, constants = stack, constants;
  282. B = B > 255 and constants[B-256].data or stack[B];
  283. C = C > 255 and constants[C-256].data or stack[C];
  284. stack[instruction.A] = B+C;
  285. end,
  286. [13] = function(instruction)
  287. local B = instruction.B;
  288. local C = instruction.C;
  289. local stack, constants = stack, constants;
  290. B = B > 255 and constants[B-256].data or stack[B];
  291. C = C > 255 and constants[C-256].data or stack[C];
  292. stack[instruction.A] = B - C;
  293. end,
  294. [14] = function(instruction)
  295. local B = instruction.B;
  296. local C = instruction.C;
  297. local stack, constants = stack, constants;
  298. B = B > 255 and constants[B-256].data or stack[B];
  299. C = C > 255 and constants[C-256].data or stack[C];
  300. stack[instruction.A] = B * C;
  301. end,
  302. [15] = function(instruction)
  303. local B = instruction.B;
  304. local C = instruction.C;
  305. local stack, constants = stack, constants;
  306. B = B > 255 and constants[B-256].data or stack[B];
  307. C = C > 255 and constants[C-256].data or stack[C];
  308. stack[instruction.A] = B / C;
  309. end,
  310. [16] = function(instruction)
  311. local B = instruction.B;
  312. local C = instruction.C;
  313. local stack, constants = stack, constants;
  314. B = B > 255 and constants[B-256].data or stack[B];
  315. C = C > 255 and constants[C-256].data or stack[C];
  316. stack[instruction.A] = B % C;
  317. end,
  318. [17] = function(instruction)
  319. local B = instruction.B;
  320. local C = instruction.C;
  321. local stack, constants = stack, constants;
  322. B = B > 255 and constants[B-256].data or stack[B];
  323. C = C > 255 and constants[C-256].data or stack[C];
  324. stack[instruction.A] = B ^ C;
  325. end,
  326. [18] = function(instruction)
  327. stack[instruction.A] = -stack[instruction.B]
  328. end,
  329. [19] = function(instruction)
  330. stack[instruction.A] = not stack[instruction.B]
  331. end,
  332. [20] = function(instruction)
  333. stack[instruction.A] = #stack[instruction.B]
  334. end,
  335. [21] = function(instruction)
  336. local B = instruction.B
  337. local result = stack[B]
  338. for i = B+1, instruction.C do
  339. result = result .. stack[i]
  340. end
  341. stack[instruction.A] = result
  342. end,
  343. [22] = function(instruction)
  344. IP = IP + instruction.sBx
  345. end,
  346. [23] = function(instruction)
  347. local A = instruction.A
  348. local B = instruction.B
  349. local C = instruction.C
  350. local stack, constants = stack, constants
  351. A = A ~= 0
  352. B = B > 255 and constants[B-256].data or stack[B]
  353. C = C > 255 and constants[C-256].data or stack[C]
  354. if (B == C) ~= A then
  355. IP = IP + 1
  356. end
  357. end,
  358. [24] = function(instruction)
  359. local A = instruction.A
  360. local B = instruction.B
  361. local C = instruction.C
  362. local stack, constants = stack, constants
  363. A = A ~= 0
  364. B = B > 255 and constants[B-256].data or stack[B]
  365. C = C > 255 and constants[C-256].data or stack[C]
  366. if (B < C) ~= A then
  367. IP = IP + 1
  368. end
  369. end,
  370. [25] = function(instruction)
  371. local A = instruction.A
  372. local B = instruction.B
  373. local C = instruction.C
  374. local stack, constants = stack, constants
  375. A = A ~= 0
  376. B = B > 255 and constants[B-256].data or stack[B]
  377. C = C > 255 and constants[C-256].data or stack[C]
  378. if (B <= C) ~= A then
  379. IP = IP + 1
  380. end
  381. end,
  382. [26] = function(instruction)
  383. if stack[instruction.A] == (instruction.C ~= 0) then
  384. IP = IP + 1
  385. end
  386. end,
  387. [27] = function(instruction)
  388. local stack = stack
  389. local B = stack[instruction.B]
  390. if B == (instruction.C ~= 0) then
  391. IP = IP + 1
  392. else
  393. stack[instruction.A] = B
  394. end
  395. end,
  396. [28] = function(instruction)
  397. local A = instruction.A;
  398. local B = instruction.B;
  399. local C = instruction.C;
  400. local stack = stack;
  401. local args, results;
  402. local limit, loop
  403. args = {};
  404. if B ~= 1 then
  405. if B ~= 0 then
  406. limit = A+B-1;
  407. else
  408. limit = top
  409. end
  410. loop = 0
  411. for i = A+1, limit do
  412. loop = loop + 1
  413. args[loop] = stack[i];
  414. end
  415. limit, results = handle_return(stack[A](unpack(args, 1, limit-A)))
  416. else
  417. limit, results = handle_return(stack[A]())
  418. end
  419. top = A - 1
  420. if C ~= 1 then
  421. if C ~= 0 then
  422. limit = A+C-2;
  423. else
  424. limit = limit+A
  425. end
  426. loop = 0;
  427. for i = A, limit do
  428. loop = loop + 1;
  429. stack[i] = results[loop];
  430. end
  431. end
  432. end,
  433. [29] = function (instruction)
  434. local A = instruction.A;
  435. local B = instruction.B;
  436. local C = instruction.C;
  437. local stack = stack;
  438. local args, results;
  439. local top, limit, loop = top
  440. args = {};
  441. if B ~= 1 then
  442. if B ~= 0 then
  443. limit = A+B-1;
  444. else
  445. limit = top
  446. end
  447. loop = 0
  448. for i = A+1, limit do
  449. loop = loop + 1
  450. args[#args+1] = stack[i];
  451. end
  452. results = {stack[A](unpack(args, 1, limit-A))};
  453. else
  454. results = {stack[A]()};
  455. end
  456. return true, results
  457. end,
  458. [30] = function(instruction)
  459. local A = instruction.A;
  460. local B = instruction.B;
  461. local stack = stack;
  462. local limit;
  463. local loop, output;
  464. if B == 1 then
  465. return true;
  466. end
  467. if B == 0 then
  468. limit = top
  469. else
  470. limit = A + B - 2;
  471. end
  472. output = {};
  473. local loop = 0
  474. for i = A, limit do
  475. loop = loop + 1
  476. output[loop] = stack[i];
  477. end
  478. return true, output;
  479. end,
  480. [31] = function(instruction)
  481. local A = instruction.A
  482. local stack = stack
  483. local step = stack[A+2]
  484. local index = stack[A] + step
  485. stack[A] = index
  486. if step > 0 then
  487. if index <= stack[A+1] then
  488. IP = IP + instruction.sBx
  489. stack[A+3] = index
  490. end
  491. else
  492. if index >= stack[A+1] then
  493. IP = IP + instruction.sBx
  494. stack[A+3] = index
  495. end
  496. end
  497. end,
  498. [32] = function(instruction)
  499. local A = instruction.A
  500. local stack = stack
  501. stack[A] = stack[A] - stack[A+2]
  502. IP = IP + instruction.sBx
  503. end,
  504. [33] = function(instruction)
  505. local A = instruction.A
  506. local B = instruction.B
  507. local C = instruction.C
  508. local stack = stack
  509. local offset = A+2
  510. local result = {stack[A](stack[A+1], stack[A+2])}
  511. for i = 1, C do
  512. stack[offset+i] = result[i]
  513. end
  514. if stack[A+3] ~= nil then
  515. stack[A+2] = stack[A+3]
  516. else
  517. IP = IP + 1
  518. end
  519. end,
  520. [34] = function(instruction)
  521. local A = instruction.A
  522. local B = instruction.B
  523. local C = instruction.C
  524. local stack = stack
  525. if C == 0 then
  526. error("NYI: extended SETLIST")
  527. else
  528. local offset = (C - 1) * 50
  529. local t = stack[A]
  530. if B == 0 then
  531. B = top
  532. end
  533. for i = 1, B do
  534. t[offset+i] = stack[A+i]
  535. end
  536. end
  537. end,
  538. [35] = function(instruction)
  539. io.stderr:write("NYI: CLOSE")
  540. io.stderr:flush()
  541. end,
  542. [36] = function(instruction)
  543. local proto = prototypes[instruction.Bx]
  544. local instructions = instructions
  545. local stack = stack
  546. local indices = {}
  547. local new_upvals = setmetatable({},
  548. {
  549. __index = function(t, k)
  550. local upval = indices[k]
  551. return upval.segment[upval.offset]
  552. end,
  553. __newindex = function(t, k, v)
  554. local upval = indices[k]
  555. upval.segment[upval.offset] = v
  556. end
  557. }
  558. )
  559. for i = 1, proto.upvalues do
  560. local movement = instructions[IP]
  561. if movement.opcode == 0 then
  562. indices[i-1] = {segment = stack, offset = movement.B}
  563. elseif instructions[IP].opcode == 4 then
  564. indices[i-1] = {segment = upvalues, offset = movement.B}
  565. end
  566. IP = IP + 1
  567. end
  568. local _, func = create_wrapper(proto, new_upvals)
  569. stack[instruction.A] = func
  570. end,
  571. [37] = function(instruction)
  572. local A = instruction.A
  573. local B = instruction.B
  574. local stack, vararg = stack, vararg
  575.  
  576. for i = A, A + (B > 0 and B - 1 or vararg_size) do
  577. stack[i] = vararg[i - A]
  578. end
  579. end,
  580. }
  581. local function loop()
  582. local instructions = instructions
  583. local instruction, a, b
  584. while true do
  585. instruction = instructions[IP];
  586. IP = IP + 1
  587. a, b = opcode_funcs[instruction.opcode](instruction);
  588. if a then
  589. return b;
  590. end
  591. end
  592. end
  593. local debugging = {
  594. get_stack = function()
  595. return stack;
  596. end;
  597. get_IP = function()
  598. return IP;
  599. end
  600. };
  601. local function func(...)
  602. local local_stack = {};
  603. local ghost_stack = {};
  604. top = -1
  605. stack = setmetatable(local_stack, {
  606. __index = ghost_stack;
  607. __newindex = function(t, k, v)
  608. if k > top and v then
  609. top = k
  610. end
  611. ghost_stack[k] = v
  612. end;
  613. })
  614. local args = {...};
  615. vararg = {}
  616. vararg_size = select("#", ...) - 1
  617. for i = 0, vararg_size do
  618. local_stack[i] = args[i+1];
  619. vararg[i] = args[i+1]
  620. end
  621. environment = getfenv();
  622. IP = 1;
  623. local thread = coroutine.create(loop)
  624. local a, b = coroutine.resume(thread)
  625. if a then
  626. if b then
  627. return unpack(b);
  628. end
  629. return;
  630. else
  631. local name = cache.name;
  632. local line = cache.debug.lines[IP];
  633. local err = b:gsub("(.-:)", "");
  634. local output = "";
  635. output = output .. (name and name .. ":" or "");
  636. output = output .. (line and line .. ":" or "");
  637. output = output .. b
  638. error(output, 0);
  639. end
  640. end
  641. return debugging, func;
  642. end
  643. local VM = {
  644. load_bytecode = function(bytecode)
  645. local cache = decode_bytecode(bytecode);
  646. local _, func = create_wrapper(cache);
  647. return func;
  648. end;
  649. utils = {
  650. decode_bytecode = decode_bytecode;
  651. create_wrapper = create_wrapper;
  652. debug_bytecode = function(bytecode)
  653. local cache = decode_bytecode(bytecode)
  654. return create_wrapper(cache);
  655. end;
  656. };
  657. }
  658. VM.load_bytecode(table.concat(data, [[]]))()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement