(self, bp, target)
| 323 | return True |
| 324 | |
| 325 | def _setup_breakpoint_HXBP(self, bp, target): |
| 326 | #print("Setup {0} into {1}".format(bp, target)) |
| 327 | if not isinstance(target, WinThread): |
| 328 | raise ValueError("SETUP HXBP_BP on {0}".format(target)) |
| 329 | # Todo: opti, not reparse exports for all thread of the same process.. |
| 330 | addr = self._resolve(bp.addr, target.owner) |
| 331 | if addr is None: |
| 332 | return False |
| 333 | x = self._hardware_breakpoint[target.tid] |
| 334 | if all(pos in x for pos in range(4)): |
| 335 | raise ValueError("Cannot put {0} in {1} (DRx full)".format(bp, target)) |
| 336 | empty_drx = str([pos for pos in range(4) if pos not in x][0]) |
| 337 | ctx = target.context |
| 338 | # Windows DebugCtl aliasing in DR7 |
| 339 | # See https://www.codeproject.com/Articles/517466/Last-branch-records-and-branch-tracing |
| 340 | ctx.EDr7.LE = 0 # bit 8 of DR7 represents bit 0 of DebugCtl. This is the LBR bit. (last branch record, will explain) |
| 341 | ctx.EDr7.GE = 0 # bit 9 of DR7 represents bit 1 of DebugCtl. This is the BTF bit. (single-step on branches) |
| 342 | setattr(ctx.EDr7, "L" + empty_drx, 1) |
| 343 | setattr(ctx, "Dr" + empty_drx, addr) |
| 344 | x[int(empty_drx)] = bp |
| 345 | target.set_context(ctx) |
| 346 | self.breakpoints[target.owner.pid][addr] = bp |
| 347 | dbgprint("Setting HXBP at <{0:#x}> in <{1}> (Dr{2})".format(addr, target, empty_drx), "DBG") |
| 348 | return True |
| 349 | |
| 350 | def _remove_breakpoint_HXBP(self, bp, target): |
| 351 | if not isinstance(target, WinThread): |
nothing calls this directly
no test coverage detected