Inspect stack for format string.
| 4041 | # |
| 4042 | |
| 4043 | class FormatStringBreakpoint(gdb.Breakpoint): |
| 4044 | """Inspect stack for format string.""" |
| 4045 | def __init__(self, spec: str, num_args: int) -> None: |
| 4046 | super().__init__(spec, type=gdb.BP_BREAKPOINT, internal=False) |
| 4047 | self.num_args = num_args |
| 4048 | self.enabled = True |
| 4049 | return |
| 4050 | |
| 4051 | def stop(self) -> bool: |
| 4052 | reset_all_caches() |
| 4053 | msg = [] |
| 4054 | ptr, addr = gef.arch.get_ith_parameter(self.num_args) |
| 4055 | addr = lookup_address(addr) |
| 4056 | |
| 4057 | if not addr.valid: |
| 4058 | return False |
| 4059 | |
| 4060 | if addr.section.is_writable(): |
| 4061 | content = gef.memory.read_cstring(addr.value) |
| 4062 | name = addr.info.name if addr.info else addr.section.path |
| 4063 | msg.append(Color.colorify("Format string helper", "yellow bold")) |
| 4064 | msg.append(f"Possible insecure format string: {self.location}('{ptr}' {RIGHT_ARROW} {addr.value:#x}: '{content}')") |
| 4065 | msg.append(f"Reason: Call to '{self.location}()' with format string argument in position " |
| 4066 | f"#{self.num_args:d} is in page {addr.section.page_start:#x} ({name}) that has write permission") |
| 4067 | push_context_message("warn", "\n".join(msg)) |
| 4068 | return True |
| 4069 | |
| 4070 | return False |
| 4071 | |
| 4072 | |
| 4073 | class StubBreakpoint(gdb.Breakpoint): |