Advertisement
Guest User

Untitled

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