9 def __init__(self
, guest
, host
, logger
=None, table
=None):
11 path
= pathlib
.Path(inspect
.getfile(self
.__class
__))
12 path
= (path
.parent
/ "syscalls.json")
13 with
open(path
, "r", encoding
="UTF-8") as stream
:
14 table
= json
.load(stream
)
15 if not isinstance(table
, dict):
16 raise ValueError("dict instance expected")
17 if "sysnums" not in table
or "sysargs" not in table
:
18 raise ValueError("sysnums and sysargs keys expected")
21 logger
= lambda *args
, **kwargs
: None
24 yield from sysnums
["x86-32"]["i386"].items()
27 yield from sysnums
["x86-64"]["common"].items()
28 yield from sysnums
["x86-64"]["64"].items()
31 yield from sysnums
["ppc"]["nospu"].items()
32 yield from sysnums
["ppc"]["common"].items()
33 yield from sysnums
["ppc"]["32"].items()
36 yield from sysnums
["ppc"]["nospu"].items()
37 yield from sysnums
["ppc"]["common"].items()
38 yield from sysnums
["ppc"]["64"].items()
46 sysnums
= table
["sysnums"]
47 sysargs
= table
["sysargs"]
49 self
.__guest
= dict(arch
[guest
](sysnums
))
50 self
.__host
= dict(arch
[host
](sysnums
))
51 self
.__parameters
= sysargs
52 self
.__logger
= logger
53 self
.__libc
= ctypes
.CDLL(None)
55 return super().__init
__()
57 def __getattr__(self
, identifier
):
58 return functools
.partial(self
.__call
__, identifier
)
60 def __call__(self
, identifier
, *arguments
):
61 if isinstance(identifier
, int):
62 identifier
= str(identifier
)
63 if identifier
not in self
.__guest
:
64 raise KeyError(identifier
)
65 entry
= self
.__guest
[identifier
][1][0]
66 identifier
= self
.__guest
[identifier
][0]
68 if not isinstance(identifier
, str):
69 raise ValueError(identifier
)
71 if not entry
.startswith(("compat_sys_", "sys_")):
72 entry
= f
"sys_{entry}"
74 if ((identifier
not in self
.__guest
) or
75 (identifier
not in self
.__host
)):
76 raise KeyError(identifier
)
78 parameters
= tuple(self
.__parameters
[entry
].items())
79 if len(arguments
) != len(parameters
):
80 raise ValueError("conflict between arguments and parameters")
82 guest
= int(self
.__guest
[identifier
])
83 host
= int(self
.__host
[identifier
])
84 self
.__logger
(f
"{identifier} {guest} => {host}")
85 for index
in range(len(arguments
)):
86 value
= arguments
[index
]
87 if not isinstance(value
, int):
88 raise ValueError("integer argument expected")
89 name
= parameters
[index
][0]
90 ctype
= parameters
[index
][1]
91 self
.__logger
(f
" 0x{value:016x} {name} ({ctype})")
93 syscall
= self
.__libc
.syscall
94 syscall
.restype
= ctypes
.c_long
95 syscall
.argtypes
= ([ctypes
.c_long
] * len(arguments
))
97 return int(syscall(ctypes
.c_ulong(host
)))