Advertisement
Guest User

Untitled

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