THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
Coff._add_relocs resolves a relocation against an undefined external symbol by
allocating it an extern address:
cle_symbol = self.get_symbol(sym_name, produce_extern_symbols=True)
self.relocs.append(reloc_class(self, cle_symbol, patch_offset))
but nothing is ever added to self.imports; the loader body ends with
# FIXME: Expose __imp_* symbols through self.imports
angr.Project._register_object iterates obj.imports and nothing else, so for
a COFF object it iterates an empty dictionary and hooks nothing. The extern
addresses stay raw zero fill, and a call to an undefined external is decoded as
instructions.
extern int one(int);
extern int two(int);
int entry(int x) { return one(x) + two(x); }
x86_64-w64-mingw32-gcc -c -o coff2.o coff2.c
p = angr.Project("coff2.o", auto_load_libs=False, main_opts={"backend": "COFF"})
print(p.loader.main_object.imports) # {}
for s in p.loader.extern_object.symbols:
print(hex(s.rebased_addr), s.name, p.is_hooked(s.rebased_addr))
{}
0x500000 one False
0x500008 two False
CFGFast() then produces a function one at 0x500000 whose single block is the
eight zero bytes of the extern slot, reached by call 0x500000 at 0x400117.
The same happens under symbolic execution: calling the import executes zero fill
instead of a ReturnUnconstrained stub.
For contrast, a relocatable ELF populates imports, so _register_object sees
the same undefined externals and hooks them: the equivalent object built with
gcc -c gets a ReturnUnconstrained at each extern address and CFGFast decodes
nothing there.
In a block-level sweep of a large mixed corpus this accounts for 17 x86 and
x86_64 COFF objects placing CFG blocks in loader-invented memory. Real objects
show it as clearly as the reduced case: on
sha256 69ba352d244c317e01aa7ca99d5391e0785f8198f46691039482607b7032cea7
(main_opts={"backend": "COFF"}) the extern object holds malloc,
FcSerializeAlloc and FcSerializePtr at 0x500000, 0x500008 and 0x500010, none
of them hooked, and CFGFast makes a function of each. On
sha256 df12b231e916f618c8ceab0e2b2a6832bd0f9c34602b81cf48e20372e888a740 there
are 84 of them.
This is a report rather than a pull request because filling in imports changes
what every COFF analysis does — every undefined external becomes a
ReturnUnconstrained stub rather than decodable memory — and because the FIXME
names __imp_* specifically, which suggests a maintainer already has a view on
whether the indirection should be represented and how.
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
Coff._add_relocsresolves a relocation against an undefined external symbol byallocating it an extern address:
but nothing is ever added to
self.imports; the loader body ends with# FIXME: Expose __imp_* symbols through self.importsangr.Project._register_objectiteratesobj.importsand nothing else, so fora COFF object it iterates an empty dictionary and hooks nothing. The extern
addresses stay raw zero fill, and a call to an undefined external is decoded as
instructions.
CFGFast()then produces a functiononeat 0x500000 whose single block is theeight zero bytes of the extern slot, reached by
call 0x500000at 0x400117.The same happens under symbolic execution: calling the import executes zero fill
instead of a
ReturnUnconstrainedstub.For contrast, a relocatable ELF populates
imports, so_register_objectseesthe same undefined externals and hooks them: the equivalent object built with
gcc -cgets aReturnUnconstrainedat each extern address and CFGFast decodesnothing there.
In a block-level sweep of a large mixed corpus this accounts for 17 x86 and
x86_64 COFF objects placing CFG blocks in loader-invented memory. Real objects
show it as clearly as the reduced case: on
sha256
69ba352d244c317e01aa7ca99d5391e0785f8198f46691039482607b7032cea7(
main_opts={"backend": "COFF"}) the extern object holdsmalloc,FcSerializeAllocandFcSerializePtrat 0x500000, 0x500008 and 0x500010, noneof them hooked, and CFGFast makes a function of each. On
sha256
df12b231e916f618c8ceab0e2b2a6832bd0f9c34602b81cf48e20372e888a740thereare 84 of them.
This is a report rather than a pull request because filling in
importschangeswhat every COFF analysis does — every undefined external becomes a
ReturnUnconstrainedstub rather than decodable memory — and because the FIXMEnames
__imp_*specifically, which suggests a maintainer already has a view onwhether the indirection should be represented and how.