Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demangle RTTI class names #9

Open
stevemk14ebr opened this issue Sep 16, 2019 · 6 comments
Open

Demangle RTTI class names #9

stevemk14ebr opened this issue Sep 16, 2019 · 6 comments

Comments

@stevemk14ebr
Copy link

RTTI class names that start with .?AV or .?AU (class/struct) are not demangled. This can be fixed by stripping the symbol prefix for RTTI and replacing it with the C++ class prefix.

Example:
.?AVCNetMidLayer@@ -> ??0CNetMidLayer@@QAE@XZ

From:
https://reverseengineering.stackexchange.com/questions/20516/how-can-i-demangle-the-name-in-an-rtti-type-descriptor
and
https://github.com/REhints/HexRaysCodeXplorer/blob/5be89aa1d32eeaefb099b838ee5622200eb8a2e9/src/HexRaysCodeXplorer/ObjectExplorer.h#L80

@nico
Copy link
Owner

nico commented Sep 17, 2019

Thanks for the report.

I think the .AV... bit is written by mangleCXXRTTIName() (currently at http://llvm-cs.pcc.me.uk/tools/clang/lib/AST/MicrosoftMangle.cpp#3129), which mangles the contents of the RTTI descriptor (i.e. it's not really a symbol, but data in the symbol whose name is computed by mangleCXXRTTI() a bit further down in that file).

undname also can't demangle this (but there's no reason not to do better, of course):

C:\src\demumble>undname .?AVCNetMidLayer@@
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- ".?AVCNetMidLayer@@"
is :- ".?AVCNetMidLayer@@"

For Itanium symbols, we're able to demangle both name of the struct and the contents:

C:\src\llvm-mono>..\demumble\demumble.exe _ZTI1H
typeinfo for H

C:\src\llvm-mono>..\demumble\demumble.exe _ZTSFviE
typeinfo name for void (int)

This suggests we should support this for the Microsoft ABI too.

@nico
Copy link
Owner

nico commented Sep 17, 2019

One problem is that this makes it a bit hard to detect a mangled string. At the moment, we can look for "?" as prefix on Win and for "_Z" on Itanium.

With this, the prefix on Win can be ".?..." for a tag type (typeof(MyClass)), ".$$B..." for an array type (typeof(MyClass[4])), ".N" (and other built-in type codes) for a built-in type (typeof(double)) -- we basically have to look for a mangled type after every period in the input.

nico added a commit that referenced this issue Sep 20, 2019
@nico
Copy link
Owner

nico commented Sep 20, 2019

With ad8745b (not production quality) applied locally:

$ buildmac/demumble ".?AVCNetMidLayer@@"
typeinfo name for class CNetMidLayer

nico added a commit that referenced this issue Sep 20, 2019
@nico
Copy link
Owner

nico commented Sep 20, 2019

Upstream bit: https://reviews.llvm.org/D67851

@stevemk14ebr
Copy link
Author

Thank you for working on this

nico added a commit that referenced this issue Sep 23, 2019
New:
  - [ms] demangle rtti descriptor names

Ran:

  cp ~/src/llvm-project/llvm/include/llvm/Demangle/*.h third_party/llvm/include/llvm/Demangle/
  cp ~/src/llvm-project/llvm/lib/Demangle/*.cpp third_party/llvm/lib/Demangle/
  cp ~/src/llvm-project/llvm/LICENSE.TXT third_party/llvm/LICENSE.txt

Related to #9.
@nico
Copy link
Owner

nico commented Sep 23, 2019

Trunk now demangles rtti descriptor names when you pass them directly:

$ ./demumble .?AVCNetMidLayer@@
class CNetMidLayer `RTTI Type Descriptor Name'

Adding it in streaming mode (echo .?AVCNetMidLayer@@ | ./demumble) is a bit tricky to do since . is such a common character. If I do what's in ad8745b , then echo ._Z1fv | ./demumble goes from .f() to ._Z1fv because the . now triggers an MS demangling attempt (because "_Z1fv" by themselves are all valid ms mangling chars), and on demangling fail demumble currently prints the whole candidate string and advances.

I could make it so that on demangling fail, we consume just one char instead or something.

Not supporting this in streaming mode at all isn't super unreasonable either imho, since that's what we do for itanium type manglings ("Pi").

But eventually I'll probably want to do the smarter backtracking -- it should fire rarely enough that it shouldn't affect perf much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants