def __extract_member(self, cexpr, obj, offset, parents, parents_type): parent = parents[0] if parents_type[0] == 'cast': default_tinfo = parent.type cexpr = parent del parents_type[0] del parents[0] else: default_tinfo = const.PX_WORD_TINFO if parents_type[0] in ('idx', 'ptr'): if parents_type[1] == 'cast': default_tinfo = parents[1].type cexpr = parents[0] del parents_type[0] del parents[0] else: default_tinfo = self.__deref_tinfo(default_tinfo) if parents_type[1] == 'asg': if parents[1].x == parents[0]: # *(TYPE *)(var + x) = ??? obj_ea = self.__extract_obj_ea(parents[1].y) return self._get_member(offset, cexpr, obj, parents[1].y.type, obj_ea) return self._get_member(offset, cexpr, obj, parents[1].x.type) elif parents_type[1] == 'call': if parents[1].x == parents[0]: # ((type (__some_call *)(..., ..., ...)var[idx])(..., ..., ...) # ((type (__some_call *)(..., ..., ...)*(TYPE *)(var + x))(..., ..., ...) return self._get_member(offset, cexpr, obj, parents[0].type) _, tinfo = helper.get_func_argument_info( parents[1], parents[0]) if tinfo is None: tinfo = const.PCHAR_TINFO return self._get_member(offset, cexpr, obj, tinfo) return self._get_member(offset, cexpr, obj, default_tinfo) elif parents_type[0] == 'call': # call(..., (TYPE)(var + x), ...) tinfo = self._parse_call(parents[0], cexpr, offset) return self._get_member(offset, cexpr, obj, tinfo) elif parents_type[0] == 'asg': if parents[0].y == cexpr: # other_obj = (TYPE) (var + offset) self._parse_left_assignee(parents[1].x, offset) return self._get_member(offset, cexpr, obj, self.__deref_tinfo(default_tinfo))
def _parse_call(self, call_cexpr, arg_cexpr, offset): _, tinfo = helper.get_func_argument_info(call_cexpr, arg_cexpr) if tinfo: return self.__deref_tinfo(tinfo) # TODO: Find example with UTF-16 strings return const.CHAR_TINFO