Skip to content

Commit

Permalink
add some tac builder, fix asm str reading bug at multi-lines, multi t…
Browse files Browse the repository at this point in the history
…hreading

* support neg, label

* support ldfalse

* support eq

* support callargsx, ldtrue; fix

* fix asmstr bug, add some tac builder, multi thread
  • Loading branch information
kokifish authored Dec 30, 2024
1 parent 377d020 commit a73e948
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 107 deletions.
12 changes: 9 additions & 3 deletions examples/dis_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Log.init_log("abcre", ".")
ohre.set_log_level("info")
ohre.set_log_print(True)
Log.info(f"START {__file__}")
parser = argparse.ArgumentParser()
parser.add_argument("dis_path", type=str, help="path to the dis file (ark_disasm-ed abc)")
arg = parser.parse_args()
Expand All @@ -28,8 +29,13 @@
print(f">> {asmstr}")

# === reverse truly START
FUNC_IDX = 1
# print(f">> before ControlFlow build {dis_file.methods[FUNC_IDX]._debug_vstr()}")
FUNC_IDX = 5 # 5: onWindowStageCreate, call loadContent and pass a mothod as para; 7: mothod that used as para
# print(f">> before CF {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()}")
print(f">> CF built {panda_re.dis_file.methods[FUNC_IDX]._debug_vstr()}")
panda_re.trans_NAC_to_TAC(method_id=FUNC_IDX)

# for idx in range(panda_re.method_len()):
# panda_re.split_native_code_block(idx)
# print(f">> [{idx}/{panda_re.method_len()}] CF built {panda_re.dis_file.methods[idx]._debug_vstr()}")
# panda_re.trans_NAC_to_TAC(method_id=idx)
10 changes: 8 additions & 2 deletions ohre/abcre/dis/AsmArg.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
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, utils


class AsmArg(DebugBase):
def __init__(self, arg_type: AsmTypes = AsmTypes.UNKNOWN, name: str = "", value=None, obj_ref=None):
def __init__(self, arg_type: AsmTypes = AsmTypes.UNKNOWN,
name: str = "", value=None, obj_ref=None, paras_len: int = None):
self.type = arg_type
# name: e.g. for v0, type is VAR, name is v0(stored without truncating the prefix v)
self.name: str = name
# value: may be set in the subsequent analysis
self.value = value
self.obj_ref = obj_ref
self.paras_len: Union[int, None] = paras_len # for method object, store paras len here

@property
def len(self):
Expand All @@ -20,7 +24,7 @@ def __len__(self) -> int:
return self.len

@classmethod
def build_arg(cls, s: str):
def build_arg(cls, s: str): # return VAR v0 v1... or ARG a0 a1...
assert isinstance(s, str) and len(s) > 0
if (s.startswith("v")):
return AsmArg(AsmTypes.VAR, s)
Expand All @@ -45,6 +49,8 @@ def _debug_str(self):
out += f"({self.value})"
if (self.obj_ref is not None):
out += f"//{self.obj_ref}"
if (self.paras_len is not None):
out += f"(paras_len={self.paras_len})"
return out

def _debug_vstr(self):
Expand Down
25 changes: 15 additions & 10 deletions ohre/abcre/dis/AsmLiteral.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,37 @@ def __init__(self, lines: List[str]):
self.address = int(first_line_parts[1], 16)
self.module_request_array: Dict = None
self.module_tags: List[Dict] = None
if (len(lines) == 1):
try:
for s in lines:
idx = s.find("MODULE_REQUEST_ARRAY: {")
if (idx >= 0):
self._process_module_request_array(lines)
return
self._process_normal_literal(lines)
else:
self._process_module_request_array(lines)
except Exception as e:
Log.error(f"init ERROR in AsmLiteral, e {e}, lines {lines}")

def _process_normal_literal(self, lines: List[str]):
literal_content = ' '.join(lines)
s_idx = literal_content.find("{")+1
s_idx = literal_content.find("{") + 1
e_idx = literal_content.find("[")
element_amount_str = literal_content[s_idx:e_idx].strip()
assert element_amount_str.isdigit(), f"Expected a digit for element amount, got {element_amount_str}"
element_amount = int(element_amount_str)

s_idx = literal_content.find("[")+1
s_idx = literal_content.find("[") + 1
e_idx = literal_content.find("]")
element_content = literal_content[s_idx:e_idx]
array_split_list = [x.strip() for x in element_content.strip().split(',') if len(x) > 0]

method_dict = {}
if 'method' in element_content and 'method_affiliate' in element_content:
cnt = 0
while cnt < len(array_split_list):
if 'string' in array_split_list[cnt]:
method_string = array_split_list[cnt].split(':')[1].strip()[1:-1]
method_name = array_split_list[cnt+1].split(':')[1].strip()
method_aff = array_split_list[cnt+2].split(':')[1].strip()
method_name = array_split_list[cnt + 1].split(':')[1].strip()
method_aff = array_split_list[cnt + 2].split(':')[1].strip()
method_dict[method_string] = {'method': method_name, 'method_affiliate': method_aff}
cnt += 3
else:
Expand All @@ -50,7 +55,7 @@ def _process_normal_literal(self, lines: List[str]):
cnt = 0
while cnt < len(array_split_list):
variable_string = array_split_list[cnt].split(':')[1].strip()[1:-1]
variable_value = array_split_list[cnt+1]
variable_value = array_split_list[cnt + 1]
if 'null_value' in variable_value:
variable_value = 'null_value'
else:
Expand Down Expand Up @@ -93,7 +98,7 @@ def _process_module_request_array(self, lines: List[str]):
kv_s = module_tag_line.split(",")
d = dict()
for kv in kv_s:
key, value = utils.find_single_kv(kv.strip(), ":")
key, value = utils.find_single_kv(kv, ":")
if (key is not None and value is not None):
d[key] = value
if (len(d)):
Expand Down
16 changes: 9 additions & 7 deletions ohre/abcre/dis/AsmMethod.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ def __init__(self, slotNumberIdx, lines: List[str]):
self.method_name: str = "" # TODO: split it accurately
self.method_type: str = ""
self.args: List = list()
self._process_method_1st_line(lines[0].strip())

self.code_blocks: Union[CodeBlocks, None] = None
self.code_blocks = CodeBlocks(self._process_method(lines))
self.code_blocks = CodeBlocks(self._process_method_inst(lines))

# for nac tac analysis
self.cur_module: str = ""

def _process_1st_line(self, line: str):
def _split_class_method_name(self, record_names):
pass # TODO: use record_names to split

def _process_method_1st_line(self, line: str):
parts = line.split(" ")
assert parts[0] == ".function"
self.return_type = parts[1].strip()
Expand Down Expand Up @@ -59,9 +63,8 @@ def _process_1st_line(self, line: str):
ty, name = arg_pair.strip().split(" ")
self.args.append((ty, name))

def _process_method(self, lines: List[str]) -> List[List[str]]:
def _process_method_inst(self, lines: List[str]) -> List[List[str]]:
insts = list()
self._process_1st_line(lines[0].strip())
for line in lines[1:]:
line = line.strip()
if (line.endswith(":")):
Expand Down Expand Up @@ -95,9 +98,8 @@ def _process_common_inst(self, line: str) -> List[str]:
return ret

def _debug_str(self) -> str:
out = f"AsmMethod: {self.slotNumberIdx} {self.method_type} {self.class_method_name} \
ret {self.return_type} file: {self.file_name}\n\
\targs({len(self.args)}) {self.args} code_blocks({len(self.code_blocks)})"
out = f"AsmMethod: {self.slotNumberIdx} {self.class_method_name} {self.method_type} \
ret {self.return_type} [{self.file_name}] args({len(self.args)}) {self.args} cbs({len(self.code_blocks)})"
return out

def _debug_vstr(self) -> str:
Expand Down
14 changes: 10 additions & 4 deletions ohre/abcre/dis/AsmString.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@


class AsmString(DebugBase):
def __init__(self, line: str):
def __init__(self, lines: List[str]):
line = ""
for s in lines:
line += s
line = line.strip()
assert line[0] == "[" and line[-1] == "]"
line = line[1:-1]
idx = line.find(", ")
assert idx > 2 and idx < len(line) - 2
self.offset = int(line[:idx].split(":")[1], 16)
remain_line = line[idx + 2:]
idx2 = remain_line.find(":")
self.name_value = remain_line[idx2 + 1:]
line_remain = line[idx + 2:]
idx2 = line_remain.find(":")
self.name_value = line_remain[idx2 + 1:]

def _debug_str(self):
out = f"AsmString({hex(self.offset)}) {len(self.name_value)} {self.name_value}"
Expand Down
1 change: 1 addition & 0 deletions ohre/abcre/dis/AsmTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class AsmTypes(BaseEnum):
LABEL = "label" # AsmArg: value not valid
STR = "str"
MODULE = "module"
METHOD_OBJ = "method_obj"
UNDEFINED = "undefined"
UNKNOWN = "unknown" # default value in this proj

Expand Down
Loading

0 comments on commit a73e948

Please sign in to comment.