-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add ARM64 exceptions #1902
Add ARM64 exceptions #1902
Conversation
Also, a very newbie question: How do I read the |
Does
|
@jxy-s I don't fully understand how to use UnwindData is the Exception Information RVA: The address of the variable-length exception information structure, stored in the I don't know how to find where |
So, since I think your goal is to read the exception information stored at the |
Regarding ARM64EC. I have no idea. I can work on that in a next PR 😅 |
Some of these |
for ARM64EC you may want to review this project: https://github.com/FFRI/ProjectChameleon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies on the delay here. I just got around to testing the changes myself. I've added some feedback to incorporate.
Additionally there is AMD64
in the ARM64EC
binary (you will see then when you use dumpbin.exe
). I haven't located where they are. If I had to guess the dynamic relocations fix up the IMAGE_DIRECTORY_ENTRY_EXCEPTION
directory in the headers to point to the alternative directory. The loader will do this for ARM64EC
in the case of the export directory, see PhpFixupExportDirectoryForARM64EC
for the hoops necessary to locate the alternate directory.
{ | ||
PhPrintPointer(value, UlongToPtr(entry->UnwindData)); | ||
PhSetListViewSubItem(ListViewHandle, lvItemIndex, 2, value); | ||
PhSetListViewSubItem(ListViewHandle, lvItemIndex, 3, L"✔️"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PhSetListViewSubItem(ListViewHandle, lvItemIndex, 3, L"✔️"); | |
PhSetListViewSubItem(ListViewHandle, lvItemIndex, 3, L"Yes"); |
I appreciate this visually but we have a precedence for using "Yes" instead of extended Unicode characters.
We've had issues the past with editors and GitHub itself screwing this up. At very least, for the sake of consistency - would you please change this to L"Yes"
instead?
exceptionData = (IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA*)PhMappedImageRvaToVa(&PvMappedImage, entry->UnwindData, NULL); | ||
functionLength = exceptionData->FunctionLength << 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exceptionData = (IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA*)PhMappedImageRvaToVa(&PvMappedImage, entry->UnwindData, NULL); | |
functionLength = exceptionData->FunctionLength << 2; | |
exceptionData = (IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA*)PhMappedImageRvaToVa(&PvMappedImage, entry->UnwindData, NULL); | |
if (exceptionData) | |
functionLength = exceptionData->FunctionLength << 2; | |
else | |
functionLength = 0; |
Please add a null pointer check. While unlikely, in an odd/corrupt case the RVA could not land within a section, causing the parser here to crash.
} | ||
} | ||
|
||
printf("Flag: %u\n", entry->Flag); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
printf("Flag: %u\n", entry->Flag); |
Please remove this.
PhPrintPointer(value, UlongToPtr(entry->BeginAddress)); | ||
PhSetListViewSubItem(ListViewHandle, lvItemIndex, 1, value); | ||
|
||
ULONG functionLength = entry->FunctionLength << 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should move accessing the packed FunctionLength
into the case where we know the entry is in the packed form. Especially since I'm asking for a null pointer check elsewhere.
ULONG functionLength = entry->FunctionLength << 2; | ||
if (entry->Flag != 0) //Packed Unwind Data | ||
{ | ||
PhPrintPointer(value, UlongToPtr(entry->UnwindData)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing UnwindData
here is incorrect. This is an erroneous value when Flags != 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably best to instead show a representation of these bits here:
ULONG RegF : 3;
ULONG RegI : 4;
ULONG H : 1;
ULONG CR : 2;
ULONG FrameSize : 9
Described here: https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#packed-unwind-data
PhSetListViewSubItem(ListViewHandle, lvItemIndex, 1, value); | ||
|
||
ULONG functionLength = entry->FunctionLength << 2; | ||
if (entry->Flag != 0) //Packed Unwind Data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth showing the type of packing here (instead of yes/no), the bits are described here:
https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#packed-unwind-data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, instead of showing L"Yes" for "Packed", we could instead show something more descriptive:
00 = packed unwind data not used; remaining bits point to an .xdata record
01 = packed unwind data used with a single prolog and epilog at the beginning and end of the scope
10 = packed unwind data used for code without any prolog and epilog. Useful for describing separated function segments
11 = reserved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any idea on column names and what text for each case?
/* Todo */ | ||
for (ULONG i = 0; i < exceptions.NumberOfEntries; i++) | ||
{ | ||
PPH_IMAGE_RUNTIME_FUNCTION_ENTRY_ARM64 entry = PTR_ADD_OFFSET(exceptions.ExceptionDirectory, i * sizeof(PH_IMAGE_RUNTIME_FUNCTION_ENTRY_ARM64)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY
is in the SDK headers now, I think we can eliminate the PPH_IMAGE_RUNTIME_FUNCTION_ENTRY_ARM64
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok. I thought that there was a reason all these entry types were being redeclared. I did see it in the SDK headers, but just to keep it conformance with the others ones I ended up redeclaring. I can work on this once I'm back.
Tank you for the many change requests. I'll work on the ones that are up to my league once I'm back after December, 11th |
@hmartinez82 I'm currently working on a set of changes specific to ARM to provide better support and visibility. I wanted to ask if you would like me to incorporate your changes here to that set of changes, or if you plan to continue this PR? |
Sure, you can incorporate these changes in your branch and I'll close this one :) |
Initial discussion for something better than a blank page :)
Is this acceptable?