-
Notifications
You must be signed in to change notification settings - Fork 570
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
Fixing support for inject_x64 injection inside WOW64 processes #4989
Conversation
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.
Thank you for working on this and contributing the patch. I'm not sure I understand some of it though.
core/win32/syscall.c
Outdated
// commenting this ASSERT since x64 client injected in | ||
// WOW64 binaries will be using mc->rax as comparaison | ||
// thus making the assert fail, while the syscall still | ||
// being valid. |
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.
A) Who is setting the upper bits?
B) You mean the Windows kernel ignores the upper bits? So the assert is flawed?
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 meant that the assert always fails due to the size of mc->rax being compared with wrong sizes, no matter if the syscall is valid or not.
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 don't understand "the assert always fails due to the size of mc->rax being compared with wrong sizes"?
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.
Trying to print the first erroneous syscall (syscall that makes the assert trigger) on WoW64 + inject_x64, I can see that mc->xax
value is ffffffff00031054
. I assume that this comes from a conversion somehow representing the syscall with a signed number, which outputs a value that is wrong if you display it. Since mc->xax
is only used as a sysnumber and type converted to int
, this is not an issue, but this still makes ASSERT_TRUNCATE
(more precisely CHECK_TRUNCATE_TYPE_int
) fail.
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.
There would not be a widening conversion for an application register. App register values have to be precisely preserved. The machine context structure stores 64-bit values and prints them as such. If the top bits there are 1's, either the app set them to 1's, or somehow there is a bug where DR corrupted the register value. Is this for 32-bit app code? If it is 64-bit, we can't put it past Windows making some change to have the top bits mean something -- though in the past 64-bit code wrote to eax
, zeroing the top bits.
core/win32/syscall.c
Outdated
@@ -1744,7 +1744,10 @@ propagate_options_via_env_vars(dcontext_t *dcontext, HANDLE process_handle, | |||
* model without requiring setting up config files for children. | |||
*/ | |||
uint64 peb; | |||
bool peb_is_32 = is_32bit_process(process_handle); | |||
bool peb_is_32 = is_32bit_process(process_handle) | |||
// if x64 client targeting WOW64 we need to |
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.
nit: Modern style is to prefer capitalized and punctuated whole-sentence comments.
All the tests are failing: looks like b/c of tabs:
The style convention is to not have any tabs. |
Tests are all still failing with clang-format style violations:
|
Fixed in last commit |
There are more -- I would suggest checking the entire diff, or better following the development setup
There are also clang-format failures -- see the ci-clang-format test. I would suggest setting up clang-format in your editor. |
Just removed other trailing spaces. |
Not sure about what is failing in Windows build. Looks like a CI error that is not coming from my code. |
I think it's a sourceforge server error causing doxygen to not get downloaded. Probably re-running is the first thing to try: I clicked re-run. |
run arm tests |
@AssadHashmi -- is there any way to enable existing contributors to trigger AArch64 Jenkins runs from a forked PR? It seems there's no way to do that now for a PR from a forked PR created by a new contributor. |
Going to merge this w/o the Jenkins for now: the master run will catch issues. Cross-compile for these code changes gives high confidence. Once @AssadHashmi is back we'll try to figure out a better long term solution. |
Fixes issues around the -inject_x64 prototype option added by PR #4653 for #803 to enable injecting a 64-bit DR into a WOW64 (32-bit) child ("mixed mode"). Xref discussion at https://groups.google.com/g/dynamorio-users/c/rhEpslerwf8 Adds a new option -vmheap_size_wow64 since the default x64 size will not fit in a WOW64 process. Saves eax register that holds routine address for RtlUserThreadStart before mode switch, and restores it on mode switch. Fixes far jmp to switch to x64 mode on injection. Fixes env variable argument propagation. Example command line that works : $ bin64\drrun.exe -inject_x64 -c .\clientdll.dll -- bin64\create_process.exe .\helloworld32.exe We still need to add proper support on drrun64 to inject natively without having to use create_process.exe. Issue: #49, #4990
add to whitelist |
ok to test |
test this please |
run arm tests |
I think once it's merged nothing will run |
You're right @derekbruening. |
An EDITThis can be fixed changing this to : bool target_64 = !x86_code IF_X64(|| !DYNAMO_OPTION(inject_x64)); But this seems to create syscall issues later on on my current Win10 OS. Upon creating a message box (target app calls Windows 10 Build 19041 |
I can confirm that mixed code injection is not working anymore on latest cronbuilds (18324 and 18331, since PR basically). I have a working version of dynamoRIO with injection somewhere. I have been testing this PR again, and the error occurs. So the problem comes from my side, I might have forgotten some change I have made somewhere. I will check that soon and submit a PR fixing that. |
A regression test should be enabled to avoid breakage. |
Applying modification from this PR to #4653 (#803) works perfectly well, if we add : if (is_32bit_process(phandle) && DYNAMO_OPTION(inject_x64)) {
target_64 = false;
} that I did forget in my PR. The syscall trouble must be coming from some other commit since this PR. Would you know which commit might have mess with syscall handling since then? |
Trouble starts from cronbuild-8.0.18663, we need to check commits between 18655 and 18663. |
PR for issue#4990.
Those changes fixes support for inject_x64 injection on WoW64 processes, which allows support for mixed mode code, see this
Note that allocation of vmheap fails upon initializing dynamoRIO 64 on WoW64 processes. Thus, we need to pass
-reachable_heap
to avoid having to make this allocation.We still need to have a proper support on
drrun64
to inject natively without having to usecreate_process.exe
.Example command line that works :
As we need to specify
reachable_heap
I am afraid thatwin32.mixedmode
test will be needing some tweaks.Changes features :
eax
register that holds routine address forRtlUserThreadStart
before mode switch, and restore it on mode switchEDIT
-reachable_heap
should not be required anymore since vmheap injection issues has been fixed in this commit.