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

Improve C++ RTTI detection #7904

Open
astrelsky opened this issue Mar 13, 2025 · 9 comments
Open

Improve C++ RTTI detection #7904

astrelsky opened this issue Mar 13, 2025 · 9 comments
Assignees
Labels
Feature: Language/C++ Status: Internal This is being tracked internally by the Ghidra team Status: Waiting on customer Waiting for customer feedback

Comments

@astrelsky
Copy link
Contributor

#3213 (reply in thread)

While uncommon there can be situations where the string may not be present in the program but the class is used from a dynamic library. Recommended changing the condition to check if any of the class type info namespaces are already defined or if the string exists in the program. (I am assuming checking the symbol table is faster than searching memory)

@ghidra007
Copy link
Contributor

@astrelsky I believe it does check for the string if it can't find the symbol. Can you share your binary (or one that displays this issue) so I can triage. Is the mangled string in the binary and referenced by the class_type_info structure? Thanks!

@ghidra007 ghidra007 added the Status: Waiting on customer Waiting for customer feedback label Mar 13, 2025
@astrelsky
Copy link
Contributor Author

astrelsky commented Mar 13, 2025

@astrelsky I believe it does check for the string if it can't find the symbol. Can you share your binary (or one that displays this issue) so I can triage. Is the mangled string in the binary and referenced by the class_type_info structure? Thanks!

The mangled string is not in the program. The vtable symbol for __class_type_info is defined. The string 'class_type_info' is not in the program. However the symbol __cxxabiv1::__class_type_info::vtable does exist and is in the symbol table. That is the only symbol in the __class_type_info namespace.

I do not own the rights to distribute the program in question.

If I remove that check it works (may have removed the other check too idk)

@ghidra007
Copy link
Contributor

@astrelsky I believe it does check for the string if it can't find the symbol. Can you share your binary (or one that displays this issue) so I can triage. Is the mangled string in the binary and referenced by the class_type_info structure? Thanks!

The mangled string is not in the program. The vtable symbol for __class_type_info is defined. The string 'class_type_info' is not in the program. However the symbol __cxxabiv1::__class_type_info::vtable does exist and is in the symbol table. That is the only symbol in the __class_type_info namespace.

I do not own the rights to distribute the program in question.

If I remove that check it works (may have removed the other check too idk)

Thanks for the info. Can you tell me the line number(s) for the check you removed so I can test whether removing it breaks anything else?

@astrelsky
Copy link
Contributor Author

@astrelsky I believe it does check for the string if it can't find the symbol. Can you share your binary (or one that displays this issue) so I can triage. Is the mangled string in the binary and referenced by the class_type_info structure? Thanks!

The mangled string is not in the program. The vtable symbol for __class_type_info is defined. The string 'class_type_info' is not in the program. However the symbol __cxxabiv1::__class_type_info::vtable does exist and is in the symbol table. That is the only symbol in the __class_type_info namespace.
I do not own the rights to distribute the program in question.
If I remove that check it works (may have removed the other check too idk)

Thanks for the info. Can you tell me the line number(s) for the check you removed so I can test whether removing it breaks anything else?

diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java b/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java
index fd0f4aa9e6..b6cd1b3295 100644
--- a/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java
+++ b/Ghidra/Features/Decompiler/ghidra_scripts/RecoverClassesFromRTTIScript.java
@@ -413,11 +413,6 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {

                        runScript("FixElfExternalOffsetDataRelocationScript.java");

-                       // first check that there is even rtti by searching the special string in memory
-                       if (!isStringInProgramMemory("class_type_info")) {
-                               return ("This program does not contain RTTI.");
-                       }
-
                        // then check to see if the special typeinfo namespace is in external space
                        // if so then relocations are present and have not been fixed up because when fixed up
                        // the namespace gets moved to inside program space
@@ -1614,7 +1609,7 @@ public class RecoverClassesFromRTTIScript extends GhidraScript {

        private boolean isExternalNamespace(String path) throws CancelledException {

-               List<Symbol> symbols = NamespaceUtils.getSymbols(path, currentProgram, true);
+               List<Symbol> symbols = NamespaceUtils.getSymbols(path, currentProgram, false);

                for (Symbol symbol : symbols) {
                        monitor.checkCancelled();

Adding a println on the symbol emitted __cxxabiv1::__class_type_info and library::__cxxabiv1::__class_type_info so it was finding the soncd one and failing with the relocation complaint even though it had a properly relocated symbol.

@ghidra007
Copy link
Contributor

@astrelsky Thanks!

@ryanmkurtz ryanmkurtz removed the Status: Waiting on customer Waiting for customer feedback label Mar 14, 2025
@ghidra007
Copy link
Contributor

ghidra007 commented Mar 14, 2025

@astrelsky I still want a check to determine if there is RTTI before running so instead of flat out removing the check a better solution is to improve it to handle this use case. I will check to see if changing the searchWithinAllLibraries option will still work with all of my use cases.

@ghidra007 ghidra007 added Status: Internal This is being tracked internally by the Ghidra team and removed Status: Triage Information is being gathered labels Mar 14, 2025
@ghidra007
Copy link
Contributor

@astrelsky Can you check to see if the script works on your binary with just the first check removed? The other check is necessary for some use cases. I might be able to rework but I am curious to know if the script runs with the original code:

List symbols = NamespaceUtils.getSymbols(path, currentProgram, true);

Thanks.

@ghidra007 ghidra007 added the Status: Waiting on customer Waiting for customer feedback label Mar 14, 2025
@astrelsky
Copy link
Contributor Author

@astrelsky Can you check to see if the script works on your binary with just the first check removed? The other check is necessary for some use cases. I might be able to rework but I am curious to know if the script runs with the original code:

List symbols = NamespaceUtils.getSymbols(path, currentProgram, true);

Thanks.

It does not work with only the first check removed.

That snippet of code finds the first good symbol and then continues iterating, finds the one in the library namespace and then returns crying about a non-existent problem.

@ghidra007
Copy link
Contributor

@astrelsky ok I'll try to make that check more specific to my use-case if possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Language/C++ Status: Internal This is being tracked internally by the Ghidra team Status: Waiting on customer Waiting for customer feedback
Projects
None yet
Development

No branches or pull requests

3 participants