(self, assembly, address=idc.BADADDR)
| 247 | ### resolve IDA names from input asm code |
| 248 | # todo: a better syntax parser for all archs |
| 249 | def ida_resolve(self, assembly, address=idc.BADADDR): |
| 250 | def _resolve(_op, ignore_kw=True): |
| 251 | names = re.findall(r"\b[a-z0-9_:\.]+\b", _op, re.I) |
| 252 | |
| 253 | # try to resolve all names |
| 254 | for name in names: |
| 255 | # ignore known keywords |
| 256 | if ignore_kw and name in ('byte', 'near', 'short', 'word', 'dword', 'ptr', 'offset'): |
| 257 | continue |
| 258 | |
| 259 | sym = name |
| 260 | |
| 261 | # split segment reg |
| 262 | parts = name.partition(':') |
| 263 | if parts[2] != '': |
| 264 | sym = parts[2] |
| 265 | |
| 266 | (t, v) = idaapi.get_name_value(address, sym) |
| 267 | |
| 268 | # skip if name doesn't exist or segment / segment registers |
| 269 | if t in (idaapi.NT_SEG, idaapi.NT_NONE): |
| 270 | continue |
| 271 | |
| 272 | _op = _op.replace(sym, '0x{0:X}'.format(v)) |
| 273 | |
| 274 | return _op |
| 275 | |
| 276 | if self.check_address(address) == 0: |
| 277 | print("Keypatch: WARNING: invalid input address {0}".format(address)) |
| 278 | return assembly |
| 279 | |
| 280 | # for now, we only support IDA name resolve for X86, ARM, ARM64, MIPS, PPC, SPARC |
| 281 | if not (self.arch in (KS_ARCH_X86, KS_ARCH_ARM, KS_ARCH_ARM64, KS_ARCH_MIPS, KS_ARCH_PPC, KS_ARCH_SPARC)): |
| 282 | return assembly |
| 283 | |
| 284 | _asm = assembly.partition(' ') |
| 285 | mnem = _asm[0] |
| 286 | opers = _asm[2].split(',') |
| 287 | |
| 288 | for idx, op in enumerate(opers): |
| 289 | _op = list(op.partition('[')) |
| 290 | ignore_kw = True |
| 291 | if _op[1] == '': |
| 292 | _op[2] = _op[0] |
| 293 | _op[0] = '' |
| 294 | else: |
| 295 | _op[0] = _resolve(_op[0], ignore_kw=True) |
| 296 | ignore_kw = False |
| 297 | |
| 298 | _op[2] = _resolve(_op[2], ignore_kw=ignore_kw) |
| 299 | |
| 300 | opers[idx] = ''.join(_op) |
| 301 | |
| 302 | asm = "{0} {1}".format(mnem, ','.join(opers)) |
| 303 | return asm |
| 304 | |
| 305 | # return bytes of instruction or data |
| 306 | # return None on failure |
no test coverage detected