Skip to content

Commit

Permalink
rearrange
Browse files Browse the repository at this point in the history
  • Loading branch information
kokifish committed Dec 25, 2024
1 parent 865a1cd commit 11d36ff
Show file tree
Hide file tree
Showing 22 changed files with 356 additions and 154 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rules_local/
*.log
isa.yaml
tmp/
temp/
tmp_extract/
tmp_hap_extract/
tmp_app_extract/
Expand Down
32 changes: 16 additions & 16 deletions examples/dis_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ohre
from ohre.abcre.dis.ControlFlow import ControlFlow
from ohre.abcre.dis.PandaReverser import PandaReverser
from ohre.abcre.dis.DisFile import DisFile
from ohre.misc import Log

Expand All @@ -13,23 +14,22 @@
parser.add_argument("dis_path", type=str, help="path to the dis file (ark_disasm-ed abc)")
arg = parser.parse_args()
dis_path = arg.dis_path
dis_file = DisFile(dis_path)
dis_file: DisFile = DisFile(dis_path)
panda_re = PandaReverser(dis_file)
print(f"> panda_re: {panda_re}")

print(f"> {dis_file}")

# print(f"\n> {dis_file.debug_deep()}")
# for method in dis_file.methods:
# print(f">> {method.debug_deep()}")

# for asmstr in dis_file.asmstrs:
# print(f">> {asmstr}")
for lit in dis_file.literals:
print(f">> {lit}")
for method in dis_file.methods:
print(f">> {method}")
for record in dis_file.records:
print(f">> {record}")
for asmstr in dis_file.asmstrs:
print(f">> {asmstr}")

# === reverse truly START
FUNC_IDX = 7
# print(f">> before ControlFlow build {dis_file.methods[FUNC_IDX].debug_deep()}")
dis_file.methods[FUNC_IDX].split_native_code_block()
# print(f">> after ControlFlow build {dis_file.methods[FUNC_IDX].debug_deep()}")
dis_file.methods[FUNC_IDX].native_code_to_TAC()
# for asm_method in dis_file.methods:
# asm_method.split_native_code_block()
# print(f">> CFed: {asm_method.debug_deep()}")
# print(f">> before ControlFlow build {dis_file.methods[FUNC_IDX]._debug_vstr()}")
panda_re.split_native_code_block(FUNC_IDX)
print(f">> after ControlFlow build {panda_re.dis_file.methods[FUNC_IDX]._debug_vstr()}")
panda_re.trans_NAC_to_TAC(method_id=FUNC_IDX)
4 changes: 2 additions & 2 deletions ohre/abcre/core/Annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, buf, pos: int):
def __str__(self):
out_elements = []
for elem in self.elements:
out_elements.append(f"{elem.debug_short()}")
out_elements.append(f"{elem._debug_str()}")
out_elements = ";".join(out_elements)

out_element_types = ""
Expand Down Expand Up @@ -56,7 +56,7 @@ def __str__(self):
name_off {hex(self.name_off)} value {hex(self.get_value())}"
return out

def debug_short(self) -> str:
def _debug_str(self) -> str:
return f"{self.name.get_str()} {hex(self.value)}"

def get_value(self, type_num):
Expand Down
4 changes: 2 additions & 2 deletions ohre/abcre/core/ClassIndex.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ def __str__(self):
out += f" {hex(v)}"
return out

def debug_deep(self):
# TODO: implement debug_deep in Class
def _debug_vstr(self):
# TODO: implement _debug_vstr in Class
pass
12 changes: 5 additions & 7 deletions ohre/abcre/dis/AsmArg.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from ohre.abcre.dis.AsmTypes import AsmTypes
from ohre.abcre.dis.DebugBase import DebugBase
from ohre.misc import Log, utils


class AsmArg:
class AsmArg(DebugBase):
def __init__(self, arg_type: AsmTypes = AsmTypes.UNKNOWN, name="", value=None, obj_ref=None):
self.type = arg_type
# name: e.g. for v0, type is VAR, name is v0(stored without truncating the prefix v)
Expand All @@ -11,9 +12,6 @@ def __init__(self, arg_type: AsmTypes = AsmTypes.UNKNOWN, name="", value=None, o
self.value = value
self.obj_ref = obj_ref

def __str__(self):
return self.debug_short()

@classmethod
def build_arg(cls, s: str):
assert isinstance(s, str) and len(s) > 0
Expand All @@ -26,14 +24,14 @@ def build_arg(cls, s: str):
def is_value_valid(self) -> bool: # TODO: for some types, value is not valid, judge it
pass

def debug_short(self):
def _debug_str(self):
out = f"{AsmTypes.get_code_name(self.type)}-{self.name}"
if (self.value is not None):
out += f"({self.value})"
if (self.obj_ref is not None):
out += f"//{self.obj_ref}"
return out

def debug_deep(self):
out = f"{self.debug_short()}"
def _debug_vstr(self):
out = f"{self._debug_str()}"
return out
75 changes: 75 additions & 0 deletions ohre/abcre/dis/AsmLiteral.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from typing import Any, Dict, Iterable, List, Tuple, Union

from ohre.abcre.dis.CODE_LV import CODE_LV
from ohre.abcre.dis.DebugBase import DebugBase
from ohre.misc import Log, utils


class AsmLiteral(DebugBase):
# fields in Class
def __init__(self, lines: List[str]):
first_line_parts = lines[0].strip().split(" ")
assert first_line_parts[0].isdigit()
self.id = int(first_line_parts[0])
self.address = int(first_line_parts[1], 16)
self.module_request_array: Dict = None
self.module_tags: List[Dict] = None
if (len(lines) == 1):
print(f"AsmLiteral todo: single line, processer is todo") # TODO: normal situation
else:
self._process_module_request_array(lines)

def _process_module_request_array(self, lines: List[str]):
s_idx = lines[0].find("{")
e_idx = lines[0].find("[")
module_tag_cnt = lines[0][s_idx + 1:e_idx].strip()
assert module_tag_cnt.isdigit()
module_tag_cnt = int(module_tag_cnt)
# module_request_array
line_all = ""
for s in lines:
line_all += s
module_request_array_start = line_all.find("MODULE_REQUEST_ARRAY: {") + len("MODULE_REQUEST_ARRAY: {")
module_request_array_end = line_all.find("};", module_request_array_start)
assert module_request_array_start > 0 and module_request_array_end > 0
module_request_array = line_all[module_request_array_start:module_request_array_end].strip()
module_request_dict = {}
if len(module_request_array):
module_requests = module_request_array.split(",")
for module_request in module_requests:
key, value = utils.find_single_kv(module_request, ":")
if (key is not None and value is not None and key.isdigit()):
key = int(key)
module_request_dict[key] = value
self.module_request_array = module_request_dict
# module_tags
module_tags_str_all = line_all[module_request_array_end:].strip()
module_tags_l = list()
if len(module_tags_str_all):
module_tags_str_all = module_tags_str_all.split(";")
for module_tag_line in module_tags_str_all:
kv_s = module_tag_line.split(",")
d = dict()
for kv in kv_s:
key, value = utils.find_single_kv(kv.strip(), ":")
if (key is not None and value is not None):
d[key] = value
if (len(d)):
module_tags_l.append(d)
self.module_tags = module_tags_l

def _debug_str(self) -> str:
out = f"AsmLiteral: {self.id} {hex(self.address)}"
if (self.module_request_array is not None):
out += f" module_request_array({len(self.module_request_array)})"
if (self.module_tags is not None):
out += f" module_tags({len(self.module_tags)})"
return out

def _debug_vstr(self) -> str:
out = f"AsmLiteral: {self.id} {hex(self.address)}"
if (self.module_request_array is not None):
out += f" module_request_array({len(self.module_request_array)}) {self.module_request_array}"
if (self.module_tags is not None):
out += f" module_tags({len(self.module_tags)}) {self.module_tags}"
return out
41 changes: 19 additions & 22 deletions ohre/abcre/dis/AsmMethod.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@
from ohre.abcre.dis.AsmTypes import AsmTypes
from ohre.abcre.dis.CODE_LV import CODE_LV
from ohre.abcre.dis.CodeBlocks import CodeBlocks
from ohre.abcre.dis.NativeToTAC import NativeToTAC
from ohre.abcre.dis.ControlFlow import ControlFlow
from ohre.misc import Log, utils
from ohre.abcre.dis.DebugBase import DebugBase


class AsmMethod:
class AsmMethod(DebugBase):
# fields in Class
def __init__(self, slotNumberIdx, lines: List[str]):
assert len(lines) >= 2
self.slotNumberIdx: int = slotNumberIdx
self.return_type = "None"
self.file_name: str = ""
self.class_func_name: str = ""
self.class_name: str = ""
self.func_name: str = ""
self.func_type: str = ""
self.args: List = list()
self.code_blocks: CodeBlocks | None = None
self.code_blocks: Union[CodeBlocks, None] = None
insts = self._process_method(lines)
self.code_blocks = CodeBlocks(insts)

Expand All @@ -27,25 +29,23 @@ def split_native_code_block(self):
self.code_blocks = ControlFlow.split_native_code_block(self.code_blocks)
self.code_blocks.set_level(CODE_LV.NATIVE_BLOCK_SPLITED)

def native_code_to_TAC(self):
assert self.code_blocks.level == CODE_LV.NATIVE_BLOCK_SPLITED
self.code_blocks = NativeToTAC.native_code_to_TAC(self.code_blocks)
self.code_blocks.set_level(CODE_LV.TAC)

def _process_1st_line(self, line: str):
parts = line.split(" ")
assert parts[0] == ".function"
self.return_type = parts[1].strip()
file_func_name = parts[2].split("(")[0]
num = file_func_name.find(".ets")
if (not num > 0):
num = file_func_name.find(".src")
if (num > 0 and num < len(file_func_name) - 5):
self.file_name = file_func_name[:num + 4]
self.class_func_name = file_func_name[num + 4 + 1:]
file_postfix_idx = file_func_name.find(".ets")
if (not file_postfix_idx > 0):
file_postfix_idx = file_func_name.find(".src")
if (file_postfix_idx > 0 and file_postfix_idx < len(file_func_name) - 5):
self.file_name = file_func_name[:file_postfix_idx + 4]
self.class_func_name = file_func_name[file_postfix_idx + 4 + 1:]
else:
self.file_name = file_func_name
self.class_func_name = file_func_name
if (self.file_name.startswith("&")):
self.file_name = self.file_name[1:]
# reverse find: something like <static>
i = len(parts) - 1
while (i >= 0):
if (parts[i].startswith("<") and parts[i].endswith(">") and len(parts[i]) >= 3):
Expand Down Expand Up @@ -91,20 +91,17 @@ def _process_common_inst(self, line: str) -> List[str]:
idx += 1
while (idx < len(line)):
start_idx = idx
idx = utils.find_next_delimiter(line, start_idx)
idx = utils.find_next_delimiter_single_line(line, start_idx)
ret.append(line[start_idx: idx].strip())
idx = idx + 1
return ret

def __str__(self):
return self.debug_short()

def debug_short(self) -> str:
def _debug_str(self) -> str:
out = f"AsmMethod: {self.slotNumberIdx} {self.func_type} {self.class_func_name} \
ret {self.return_type} file: {self.file_name}\n\
args({len(self.args)}) {self.args} code_blocks({len(self.code_blocks)})"
\targs({len(self.args)}) {self.args} code_blocks({len(self.code_blocks)})"
return out

def debug_deep(self) -> str:
out = f"{self.debug_short()}\n{self.code_blocks.debug_deep()}"
def _debug_vstr(self) -> str:
out = f"{self._debug_str()}\n{self.code_blocks._debug_vstr()}"
return out
33 changes: 27 additions & 6 deletions ohre/abcre/dis/AsmRecord.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
from typing import Any, Dict, Iterable, List, Tuple, Union

from ohre.abcre.dis.AsmTypes import AsmTypes
from ohre.abcre.dis.DebugBase import DebugBase
from ohre.misc import Log


class AsmRecord:
class AsmRecord(DebugBase):
# fields in Class
def __init__(self, lines: List[str]):
self.file_class_name: str = ""
self.file_name: str = ""
self.class_name: str = ""
self.fields: Dict[Tuple[str, Any]] = dict() # k: field name; v: (type, value)
for line in lines:
line = line.strip()
if ("}" in line):
return
break
elif ("{" in line and ".record" in line):
parts = line.split(" ")
self.class_name = parts[1].split("@")[0]
self.file_class_name = parts[1].split("@")[0].strip()
elif ("=" in line):
parts = line.split("=")
ty, name = parts[0].split(" ")[0].strip(), parts[0].split(" ")[1].strip()
Expand All @@ -27,9 +30,27 @@ def __init__(self, lines: List[str]):
self.fields[name] = (ty, value)
else:
Log.warn(f"invalid line in AsmRecord: {line},\nlines: {lines}")
# file+class name like: &entry.src.main.ets.entryability.EntryAbility&
if (self.file_class_name.startswith("&")):
self.file_class_name = self.file_class_name[1:]
if (self.file_class_name.endswith("&")):
self.file_class_name = self.file_class_name[:-1]
file_postfix_idx = self.file_class_name.find(".ets")
if (not file_postfix_idx > 0):
file_postfix_idx = self.file_class_name.find(".src")
if (file_postfix_idx > 0):
self.file_name = self.file_class_name[:file_postfix_idx + len(".ets")].strip()
self.class_name = self.file_class_name[file_postfix_idx + len(".ets") + 1:].strip()

def debug_deep(self):
out = f"AsmRecord {self.class_name}: "
def _debug_str(self):
out = f"AsmRecord: {self.file_class_name} {self.file_name} \
class_name({len(self.class_name)}) {self.class_name}: "
for field_name, (ty, value) in self.fields.items():
out += f"{field_name}({ty}) {value};"
if (isinstance(value, int)):
out += f"{field_name}({ty}) {hex(value)}; "
else:
out += f"{field_name}({ty}) {value}; "
return out

def _debug_vstr(self):
return self._debug_str()
11 changes: 6 additions & 5 deletions ohre/abcre/dis/AsmString.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from typing import Any, Dict, Iterable, List, Tuple, Union

from ohre.abcre.dis.AsmTypes import AsmTypes
from ohre.abcre.dis.DebugBase import DebugBase
from ohre.misc import Log


class AsmString:
class AsmString(DebugBase):
def __init__(self, line: str):
idx = line.find(", ")
assert idx > 2 and idx < len(line) - 2
Expand All @@ -13,9 +14,9 @@ def __init__(self, line: str):
idx2 = remain_line.find(":")
self.name_value = remain_line[idx2 + 1:]

def __str__(self):
return self.debug_deep()

def debug_deep(self):
def _debug_str(self):
out = f"AsmString({hex(self.offset)}) {len(self.name_value)} {self.name_value}"
return out

def _debug_vstr(self):
return self._debug_str()
Loading

0 comments on commit 11d36ff

Please sign in to comment.