Skip to content
Snippets Groups Projects
Commit e002363e authored by vincent's avatar vincent
Browse files

BTC Parser

	* Fix- The number of bytes to push onto the stack was incorrect.
	  Example: a0 should be interpreted as 160, not -32
parent 68f48b6d
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,6 @@ from symbolic_execution.language.exceptions import IncompleteIfEndIfClause
pyparsing.ParserElement.enablePackrat()
from collections import deque
from symbolic_execution.hardware.machines.btc_machine import str_to_int
from symbolic_execution.program.block.interfaces import IInstructionBlock
from symbolic_execution.program.block.instruction_block import InstructionBlock
......@@ -33,6 +32,23 @@ import sys
sys.setrecursionlimit(1000000)
def read_little_endian(hex: str, bytes: int, start: int = 0) -> int:
"""Read and returns the integer value of a hexadecimal value in little endian contained in a string.
Args:
hex: A string containing a hexadecimal value encoded in little endian.
bytes: The number of bytes to read.
start: The offset of the beginning of the hex value.
Returns:
int: The integer value of the hex string in little endian.
Examples:
read_little_endian('xxxaf12xx', 2, 3) will return 4783
"""
ordered = [hex[i : i + 2] for i in range(start, start + bytes * 2, 2)][::-1]
string = "".join(ordered)
return int(string, 16)
class BitcoinParser(ILanguage):
"""Parser for the Bitcoin script language."""
......@@ -72,11 +88,11 @@ class BitcoinParser(ILanguage):
OP_PUSH_0 = MatchFirst([format(op, "02x") for op in range(0x01, 0x4C)])
OP_PUSH_0.addParseAction(lambda t: int(t[0], 16))
OP_PUSH_1 = Literal("4c") + Word(hexnums, exact=2)
OP_PUSH_1.addParseAction(lambda t: str_to_int(t[1]))
OP_PUSH_1.addParseAction(lambda t: read_little_endian(t[1], 1))
OP_PUSH_2 = Literal("4d") + Word(hexnums, exact=4)
OP_PUSH_2.addParseAction(lambda t: str_to_int(t[1]))
OP_PUSH_2.addParseAction(lambda t: read_little_endian(t[1], 2))
OP_PUSH_4 = Literal("4e") + Word(hexnums, exact=8)
OP_PUSH_4.addParseAction(lambda t: str_to_int(t[1]))
OP_PUSH_4.addParseAction(lambda t: read_little_endian(t[1], 4))
OP_PUSH = MatchFirst([OP_PUSH_0, OP_PUSH_1, OP_PUSH_2, OP_PUSH_4])
DATA = Combine(countedArray(BYTE, intExpr=OP_PUSH))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment