Make ida integration work in shared libraries (#3172)

* Make ida integration work in shared libraries

* lint

* edge case happens too often

* make the check faster (and change the contract abit)
pull/3177/head
k4lizen 5 months ago committed by GitHub
parent 46047f6530
commit 0e39240186
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -41,3 +41,44 @@ def find(address: int | pwndbg.dbg_mod.Value | None) -> pwndbg.lib.memory.Page |
return page
return pwndbg.aglib.vmmap_custom.explore(address)
def addr_region_start(address: int | pwndbg.dbg_mod.Value) -> int | None:
"""
Let's define a "region" as contiguous memory compromised of memory mappings
which all have the same object file name. Also referred to as "File (Base)" by
`xinfo`.
Returns:
The start of the memory region this address belongs to, or None if the address
is not mapped.
"""
address = int(address)
if address < 0:
return None
mappings = sorted(pwndbg.aglib.vmmap.get(), key=lambda p: p.vaddr)
idx = -1
for i in range(len(mappings)):
if mappings[i].start <= address < mappings[i].end:
idx = i
break
if idx == -1:
# Maybe we can find the page by exploring.
explored_page = pwndbg.aglib.vmmap_custom.explore(address)
if not explored_page:
return None
# We know vmmap_custom.explore() can only find one page, it does
# not cascade a whole region so there is no need to look backwards.
return explored_page.start
# Look backwards from i to find all the mappings with the same name.
objname = mappings[i].objfile
while i > 0 and objname == mappings[i - 1].objfile:
i -= 1
# There might be other mappings with the name "objname" in the address space
# but they are not contiguous with us, so we don't care.
return mappings[i].start

@ -61,17 +61,19 @@ def xinfo_mmap_file(page: Page, addr: int) -> None:
file_name = page.objfile
objpages = filter(lambda p: p.objfile == file_name, pwndbg.aglib.vmmap.get())
first = sorted(objpages, key=lambda p: p.vaddr)[0]
region_start = pwndbg.aglib.vmmap.addr_region_start(addr)
if region_start is None:
print("The file is not contiguous in memory.")
return
# print offset from ELF base load address
rva = addr - first.vaddr
print_line("File (Base)", addr, first.vaddr, rva, "+")
rva = addr - region_start
print_line("File (Base)", addr, region_start, rva, "+")
# find possible LOAD segments that designate memory and file backings
containing_loads = [
seg
for seg in pwndbg.aglib.elf.get_containing_segments(file_name, first.vaddr, addr)
for seg in pwndbg.aglib.elf.get_containing_segments(file_name, region_start, addr)
if seg["p_type"] == "PT_LOAD"
]
@ -89,7 +91,7 @@ def xinfo_mmap_file(page: Page, addr: int) -> None:
else:
print(f"{'File (Disk)'.rjust(20)} {M.get(addr)} = [not file backed]")
containing_sections = pwndbg.aglib.elf.get_containing_sections(file_name, first.vaddr, addr)
containing_sections = pwndbg.aglib.elf.get_containing_sections(file_name, region_start, addr)
if len(containing_sections) > 0:
print("\n Containing ELF sections:")
for sec in containing_sections:

@ -180,18 +180,18 @@ def can_connect() -> bool:
def l2r(addr: int) -> int:
exe = pwndbg.aglib.elf.exe()
if not exe:
raise Exception("Can't find EXE base")
result = (addr - int(exe.address) + base()) & pwndbg.aglib.arch.ptrmask
region_start = pwndbg.aglib.vmmap.addr_region_start(addr)
if region_start is None:
return 0
result = (addr - region_start + base()) & pwndbg.aglib.arch.ptrmask
return result
def r2l(addr: int) -> int:
exe = pwndbg.aglib.elf.exe()
if not exe:
raise Exception("Can't find EXE base")
result = (addr - base() + int(exe.address)) & pwndbg.aglib.arch.ptrmask
region_start = pwndbg.aglib.vmmap.addr_region_start(addr)
if region_start is None:
return 0
result = (addr - base() + region_start) & pwndbg.aglib.arch.ptrmask
return result

Loading…
Cancel
Save