Shofel2_T124_python/venv/lib/python3.10/site-packages/qiling/os/stats.py

151 lines
3.9 KiB
Python
Raw Permalink Normal View History

2024-05-25 16:45:07 +00:00
#!/usr/bin/env python3
#
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import json
from typing import Any, List, MutableMapping, Mapping, Optional, Set
class QlOsStats:
"""Record basic OS statistics, such as API calls and strings.
"""
def __init__(self):
self.syscalls: MutableMapping[str, List] = {}
self.strings: MutableMapping[str, Set] = {}
self.position = 0
def clear(self):
"""Reset collected stats.
"""
self.syscalls.clear()
self.strings.clear()
self.position = 0
@staticmethod
def _banner(caption: str) -> List[str]:
bar = '-' * 24
return ['', caption, bar]
def summary(self) -> List[str]:
ret = []
ret.extend(QlOsStats._banner('syscalls called'))
for key, values in self.syscalls.items():
ret.append(f'{key}:')
ret.extend(f' {json.dumps(value):s}' for value in values)
ret.extend(QlOsStats._banner('strings ocurrences'))
for key, values in self.strings.items():
ret.append(f'{key}: {", ".join(str(word) for word in values)}')
return ret
def log_api_call(self, address: int, name: str, params: Mapping, retval: Any, retaddr: int) -> None:
"""Record API calls along with their details.
Args:
address : location of the calling instruction
name : api function name
params : mapping of the parameters name to their effective values
retval : value returned by the api function
retaddr : address to which the api function returned
"""
if name.startswith('hook_'):
name = name[5:]
self.syscalls.setdefault(name, []).append({
'params' : params,
'retval' : retval,
'address' : address,
'retaddr' : retaddr,
'position' : self.position
})
self.position += 1
def log_string(self, s: str) -> None:
"""Record strings appearance as they are encountered during emulation.
Args:
s : string to record
"""
for token in s.split(' '):
self.strings.setdefault(token, set()).add(self.position)
class QlWinStats(QlOsStats):
"""OS statistics object for Windows OS. Includes registry access stats.
"""
def __init__(self):
super().__init__()
self.registry: MutableMapping[str, List] = {}
def clear(self):
super().clear()
self.registry.clear()
def summary(self) -> List[str]:
ret = super().summary()
ret.extend(QlOsStats._banner('registry keys accessed'))
for key, values in self.registry.items():
ret.append(f'{key}:')
ret.extend(f' {json.dumps(value):s}' for value in values)
return ret
def log_reg_access(self, key: str, item: Optional[str], type: Optional[int], value: Any) -> None:
"""Record registry access.
Args:
key : accessed key name
name : sub item name (if provided)
type : sub item type (if provided)
value : value set to item, in case of a registry modification
"""
self.registry.setdefault(key, []).append({
'item' : item,
'type' : type,
'value' : value,
'position' : self.position
})
class QlOsNullStats(QlOsStats):
"""Nullified OS statistics object.
"""
def clear(self):
pass
def summary(self) -> List[str]:
return []
def log_api_call(self, address: int, name: str, params: Mapping, retval: Any, retaddr: int) -> None:
pass
def log_string(self, s: str) -> None:
pass
class QlWinNullStats(QlOsNullStats):
"""Nullified Windows statistics object.
"""
def log_reg_access(self, key: str, item: Optional[str], type: Optional[int], value: Any) -> None:
pass