; PCWSTR __stdcall RtlGetNtSystemRoot()
                public RtlGetNtSystemRoot
RtlGetNtSystemRoot proc near            ; CODE XREF: LdrpBuildSystem32FileName+1A↑p
                                        ; _IsOverlaySupportedPath+2B↓p ...

; FUNCTION CHUNK AT .text:00000001800B5A2A SIZE 00000019 BYTES

                sub     rsp, 28h
                call    RtlGetCurrentServiceSessionId
                test    eax, eax
                jnz     ReadFromPEB
                mov     eax, offset UserSharedData.NtSystemRoot ; was 7FFE0030h instead of the offset

loc_18003C806:                          ; CODE XREF: RtlGetNtSystemRoot+7924E↓j
                add     rsp, 28h
; ---------------------------------------------------------------------------
                db 0CCh
RtlGetNtSystemRoot endp

(NB: ReadFromPEB is uninteresting for this discussion.)

When I originally decompiled this code, it looked somewhat like this (even without the cast on the second return):

PCWSTR __stdcall RtlGetNtSystemRoot()
  if ( RtlGetCurrentServiceSessionId() )
    return (NtCurrentPeb()->SharedData + 0x30);
    return 0x7ffe0030i64;

The color of the second return value suggested something was wrong, so I went ahead and made the address known to IDA.

Now, UserSharedData is a struct (based on the imported standard struct _KUSER_SHARED_DATA) which resides in its own segment which I declared at 0x7FFE0000. I declared the segment with the current size of the struct (0x720) to fit it snugly.

It looks like this:

_user_shared_data segment para public '' use64
                assume cs:_user_shared_data
                ;org 7FFE0000h
                assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
UserSharedData  _KUSER_SHARED_DATA <?>  ; DATA XREF: LdrpGenSecurityCookie+4A↓r
                                        ; LdrpGenSecurityCookie+53↓r ...
_user_shared_data ends

After that I changed the original disassembly line:

mov     eax, 7FFE0030h


mov     eax, offset UserSharedData.NtSystemRoot

Alas, when I closed all the "Pseudocode" windows and then hit F5 again, the output remained the same. Thinking I'd be able to adjust it through the Edit menu I found all relevant menu items disabled there.

However, then I went ahead typing up my question here (which in the end had to be changed completely once again) just to go back to IDA and see that the Peudocode view had finally caught up to my change of the segment and the disassembly:

PCWSTR __stdcall RtlGetNtSystemRoot()
  if ( RtlGetCurrentServiceSessionId() )
    return (NtCurrentPeb()->SharedData + 30);
    return UserSharedData.NtSystemRoot;

I've had this lag before and found it somewhat annoying. I assume it's perhaps an expensive operation that runs in the background every now and then.

Question: But can I perhaps also force IDA to sync the knowledge the disassembler has with that of the decompiler so such changes take effect immediately in the pseudo-code?


1 Answer 1


A "heavy-weight" answer to this question would be that you can force the decompiler to flush all decompilation caches that it maintains via Edit->Other->Reset decompiler information, then selecting (only) All caches. This does what it sounds like, and forces Hex-Rays to re-decompile every function rather than relying upon cached results the next time around. Of course, this will increase the amount of time it takes for Hex-Rays to decompile any function the next time around, since it won't be able to use cached results.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.