-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #174 from Hypnootika/master
Feat: stub.py, a stub_generator. Fix: LM_IsProcessAlive.md
- Loading branch information
Showing
4 changed files
with
232 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ bindings/python/build/ | |
bindings/python/src/libmem.* | ||
docs/examples/rust/target/ | ||
clang-format | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
from typing import * | ||
|
||
|
||
lm_address_t = TypeVar('lm_address_t', bound=int) | ||
lm_size_t = TypeVar('lm_size_t', bound=int) | ||
lm_pid_t = TypeVar('lm_pid_t', bound=int) | ||
lm_tid_t = TypeVar('lm_tid_t', bound=int) | ||
lm_prot_t = TypeVar('lm_prot_t', bound=int) | ||
lm_inst_t = TypeVar('lm_inst_t', bound=int) | ||
|
||
|
||
LM_PATH_MAX = 260 | ||
LM_CHARSET_UC = 1 | ||
LM_PROT_NONE = 0 | ||
LM_PROT_X = (1 << 0) | ||
LM_PROT_R = (1 << 1) | ||
LM_PROT_W = (1 << 2) | ||
LM_PROT_XR = LM_PROT_X | LM_PROT_R | ||
LM_PROT_XW = LM_PROT_X | LM_PROT_W | ||
LM_PROT_RW = LM_PROT_R | LM_PROT_W | ||
LM_PROT_XRW = LM_PROT_X | LM_PROT_R | LM_PROT_W | ||
|
||
class lm_module_t: | ||
base: lm_address_t | ||
end: lm_address_t | ||
size: lm_size_t | ||
path: str | ||
name: str | ||
|
||
class lm_process_t: | ||
pid: lm_pid_t | ||
ppid: lm_pid_t | ||
bits: lm_size_t | ||
start_time: lm_size_t | ||
path: str | ||
name: str | ||
|
||
class lm_page_t: | ||
base: lm_address_t | ||
end: lm_address_t | ||
size: lm_size_t | ||
prot: lm_prot_t | ||
|
||
class lm_thread_t: | ||
tid: lm_tid_t | ||
|
||
class lm_symbol_t: | ||
addr: lm_address_t | ||
name: str | ||
|
||
def LM_AllocMemory(size : int, prot : int) -> lm_address_t: ... | ||
def LM_AllocMemoryEx(pproc : lm_process_t, size : int, prot : int) -> lm_address_t: ... | ||
def LM_Assemble(code : str) -> lm_inst_t: ... | ||
def LM_AssembleEx(code : str, bits : int, runtime_addr : int) -> bytearray: ... | ||
def LM_CodeLength(code : int, minlength : int) -> int: ... | ||
def LM_CodeLengthEx(pproc : lm_process_t, code : int, minlength : int) -> int: ... | ||
def LM_DataScan(data : bytearray, addr : int, scansize : int) -> lm_address_t: ... | ||
def LM_DataScanEx(pproc : lm_process_t, data : bytearray, addr : int, scansize : int) -> lm_address_t: ... | ||
def LM_DemangleSymbol(symbol : str) -> str: ... | ||
def LM_Disassemble(code : int) -> lm_inst_t: ... | ||
def LM_DisassembleEx(code : int, bits : int, size : int, count : int, runtime_addr : int) -> List[lm_inst_t]: ... | ||
def LM_EnumModules() -> List[lm_module_t]: ... | ||
def LM_EnumModulesEx(pproc : lm_process_t) -> List[lm_module_t]: ... | ||
def LM_EnumPages() -> List[lm_page_t]: ... | ||
def LM_EnumProcesses() -> List[lm_process_t]: ... | ||
def LM_EnumSymbols(pmod : lm_module_t) -> List[lm_symbol_t]: ... | ||
def LM_EnumSymbolsDemangled(pmod : lm_module_t) -> List[lm_symbol_t]: ... | ||
def LM_EnumThreads() -> List[lm_thread_t]: ... | ||
def LM_EnumThreadsEx(pproc : lm_process_t) -> List[lm_thread_t]: ... | ||
def LM_FindModule(name : str) -> lm_module_t: ... | ||
def LM_FindModuleEx(pproc : lm_process_t, name : str) -> lm_module_t: ... | ||
def LM_FindProcess(procstr : str) -> lm_process_t: ... | ||
def LM_FindSymbolAddress(pmod : lm_module_t, name : str) -> int: ... | ||
def LM_FindSymbolAddressDemangled(pmod : lm_module_t, name : str) -> int: ... | ||
def LM_FreeMemory(alloc : int, size : int) -> bool: ... | ||
def LM_FreeMemoryEx(pproc : lm_process_t, alloc : int, size : int) -> bool: ... | ||
def LM_GetPage(addr : int) -> lm_page_t: ... | ||
def LM_GetPageEx(pproc : lm_process_t, addr : int) -> lm_page_t: ... | ||
def LM_GetProcess() -> lm_process_t: ... | ||
def LM_GetProcessEx(pid : lm_pid_t) -> lm_process_t: ... | ||
def LM_GetThread() -> lm_thread_t: ... | ||
def LM_GetThreadEx(pproc : lm_process_t) -> lm_thread_t: ... | ||
def LM_GetThreadProcess(pthr : lm_thread_t) -> lm_process_t: ... | ||
def LM_HookCode(from: lm_address_t, to : lm_address_t) -> lm_address_t: ... | ||
def LM_HookCodeEx(pproc : lm_process_t, from: lm_address_t, to : lm_address_t) -> lm_address_t: ... | ||
def LM_IsProcessAlive(pproc : lm_process_t) -> bool: ... | ||
def LM_LoadModule(modpath : str) -> lm_module_t: ... | ||
def LM_LoadModuleEx(pproc : lm_process_t, modpath : str) -> lm_module_t: ... | ||
def LM_PatternScan(pattern : bytearray, mask : str, addr : lm_address_t, scansize : int) -> lm_address_t: ... | ||
def LM_PatternScanEx(pproc : lm_process_t, pattern : bytearray, mask : str, addr : lm_address_t, scansize : int) -> lm_address_t: ... | ||
def LM_ProtMemory(addr : int, size : int, prot : lm_prot_t) -> lm_prot_t: ... | ||
def LM_ProtMemoryEx(pproc : lm_process_t, addr : lm_address_t, size : int, prot : lm_prot_t) -> lm_prot_t: ... | ||
def LM_ReadMemory(src : lm_address_t, size : int) -> bytearray: ... | ||
def LM_ReadMemoryEx(pproc : lm_process_t, src : lm_address_t, size : int) -> bytearray: ... | ||
def LM_SetMemory(dst : lm_address_t, byte : bytes, size : int) -> bool: ... | ||
def LM_SetMemoryEx(pproc : lm_process_t, dst : lm_address_t, byte : bytes, size : int) -> bool: ... | ||
def LM_SigScan(sig : str, addr : lm_address_t, scansize : int) -> lm_address_t: ... | ||
def LM_SigScanEx(pproc : lm_process_t, sig : str, addr : lm_address_t, scansize : int) -> lm_address_t: ... | ||
def LM_UnhookCode(from: lm_address_t, trampoline : (lm_address_t, int)) -> bool: ... | ||
def LM_UnhookCodeEx(pproc : lm_process_t, from: lm_address_t, trampoline : (int, int)) -> bool: ... | ||
def LM_UnloadModule(pmod : lm_module_t) -> bool: ... | ||
def LM_UnloadModuleEx(pproc : lm_process_t, pmod : lm_module_t) -> bool: ... | ||
def LM_WriteMemory(dst : int, src : bytearray) -> bool: ... | ||
def LM_WriteMemoryEx(pproc : lm_process_t, dst : int, src : bytearray) -> bool: ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
# TODO - New stub generation method: | ||
# - Make the documentation declaration be exactly like how it would be on `.pyi` | ||
# - Get the lines between the two ``` for each API in the documentation and place them directly in the `.pyi` | ||
|
||
import os | ||
import re | ||
|
||
text = """from typing import * | ||
lm_address_t = TypeVar('lm_address_t', bound=int) | ||
lm_size_t = TypeVar('lm_size_t', bound=int) | ||
lm_pid_t = TypeVar('lm_pid_t', bound=int) | ||
lm_tid_t = TypeVar('lm_tid_t', bound=int) | ||
lm_prot_t = TypeVar('lm_prot_t', bound=int) | ||
lm_inst_t = TypeVar('lm_inst_t', bound=int) | ||
LM_PATH_MAX = 260 | ||
LM_CHARSET_UC = 1 | ||
LM_PROT_NONE = 0 | ||
LM_PROT_X = (1 << 0) | ||
LM_PROT_R = (1 << 1) | ||
LM_PROT_W = (1 << 2) | ||
LM_PROT_XR = LM_PROT_X | LM_PROT_R | ||
LM_PROT_XW = LM_PROT_X | LM_PROT_W | ||
LM_PROT_RW = LM_PROT_R | LM_PROT_W | ||
LM_PROT_XRW = LM_PROT_X | LM_PROT_R | LM_PROT_W | ||
class lm_module_t: | ||
base: lm_address_t | ||
end: lm_address_t | ||
size: lm_size_t | ||
path: str | ||
name: str | ||
class lm_process_t: | ||
pid: lm_pid_t | ||
ppid: lm_pid_t | ||
bits: lm_size_t | ||
start_time: lm_size_t | ||
path: str | ||
name: str | ||
class lm_page_t: | ||
base: lm_address_t | ||
end: lm_address_t | ||
size: lm_size_t | ||
prot: lm_prot_t | ||
class lm_thread_t: | ||
tid: lm_tid_t | ||
class lm_symbol_t: | ||
addr: lm_address_t | ||
name: str | ||
""" | ||
|
||
doc_path = "../../../docs/api/python" | ||
files = os.listdir(doc_path) | ||
files = [f for f in files if f.endswith(".md")] | ||
|
||
|
||
def extract_return_types(file_name): | ||
file_path = os.path.join(doc_path, file_name) | ||
with open(file_path, 'r', encoding='utf-8') as file: | ||
lines = file.readlines() | ||
|
||
for i, line in enumerate(lines): | ||
if line.strip() == "# Return Value": | ||
type_line = lines[i + 2].strip() | ||
all_types = re.findall(r'`([^`]+)`', type_line) | ||
extracted_types = [] | ||
for type_str in all_types: | ||
if ' of ' in type_str: | ||
container, inner_type = type_str.split(' of ') | ||
extracted_types.append(container.strip()) | ||
extracted_types.append(inner_type.strip()) | ||
else: | ||
extracted_types.append(type_str.strip()) | ||
return ', '.join(extracted_types) | ||
|
||
return 'Any' | ||
|
||
|
||
def get_function_def(files): | ||
function_defs = [] | ||
for f in files: | ||
data = open(os.path.join(doc_path, f)).readlines() | ||
for i, line in enumerate(data): | ||
if i == 3 and line.startswith("def"): | ||
function_defs.append((f, line.strip())) | ||
return function_defs | ||
|
||
|
||
def write_stub(): | ||
with open("libmem.pyi", "w") as f: | ||
f.write(text) | ||
for file_name, defi in get_function_def(files): | ||
return_type = extract_return_types(file_name).split(",")[0] | ||
if return_type == "Any" and "Module" in defi: | ||
return_type = "List[lm_module_t]" | ||
if return_type == "Any" and "Process" in defi: | ||
return_type = "List[lm_process_t]" | ||
if return_type == "Any" and "Page" in defi: | ||
return_type = "List[lm_page_t]" | ||
if return_type == "Any" and "Thread" in defi: | ||
return_type = "List[lm_thread_t]" | ||
if return_type == "Any" and "Symbol" in defi: | ||
return_type = "List[lm_symbol_t]" | ||
if return_type == "(trampoline_address": | ||
return_type = "int" | ||
if return_type == "true" or return_type == "false": | ||
return_type = "bool" | ||
if return_type == "": | ||
continue | ||
if "from :" in defi: | ||
f.write(f"{defi.replace('from :', '_from:')} -> {return_type}: ...\n") | ||
continue | ||
|
||
f.write(f"{defi} -> {return_type}: ...\n") | ||
|
||
|
||
if __name__ == '__main__': | ||
write_stub() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters