Minor Bug in MoveFileEx?

niemiro

Senior Administrator, Windows Update Expert
Staff member
Joined
Mar 2, 2012
Posts
8,770
Location
District 12
I think I've found a bug in MoveFileEx which affects an extremely specific condition when running under a 32bit process on a 64bit computer.

Calling with dwFlags MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING.

The problem is that you can't move a file in System32 - and wait, this probably isn't what you think it is.

I've covered all of the basis - file permissions (write etc. on destination, delete on source), AllowPendingRenames, etc. etc.

The function returns success, and the PendingFileRenameOperations registry key is set almost correctly.

But here's the problem - when I make a call from a 64bit application, everything works fine and the replacement goes through perfectly over the reboot - this suggests to me that my permissions, AllowPendingRenames, etc. setup are correct.

However, I would get a silent failure over the reboot when running from a 32bit application on a 64bit computer, so I started to look into why this might be.

It turns out that MoveFileEx with this setup from a WOW64 application redirects System32 --> SysWOW64. Nothing unexpected there, perfect behavior infact. So what if I want to access System32 itself? Well, I use Sysnative. Well, here's the problem. MoveFileEx doesn't convert Sysnative --> System32, (and smss.exe won't accept Sysnative over the reboot from what I can see) and consequently I am a bit stuck for accessing System32.

Must I use Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection? Just seems a bit weird that MoveFileEx redirects System32 --> SysWOW64, but not Sysnative --> System32. I would consider this a bug. Just wondering whether I've perhaps overlook something.

But...if I manually tweak the registry from Sysnative --> System32, and replacement goes perfectly. So there can't be anything wrong with the setup, just how I'm calling the function, or a bug, or something undocumented.

This is such a specific case with workarounds that it really doesn't matter, more a curiosity (and after all, worst case scenario I could manually set the registry key myself).

Richard

EDIT: Can now confirm for sure Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection works as expected. That is probably the best workaround, but it still feels a little buggy.
 
Last edited:
This is because Windows on WOW64 provides filesystem redirection. In 64 bit Windows System32 is reserved for 64 bit applications. When a 32 bit application tries to access the System32 folder, access is redirected to SysWOW64.

This is known behavior though... Call this function to disable that redirection for the calling thread: Wow64DisableWow64FsRedirection function

Not exactly a bug, but planned behavior differences between 32 and 64 bit Windows, probably for security purposes in Microsoft's defense. The other method would be to create an NTFS junction point in which points to the System32 folder itself, and access the NTFS junction point instead of the System32 folder directly.
 
Last edited:
This is because Windows on WOW64 provides filesystem redirection. In 64 bit Windows System32 is reserved for 64 bit applications. When a 32 bit application tries to access the System32 folder, access is redirected to SysWOW64.

This is known behavior though... Call this function to disable that redirection for the calling thread: Wow64DisableWow64FsRedirection function

Not exactly a bug, but planned behavior differences between 32 and 64 bit Windows, probably for security purposes in Microsoft's defense. The other method would be to create an NTFS junction point in which points to the System32 folder itself, and access the NTFS junction point instead of the System32 folder directly.

Thank you for your response!

It is indeed the redirection policies, and the System32 --> SysWOW64 redirection is as I would expect.

But the thing I don't get is why Sysnative alias doesn't work: File System Redirector (Windows)

General Microsoft Documentation said:
WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.

So why doesn't Sysnative work here? Oh yes, there are plenty of easy workarounds, I was just confused by why it wasn't working here, and wondered whether you or anything else knew exceptions to the usage of the Sysnative alias.

Thank you!

Richard
 
Sysnative should work, are you sure this is a WOW64 process? Sysnative still hasn't changed on Windows 8, I just confirmed. I was too lazy to make a program so I went to the SysWOW64 folder where all the 32 bit programs reside, opened notepad and tried to open a file from %WinDir%\Sysnative. It redirects to the native System32 folder no problem.

edit: I placed a dummy file in the native System32 folder to see if it existed in the Sysnative redirect to validate whether I was in SysWOW64 or System32. They should have just made a System64 folder. I can only imagine the chaos we'll see when 128 bit machines make the mainstream market. What is odd is that System32 is the native location for 64 bit programs, and SysWOW64 is for 32. When 128 bit comes out, what kind of folder will they decide for it? Or will 32 bit be removed at that point?
 

Attachments

  • sysnative_1.png
    sysnative_1.png
    44.5 KB · Views: 0
  • sysnative_2.png
    sysnative_2.png
    34.7 KB · Views: 0
Last edited:
Thanks again for looking. It's definitely a WOW64 process, and the thing is, Sysnative redirection works perfectly in this process - except in MoveFileEx in this one extremely specific scenario.

I've had a quick disassemble though, and now think the problem lies in the function BasepMoveFileDelayed.

In the code, there are two references to SysWOW64, with a rather complicated bunch of conditional jumps I haven't attempted to understand, so I do believe that this is where SysWOW64 redirection is occurring. However, there isn't a single reference to Sysnative. I believe this problem to have arisen due to the use of DOS file paths for smss.exe, and I suspect that the cause is that delaying the file move means that the lowest level file access functions never get called, which is where the normal (non-buggy) redirection is normally situation, and the redirection must occur before the reboot as smss.exe is a 64bit application, not WOW64, so it can't access Sysnative should it have been left in the registry (and it can't do delayed redirection because otherwise System32 would be ambiguous), therefore BasepMoveFileDelayed takes on the manual redirection, but the developer forgot about Sysnative! Definitely a bug IMO...

Believe this to be a bug in BasepMoveFileDelayed...

Code:
.text:7DDED5E8 aSyswow64_0:                            ; DATA XREF: BasepMoveFileDelayed(x,x,x,x,x)+B1o
.text:7DDED5E8                                         ; BasepMoveFileDelayed(x,x,x,x,x)+116o
.text:7DDED5E8                 unicode 0, <SysWOW64>,0
.text:7DDED5FA                 align 4
.text:7DDED5FC                 db 3 dup(90h)

...

.text:7DDED09F                 mov     edi, edi
.text:7DDED0A1                 push    ebp
.text:7DDED0A2                 mov     ebp, esp
.text:7DDED0A4                 sub     esp, 0F8h
.text:7DDED0AA                 mov     eax, ___security_cookie
.text:7DDED0AF                 xor     eax, ebp
.text:7DDED0B1                 mov     [ebp+var_4], eax
.text:7DDED0B4                 mov     eax, [ebp+arg_10]
.text:7DDED0B7                 push    ebx
.text:7DDED0B8                 xor     ebx, ebx
.text:7DDED0BA                 mov     [ebp+var_88], eax
.text:7DDED0C0                 mov     eax, large fs:18h
.text:7DDED0C6                 mov     [ebp+var_A4], ebx
.text:7DDED0CC                 mov     eax, [eax+0F70h]
.text:7DDED0D2                 mov     ecx, [eax+14C0h]
.text:7DDED0D8                 or      ecx, [eax+14C4h]
.text:7DDED0DE                 push    esi
.text:7DDED0DF                 mov     esi, [ebp+arg_0]
.text:7DDED0E2                 push    edi
.text:7DDED0E3                 mov     edi, [ebp+arg_4]
.text:7DDED0E6                 mov     [ebp+var_94], esi
.text:7DDED0EC                 mov     [ebp+var_9C], edi
.text:7DDED0F2                 mov     [ebp+var_98], ebx
.text:7DDED0F8                 mov     [ebp+var_A0], ebx
.text:7DDED0FE                 jnz     loc_7DDED1C4
.text:7DDED104                 call    _KernelBaseGetGlobalData@0 ; KernelBaseGetGlobalData()
.text:7DDED109                 add     eax, 3Ch
.text:7DDED10C                 cmp     word ptr [esi], 10h
.text:7DDED110                 mov     ecx, [eax]
.text:7DDED112                 mov     eax, [eax+4]
.text:7DDED115                 mov     [ebp+var_AC], ecx
.text:7DDED11B                 mov     [ebp+var_A8], eax
.text:7DDED121                 jbe     short loc_7DDED165
.text:7DDED123                 movzx   ecx, cx
.text:7DDED126                 mov     [ebp+var_90], ecx
.text:7DDED12C                 shr     ecx, 1
.text:7DDED12E                 push    ecx             ; size_t
.text:7DDED12F                 mov     ecx, [esi+4]
.text:7DDED132                 add     ecx, 8
.text:7DDED135                 push    ecx             ; wchar_t *
.text:7DDED136                 push    eax             ; wchar_t *
.text:7DDED137                 call    __wcsnicmp
.text:7DDED13C                 add     esp, 0Ch
.text:7DDED13F                 test    eax, eax
.text:7DDED141                 jnz     short loc_7DDED165
.text:7DDED143                 mov     eax, [esi+4]
.text:7DDED146                 mov     ecx, [ebp+var_90]
.text:7DDED14C                 lea     edi, [eax+ecx-8]
.text:7DDED150                 mov     esi, offset aSyswow64_0 ; "SysWOW64"
.text:7DDED155                 movsd
.text:7DDED156                 movsd
.text:7DDED157                 movsd
.text:7DDED158                 movsd
.text:7DDED159                 mov     esi, [ebp+var_94]
.text:7DDED15F                 mov     edi, [ebp+var_9C]
.text:7DDED165
.text:7DDED165 loc_7DDED165:                           ; CODE XREF: BasepMoveFileDelayed(x,x,x,x,x)+82j
.text:7DDED165                                         ; BasepMoveFileDelayed(x,x,x,x,x)+A2j
.text:7DDED165                 cmp     word ptr [edi], 10h
.text:7DDED169                 jbe     short loc_7DDED1C4
.text:7DDED16B                 mov     eax, [edi+4]
.text:7DDED16E                 xor     ecx, ecx
.text:7DDED170                 cmp     word ptr [eax], 21h
.text:7DDED174                 setz    cl
.text:7DDED177                 add     ecx, 4
.text:7DDED17A                 mov     edi, ecx
.text:7DDED17C                 movzx   ecx, word ptr [ebp+var_AC]
.text:7DDED183                 mov     [ebp+var_90], ecx
.text:7DDED189                 shr     ecx, 1
.text:7DDED18B                 push    ecx             ; size_t
.text:7DDED18C                 lea     eax, [eax+edi*2]
.text:7DDED18F                 push    eax             ; wchar_t *
.text:7DDED190                 push    [ebp+var_A8]    ; wchar_t *
.text:7DDED196                 call    __wcsnicmp
.text:7DDED19B                 add     esp, 0Ch
.text:7DDED19E                 test    eax, eax
.text:7DDED1A0                 jnz     short loc_7DDED1C4
.text:7DDED1A2                 mov     eax, [ebp+var_90]
.text:7DDED1A8                 lea     edi, [eax+edi*2-10h]
.text:7DDED1AC                 mov     eax, [ebp+var_9C]
.text:7DDED1B2                 add     edi, [eax+4]
.text:7DDED1B5                 mov     esi, offset aSyswow64_0 ; "SysWOW64"
.text:7DDED1BA                 movsd
.text:7DDED1BB                 movsd
.text:7DDED1BC                 movsd
.text:7DDED1BD                 movsd
.text:7DDED1BE                 mov     esi, [ebp+var_94]
 
Last edited:
Have you tried MoveFileEx() with any other arguments?

There shouldn't be a reference to Sysnative though because it doesn't actually exist. It's only something that the FSR knows about, and stays hidden to everything else. It's kind of like your employee thinking they know what they are doing, and then having some other guy fix the "issues" afterwards because he knows what he is doing. I assume you already know this though, as you know about Sysnative redirection, but I just felt like making an analogy there. :)

I suspect that the cause is that delaying the file move means that the lowest level file access functions never get called

Could be, at this point I can't verify anything for you... I really should have tried. But I didn't feel like having my system reboot at the time with all of the open work I had. I had HyperV turned off also, so I couldn't test with a VM either.

(and it can't do delayed redirection because otherwise System32 would be ambiguous)

What do you mean by this though? Nothing would be calling System32, the redirection would still redirect to the actual System32 folder because at the time of redirection System32 is not known, as sysnative is a virtual directory.

The way to debug this would be to see what calls to invoke the file move operation; the function MoveFileEx() with the Sysnative path; whether this parent process is 64 bit or not. It has to be 32 bit though as you say (WOW64), otherwise, as the documentation says, Sysnative will not work; it's unrecognized.

Believe this to be a bug in BasepMoveFileDelayed...

I don't think this is function based... It would depend on the architecture of the process which initializes the call to the function after the reboot.

There should be a way to hook this and find out though...

In my opinion though, because 64 bit processes are exluded. The ONLY way for this to work would be if the file move instructions, which indicate the move file operation is pending on startup, would have to know whether to be called from a 32 bit process or a 64 bit process with no adverse side affects; Sysnative doesn't exist in the string.

And next thing would be to make sure that we want to call the virtual Sysnative directory and not some other file in a physical Sysnative directory. That could be trouble otherwise for us members on Sysnative forums! (If someone makes an app that creates a folder with the Sysnative alias.) :lol:

Just don't create a Sysnative directory in the location where Sysnative's virtual directory is to be used... Now that could be ambiguous! Who knows... lol. Bottom line though is, all these functions do as they are intended. It depends on a conditional to decide whether a 32 bit process or 64 bit process invokes the function. Because there is no way for a 64 bit process to do anything with Sysnative if that's the case here... Disabling/Enabling direction in whatever way you want to twist things around, just won't work, because it depends on recognition for the virtual Sysnative directory and nothing else. That's my opinion. Because I highly doubt that Windows is going to load YOUR (32 bit) program, just to do the file move...

I would blame this on the Filesystem Redirector itself, for not allowing recognition for Sysnative from 64 bit processes. 64 bit processes can already interact with System32, so why not just allow it to be redirected anyways? There wouldn't be any harm in allowing people to use it, but I suspect it could fix this issue if there is an issue here. 64 bit works alongside 32 bit, but jumping from 32 bit to 64 bit doesn't work; hence why we can run 64 bit and 32 bit programs on a 64 bit OS, but not in reverse.

~Ace
 
Last edited:
Thank you again for your time. I'll try to clarify a couple of points from my rushed last post :p Here's how I see the situation.

Firstly, MoveFileEx with any other argument combination works perfectly.

Let's now make the assumption that automatic file system redirection (SysWOW64 & Sysnative redirection which works in every case...except across a reboot) works at the lowest level, so that the code is not duplicated. I am going to pretend (and I recognise that this is highly unlikely to be factually accurate, that this redirection occurs in a file system filter driver. This is just so I can save myself some typing later (you'll soon see why). So...FSR occurs in a driver. Please bear with me.)

When you call MoveFileEx to make the move now, the call sinks lower and lower until hitting the FS driver layer, and directory redirection comes into play when the FSR driver is called. Everything works well.

However, when you call MoveFileEx to make the replacement over the reboot, the function BasepMoveFileDelayed gets called, which sets the path into the PendingFileRenames registry value for processing over the reboot. Because no file is being moved now, the FSR driver never gets called, and so no redirection takes place. There is no automatic redirection, and the registry value gets set to exactly the string which is passed in. Happy so far?

So, e.g. if I call System32 from a WOW64 process, System32 gets written to the registry.

Now, over the reboot, the actual replacement is made by smss.exe. This is a 64bit process. Therefore, when it makes the move, redirection policies act as though it were a 64bit application. So System32 --> System32, SysWOW64 --> SysWOW64, Sysnative --> X

This works fine, but there's a critical problem. I passed System32 to MoveFileEx from my WOW64 process. This got left as System32 in the registry, and so eventually got redirected as System32 --> System32 from a 64bit process. This is not how the rest of the OS works. Under any other conditions, WOW64 System32 --> SysWOW64, which did not occur here. The automatic redirection policies simply do not work due to the transition from 32bit to 64bit process in the middle.

Fortunately, Microsoft recognised that there MUST be additional manual redirection to fix this issue (basically, to flip all of the redirections to transition from 32bit to 64bit). So they had two choices, redirection in smss.exe, or redirection in BasepMoveFileDelayed.

Let's first consider the possibility of redirection in smss.exe:

Let's consider how the registry gets set:

64bit Process: Passed in: System32: Where File Should End Up: System32
64bit Process: Passed in: SysWOW64: Where File Should End Up: SysWOW64
64bit Process: Passed in: Sysnative: Where File Should End Up: X

WOW64 Process: Passed in: System32: Where File Should End Up: SysWOW64
WOW64 process: Passed in: SysWOW64: Where File Should End Up: X
WOW64 process: Passed in: Sysnative: Where File Should End Up: System32

So...the smss.exe redirection needs to be as follows (top to bottom):

System32 --> System32 (no direction)
SysWOW64 --> SysWOW64 (no redirection)
System32 --> SysWOW64
Sysnative --> System32

But look at the red...there's a conflict. Depending on whether a 64bit or WOW64 bit process created the PendingFileRenames key, the redirection needs to vary. But this information is not saved. There is no way to overcome this (without changing the structure of the PendingFileRenames key), so redirection within smss.exe must be ruled out.

So...the alternative: redirection in BasepMoveFileDelayed before putting the data into the registry. Here, the bitness of the process is known, and that's very important.

The same redirections need to occur, but the bit-rate is known.

System32 --> System32 (if 64bit process)
SysWOW64 --> SysWOW64 (if 64bit process)
System32 --> SysWOW64 (if WOW64 process)
Sysnative --> System32 (if WOW64 process)

Therefore, this comes down to:

System32 --> SysWOW64 (if WOW64 process)
Sysnative --> System32 (if WOW64 process)

as no redirection is required for 64bit processes. So I looked at the code for BasepMoveFileDelayed, and I found this rule: System32 --> SysWOW64 for WOW64 processes. And that is correct. But we've also ascertained already that there must also be a Sysnative redirection rule. And there simply isn't.

This, almost without any doubt at all, is a bug in BasepMoveFileDelayed. Would you agree?

Richard

P.S. The only thing I haven't yet quite got straight is why Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection DOES work as a fix/workaround for this issue. I'm still investigating where the normal redirection takes place and how it fits into the above.
 
Last edited:
Firstly, MoveFileEx with any other argument combination works perfectly.

Correct! :) And this is because the function call is invoked directly from the program itself, 32 bit or 64 bit, and therefore does as intended when you reference Sysnative (assuming this is a 32 bit program, which it should be because the function can be invoked directly from that same program of a 32 bit architecture).

After a reboot, the way the File system redirector is set up, it doesn't have to know whether the string was referenced by a 32 bit or 64 bit program, because it can do the redirection right away.

But look at the red...there's a conflict. Depending on whether a 64bit or WOW64 bit process created the PendingFileRenames key, the redirection needs to vary.

I see what you are saying now. It was hard to read what you meant last time. Although there is no conflict here, for the reason that smss.exe is ONLY a 64 bit process. There is only the non-WOW64 redirections, and Sysnative -> System32 and System32 -> SysWOW64 don't exist. So I figure that when this location is set, it is set to assume that we are trying to get to the intended location from a 32 bit process, with the equivalent 64 bit redirection routines, because there can only be 64 bit redirections; smss.exe being only 64 bit.

So in sum, before the reboot is probably where things start to fall apart, as proven if you say that Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection calls, fix this issue... (The reason is because these functions are not global, they are based solely on the calling thread, which is super key here.)

This, almost without any doubt at all, is a bug in BasepMoveFileDelayed. Would you agree?

Hmmm... For this redirection to work, since smss.exe is a 64 bit process, the redirection would have to happen before the reboot, and Sysnative redirected to System32. When at startup, that 64 bit process calling to invoke some operation and using the redirected path to native "System32", would not redirect away from that intended location because it is a 64 bit process and System32 is reserved for 64 bit.

As for the Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection functions being a fix. This hints that some kind of manipulation does happen for the redirection before the reboot, because there is no way that Windows would boot up and recognize the function call from the previous Windows logon session, from the calling thread, to be invoked for the startup operation in some other process thread, and then disabled after the operations are carried out.

Something on a low level happens before the reboot, which must break this... And those functions "fix" it, but not allowing these things to happen.

I do have access to Windows source code... It is a bit hectic to look through and find what you want though unless you review it a lot. But I may be able to find some answers in there. I cannot share anything directly though, I would have to use it for my own information, and then find debuggable ways of proving this, in which others can follow along, to avoid any NDA or legal conflicts...

The call chains BasepMoveFileDelayed makes are:
Code:
1. RtlInitUnicodeString
2. __imp__swprintf
3. NtCreateKey
4. RtlAllocateHeap (NTDLL)
5. NtQueryValueKey
6. RtlFreeHeap (NTDLL)
7. NtClose
8. NtSetValueKey

~Ace
 
Last edited:
\sysnative is a virtual copy of \system32 for x86 apps.

I would think moving a file from \sysnative would not affect \system32 ...?
 
\sysnative is a virtual copy of \system32 for x86 apps.

I would think moving a file from \sysnative would not affect \system32 ...?

%WinDir%\Sysnative is the exact virtual directory for the location that the FSR recognizes for WOW64 processes yes. It just seems odd. If redirection does not occur however, then if you do have a physical location in place of the virtual one, I would expect that things happen to that physical location and not the redirected location for System32.
 
What OS does this reproduce on? I'd be curious if it reproduced on Windows 8 / Server 2012, but not surprised if it reproduced on Win7 / 2008R2 or older. Yes, the flags you're passing are the ones I'm curious on for MoveFileEx on which OS it reproduces on.
 
@AceInfinity: Still trying to find time to reply - I promise I'm not ignoring you!

What OS does this reproduce on? I'd be curious if it reproduced on Windows 8 / Server 2012, but not surprised if it reproduced on Win7 / 2008R2 or older. Yes, the flags you're passing are the ones I'm curious on for MoveFileEx on which OS it reproduces on.

Thank you very much for your input. I'm just testing this (previously I have only tested on Windows 7), but it looks like it does reproduce on Windows 8. I can confirm already that Sysnative is still written to the registry as is and without redirection, but have yet to reboot and check whether it is redirected later, or any other changes in behavior (after all, it is possible to generate ideal redirection behavior with redirection split before and after the reboot, and I have yet to test all cases of this). But so far...Sysnative-->Sysnative.

Richard
 
@AceInfinity: Still trying to find time to reply - I promise I'm not ignoring you!

What OS does this reproduce on? I'd be curious if it reproduced on Windows 8 / Server 2012, but not surprised if it reproduced on Win7 / 2008R2 or older. Yes, the flags you're passing are the ones I'm curious on for MoveFileEx on which OS it reproduces on.

Thank you very much for your input. I'm just testing this (previously I have only tested on Windows 7), but it looks like it does reproduce on Windows 8. I can confirm already that Sysnative is still written to the registry as is and without redirection, but have yet to reboot and check whether it is redirected later, or any other changes in behavior (after all, it is possible to generate ideal redirection behavior with redirection split before and after the reboot, and I have yet to test all cases of this). But so far...Sysnative-->Sysnative.

Richard

This is the problem then. The only way this would work is if redirection happened before the reboot because a 64 bit process will not be able to read that (forgotten) "SysNative" virtual location. It's undefined at startup I bet. The NtSetValueKey call sets Sysnative as though it is a physical path, and it is also attempted to be read as one when the action takes place. I am also convinced this is probably a bug. (~Followup conclusion from my last post).

I have HyperV re-enabled now... I will have to re-create a Windows 8 VM due to an incident I had, but all other VM's I had still work. I'll try doing some testing after I get back home in a few hours. :)

~Ace
 
@AceInfinity: Still trying to find time to reply - I promise I'm not ignoring you!

What OS does this reproduce on? I'd be curious if it reproduced on Windows 8 / Server 2012, but not surprised if it reproduced on Win7 / 2008R2 or older. Yes, the flags you're passing are the ones I'm curious on for MoveFileEx on which OS it reproduces on.

Thank you very much for your input. I'm just testing this (previously I have only tested on Windows 7), but it looks like it does reproduce on Windows 8. I can confirm already that Sysnative is still written to the registry as is and without redirection, but have yet to reboot and check whether it is redirected later, or any other changes in behavior (after all, it is possible to generate ideal redirection behavior with redirection split before and after the reboot, and I have yet to test all cases of this). But so far...Sysnative-->Sysnative.

Richard

This is the problem then. The only way this would work is if redirection happened before the reboot because a 64 bit process will not be able to read that (forgotten) "SysNative" virtual location. It's undefined at startup I bet. The NtSetValueKey call sets Sysnative as though it is a physical path, and it is also attempted to be read as one when the action takes place. I am also convinced this is probably a bug. (~Followup conclusion from my last post).

I have HyperV re-enabled now... I will have to re-create a Windows 8 VM due to an incident I had, but all other VM's I had still work. I'll try doing some testing after I get back home in a few hours. :)

~Ace

Well....smss.exe (or whatever it is in Windows 8 - I shall assume (but don't know for certain) that the SM maintains this job) *could* do a simple if statement on "Sysnative" and change it to "System32" before processing. It could, but I'm skeptical that it would.

After all, as long as all the ambiguous references are redirected with prior to the reboot, the non-ambiguous references such as "Sysnative" which only goes to one place could be dealt with after the reboot. And no, I have genuinely no idea why they would ever do that :p
 
@AceInfinity: Still trying to find time to reply - I promise I'm not ignoring you!

What OS does this reproduce on? I'd be curious if it reproduced on Windows 8 / Server 2012, but not surprised if it reproduced on Win7 / 2008R2 or older. Yes, the flags you're passing are the ones I'm curious on for MoveFileEx on which OS it reproduces on.

Thank you very much for your input. I'm just testing this (previously I have only tested on Windows 7), but it looks like it does reproduce on Windows 8. I can confirm already that Sysnative is still written to the registry as is and without redirection, but have yet to reboot and check whether it is redirected later, or any other changes in behavior (after all, it is possible to generate ideal redirection behavior with redirection split before and after the reboot, and I have yet to test all cases of this). But so far...Sysnative-->Sysnative.

Richard

This is the problem then. The only way this would work is if redirection happened before the reboot because a 64 bit process will not be able to read that (forgotten) "SysNative" virtual location. It's undefined at startup I bet. The NtSetValueKey call sets Sysnative as though it is a physical path, and it is also attempted to be read as one when the action takes place. I am also convinced this is probably a bug. (~Followup conclusion from my last post).

I have HyperV re-enabled now... I will have to re-create a Windows 8 VM due to an incident I had, but all other VM's I had still work. I'll try doing some testing after I get back home in a few hours. :)

~Ace

Well....smss.exe (or whatever it is in Windows 8 - I shall assume (but don't know for certain) that the SM maintains this job) *could* do a simple if statement on "Sysnative" and change it to "System32" before processing. It could, but I'm skeptical that it would.

After all, as long as all the ambiguous references are redirected with prior to the reboot, the non-ambiguous references such as "Sysnative" which only goes to one place could be dealt with after the reboot. And no, I have genuinely no idea why they would ever do that :p

This would be a redirection regardless of 32 bit or 64 bit before the reboot though if that was done that way. It would work I suppose, but it would be an inevitable redirection in both cases.

Thus there would be no possibility of using a physical %WinDir%\Sysnative location, but I would assume it would be poor to be doing this anyways. :)
 
Thank you very much for your input. I'm just testing this (previously I have only tested on Windows 7), but it looks like it does reproduce on Windows 8. I can confirm already that Sysnative is still written to the registry as is and without redirection, but have yet to reboot and check whether it is redirected later, or any other changes in behavior (after all, it is possible to generate ideal redirection behavior with redirection split before and after the reboot, and I have yet to test all cases of this). But so far...Sysnative-->Sysnative.
Thanks for the follow-up - I've sent you a PM.
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top