Skip to content

Commit 23059e9

Browse files
committed
Make GeneratorOrInt class more flexible
1 parent 419b653 commit 23059e9

4 files changed

Lines changed: 38 additions & 33 deletions

File tree

ptrlib/binary/operation/rotate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def rol(data: _T, n: int, bits: int=32) -> _T:
2626
data &= ((1 << bits) - 1)
2727
return ((data << n) | (data >> (bits - n))) & ((1 << bits) - 1)
2828

29-
if isinstance(data, (str, bytes, list)):
29+
if isinstance(data, (str, bytes, bytearray, list)):
3030
return data[n:] + data[:n]
3131

3232
raise ValueError(f"{type(data)} given ('int'/'str'/'bytes'/'list' expected)")
@@ -49,7 +49,7 @@ def ror(data: _T, n: int, bits: int=32) -> _T:
4949
data &= ((1 << bits) - 1)
5050
return ((data >> n) | ((data & ((1 << n) - 1)) << (bits - n))) & ((1 << bits) - 1)
5151

52-
if isinstance(data, (str, bytes, list)):
52+
if isinstance(data, (str, bytes, bytearray, list)):
5353
return data[-n:] + data[:-n]
5454

5555
raise ValueError(f"{type(data)} given ('int'/'str'/'bytes'/'list' expected)")

ptrlib/pwn/xop/rop.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def search(self, code: str, syntax: PtrlibAssemblySyntaxT='intel'):
3434

3535
# Assemble gadget
3636
bytecode = self._bin.cpu.assemble(code, syntax=syntax)
37-
return GeneratorOrInt(self._bin.search(bytecode, executable=True).generator, code.encode())
37+
return self._bin.search(bytecode, executable=True)
3838

3939

4040
__all__ = ['GadgetFinder']

ptrlib/types/__init__.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,4 @@
11
"""This package provides types defined in ptrlib
22
"""
3-
from typing import Literal, TypeAlias, Union, SupportsInt, SupportsIndex
3+
from .enums import *
44
from .genint import *
5-
6-
PtrlibArchT = Literal['unknown', 'intel', 'arm', 'risc-v', 'sparc', 'mips']
7-
PtrlibBitsT = Literal[16, 32, 64]
8-
PtrlibEndiannessT = Literal['little', 'big']
9-
PtrlibAssemblySyntaxT = Literal['intel', 'att']
10-
PtrlibAssemblerT = Literal['keystone', 'gcc', 'nasm', 'none']
11-
PtrlibDisassemblerT = Literal['capstone', 'objdump', 'none']
12-
13-
PtrlibIntLikeT: TypeAlias = Union[SupportsInt, SupportsIndex]
14-
15-
__all__ = ['PtrlibArchT', 'PtrlibBitsT', 'PtrlibEndiannessT',
16-
'PtrlibAssemblySyntaxT', 'PtrlibAssemblerT', 'PtrlibDisassemblerT',
17-
'PtrlibIntLikeT']

ptrlib/types/genint.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""This package provides a type representing a generator or an integer.
22
"""
33
from typing import Generator
4+
from ptrlib.types import PtrlibIntLikeT
45

56

67
class GeneratorOrInt:
@@ -20,34 +21,51 @@ class GeneratorOrInt:
2021
def __init__(self, generator: Generator[int, None, None], symbol: bytes=b''):
2122
self._generator = generator
2223
self._symbol = symbol
23-
self._first = None
24+
self._cache = []
25+
self._cursor = 0
2426

25-
@property
26-
def generator(self) -> Generator[int, None, None]:
27-
"""Get generator
27+
def __getitem__(self, index: PtrlibIntLikeT):
28+
"""Get n-th value of the generator
2829
"""
29-
return self._generator
30+
index = int(index)
31+
32+
if index >= len(self._cache):
33+
for _ in range(index + 1- len(self._cache)):
34+
self._cache.append(next(self._generator))
35+
36+
return self._cache[index]
3037

3138
def __int__(self) -> int:
32-
if self._first is None:
33-
v = next(self._generator)
34-
self._first = v
35-
return v
36-
return self._first
39+
"""Get the first value of the generator
40+
"""
41+
return self[0]
42+
43+
def __index__(self) -> int:
44+
"""Get the first value of the generator
45+
"""
46+
return int(self)
3747

3848
def __iter__(self) -> 'GeneratorOrInt':
3949
return self
4050

4151
def __next__(self) -> int:
42-
v = next(self._generator)
43-
if self._first is None:
44-
self._first = v
45-
return v
52+
"""Get next value
53+
"""
54+
self._cursor += 1
55+
56+
if self._cursor - 1 < len(self._cache):
57+
return self._cache[self._cursor - 1]
58+
59+
self._cache.append(next(self._generator))
60+
return self._cache[-1]
4661

4762
def __str__(self) -> str:
48-
if self._first is None:
63+
if len(self._cache) == 0:
4964
return f'GeneratorOrInt({repr(self._symbol)})'
50-
return f'GeneratorOrInt({repr(self._symbol)} @ {hex(self._first)})'
65+
if len(self._cache) == 1:
66+
return f'GeneratorOrInt({repr(self._symbol)} @ {hex(self._cache[0])})'
67+
return f'GeneratorOrInt({repr(self._symbol)} @ {hex(self._cache[0])} ' \
68+
f'and {len(self._cache) - 1} more known values)'
5169

5270

5371
__all__ = ['GeneratorOrInt']

0 commit comments

Comments
 (0)