add support for finding vtable pointers to check-structures-sanity

update structures
develop
Ben Lubar 2020-03-02 15:34:29 -06:00
parent 0024457167
commit 269b3cb8eb
No known key found for this signature in database
GPG Key ID: 92939677AB59EDA4
2 changed files with 15 additions and 11 deletions

@ -1 +1 @@
Subproject commit 24ed650356467b48ee12db9b22deb0528430d375
Subproject commit 9df961c0382cfdf052dfac2315c39a7260c497c5

@ -216,7 +216,7 @@ private:
#endif
bool check_access(const ToCheck &, void *, type_identity *);
bool check_access(const ToCheck &, void *, type_identity *, size_t);
bool check_vtable(const ToCheck &, void *, type_identity *);
const char *check_vtable(const ToCheck &, void *, type_identity *);
void queue_field(ToCheck &&, const struct_field_info *);
void queue_static_array(const ToCheck &, void *, type_identity *, size_t, bool = false, enum_identity * = nullptr);
bool maybe_queue_union(const ToCheck &, const struct_field_info *, const struct_field_info *);
@ -535,20 +535,20 @@ bool Checker::check_access(const ToCheck & item, void *base, type_identity *iden
#undef FAIL_PTR
}
bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *identity)
const char *Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *identity)
{
if (!check_access(item, PTR_ADD(vtable, -ptrdiff_t(sizeof(void *))), identity, sizeof(void *)))
return false;
return nullptr;
char **info = *(reinterpret_cast<char ***>(vtable) - 1);
#ifdef WIN32
if (!check_access(item, PTR_ADD(info, 12), identity, 4))
return false;
return nullptr;
#ifdef DFHACK64
void *base;
if (!RtlPcToFileHeader(info, &base))
return false;
return nullptr;
char *typeinfo = reinterpret_cast<char *>(base) + reinterpret_cast<int32_t *>(info)[3];
char *name = typeinfo + 16;
@ -557,7 +557,7 @@ bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *id
#endif
#else
if (!check_access(item, info + 1, identity, sizeof(void *)))
return false;
return nullptr;
char *name = *(info + 1);
#endif
@ -571,7 +571,7 @@ bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *id
if (!range.valid || !range.read)
{
FAIL("pointer to invalid memory range");
return false;
return nullptr;
}
bool letter = false;
@ -579,7 +579,7 @@ bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *id
{
if (!range.isInRange(p))
{
return false;
return nullptr;
}
if (*p >= 'a' && *p <= 'z')
@ -588,12 +588,12 @@ bool Checker::check_vtable(const ToCheck & item, void *vtable, type_identity *id
}
else if (!*p)
{
return letter;
return letter ? name : nullptr;
}
}
}
return false;
return nullptr;
}
void Checker::queue_field(ToCheck && item, const struct_field_info *field)
@ -834,6 +834,10 @@ void Checker::check_dispatch(ToCheck & item)
FAIL("untyped pointer is actually stl-string with value \"" << *str << "\" (length " << str->length() << ")");
}
#endif
else if (auto vtable_name = check_vtable(item, item.ptr, df::identity_traits<void *>::get()))
{
FAIL("pointer to a vtable: " << vtable_name);
}
else
{
FAIL("pointer to memory with no size information");