microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.52k stars 822 forks source link

WSL2 and Ryzen Master - Virtualization Based Security. #4771

Closed rwilliams closed 3 years ago

rwilliams commented 4 years ago
  1. I've found the DG Readiness Tool via reddit which allows disabling VBS but it doesn't persist through reboots. Would it be possible to disable VBS persistently?
  2. Is uninstalling and re-installing Virtual Machine Platform as needed better work around? I did notice my existing distro wouldn't boot after re-installing Virtual Machine Platform until I loaded another distro from the Windows Store. wsl --shutdown also just hangs. It seems like installing a new distro re-initializes tome things broken from adding and removing Virtual Machine Platform. *It might just take a 2nd reboot.

Dyanamic Ryzen Master Patcher https://github.com/milesburchell/RyzenMasterVBSFix thanks @milesburchell

Current Offsets With the offset you change 0F 84 to 90 E9

Build 2.2.0.1543 3000 Series

2000 Series

1000 Series

Build 2.1.1.1472 3000 Series

2000 Series

1000 Series

onomatopellan commented 4 years ago

Try disabling Memory integrity. https://techcommunity.microsoft.com/t5/Windows-Insider-Program/Windows-Defender-System-Guard-Making-a-leap-forward-in-platform/m-p/167303

rwilliams commented 4 years ago

@onomatopellan Thanks for that link. Memory Integrity is disabled.

onomatopellan commented 4 years ago

VBS is not the problem then. WSL2 enables an Hyper-V component and it seems Ryzen Master v1.3 won't work with Hyper-v enabled. You can read more here https://community.amd.com/thread/241792

With each new version Windows 10 adds more and more Hyper-V components (WSL2, Sandbox, VBS...) so AMD just needs to update their software to make it compatible.

rwilliams commented 4 years ago

@onomatopellan When you reboot after using the DG Readiness Tool you are prompted with this IMG_20191218_144631 Disabling that allows Ryzen master to work alongside WSL2, but it doesn't persist between reboots.

MostHated commented 4 years ago

I have not seen that come up, so I have not been able to test it. Is there any confirmation or this, or a way to force that dialog to show so I can test it?

MostHated commented 4 years ago

Hmmm... nevermind, I just tried again and now it came up. I disabled it and WSL2 is still working, and I was able to open Ryzen Master. Thanks for that, I spent hours on AMD forums and other places trying to find something that would work, even trying the Readiness tool before but it didn't seem to work before.

Stanzilla commented 4 years ago

You can HEX edit RyzenMaster.exe to remove the check for that as well and it works fine.

rwilliams commented 4 years ago

Interesting. If it works fine with VBS enabled why are they doing the check in the first place.

Stanzilla commented 4 years ago

That's a question neither their Twitter, nor their Forum and Email support could answer me. All I got was

The feedback from our software team is that the incompatibility lies with VBS limiting Ryzen Master access to specific system resources.

We are currently looking into this limitation, but do not have any specific timeline as to when a solution will be available.

Thanks for contacting AMD. 
rwilliams commented 4 years ago

@Stanzilla Can you email the detail on the hex edit? My email is on my profile if you click it.

Stanzilla commented 4 years ago

I can just link this Tweet by @tomrus88 https://twitter.com/TOM_RUS/status/1204867886197755904

yunghoy commented 4 years ago

This was why I uninstalled WSL2 and installed Linux on my external ssd. The only reason I was on the fast ring instead of 19h1 was for WSL2 but it seemed useless because my cpu was not that great without Ryzen Master.

rwilliams commented 4 years ago

I did the same thing, put Ubuntu on a spare SSD as it was less hassle than rebooting to disable VBS or WSL.

onomatopellan commented 4 years ago

Another succesfull story on how to run Ryzen Master with WSL2: https://twitter.com/steeve/status/1222282378648924163

rwilliams commented 4 years ago

Has anyone using it with the hex edit seen any issues with Ryzen Master? It's like AMD is checking for it but it doesn't actually effect the software?

rwilliams commented 4 years ago

@benhillis Can we get an official response to this? There are a lot of people in this boat and it's pretty frustrating at the moment.

Stanzilla commented 4 years ago

It's AMD's fault not Microsoft's. And yeah, I've been running a HEX edited version just fine over the last few months.

rwilliams commented 4 years ago

I understand it's not Microsoft's fault but maybe MS and AMD could work together and figure out why this is even a thing? For a long time Ryzen Master didn't do this check so I don't understand why they need VBS disabled now.

orangpelupa commented 4 years ago

anyone have the hex edit for the latest ryzen master? the hex offset has changed :(

AntiPhotonz commented 4 years ago

For version 2.1.1.1472 the offset is 0x0158C0.

tautomer commented 4 years ago

For version 2.1.1.1472 the offset is 0x0158C0.

Can confirm it works with 2.1.1.1472.

codewerfer commented 4 years ago

For version 2.1.1.1472 the offset is 0x0158C0.

To keep it exact, it is at 0x0158C7.

skythian commented 4 years ago

My Hex at that offset is different... This is 2.1.1.1472 Annotation 2020-02-24 092332

tommyvct commented 4 years ago

Same. I even tried to find the previous and after bytes in the file but nothing was found. They must have changed the memory map without our knowledge.

codewerfer commented 4 years ago

I've downloaded it again and reinstalled it. Seams to stay at version 2.1.1.1472: Signed at 27.01.2020 09:13:41 by Advanced Micro Devices INC. (fingerprint ef03f44c216eaf43950f7f7f13c683885904f46d) Filesize: 817920 Bytes (798 KiB) CRC32: 0EE45B94

Installed (and downloaded) for Ryzen 9 3950X - makes the only reason for my why there is a difference for the same "version".

Stanzilla commented 4 years ago

It should have 0F 84 at 0x0158c7 and you change that to 90 E9, worked fine here with Master 2.1.1.1472

AntiPhotonz commented 4 years ago

Searching for 0F84F7000000 might work if the address of the jump hasn't changed. Then it's just a matter of trying all returned results for the one that works.

tommyvct commented 4 years ago

It should have 0F 84 at 0x0158c7 and you change that to 90 E9, worked fine here with Master 2.1.1.1472

Nope. image

Searching for 0F84F7000000 might work if the address of the jump hasn't changed. Then it's just a matter of trying all returned results for the one that works.

Nope. image

tommyvct commented 4 years ago

Installed (and downloaded) for Ryzen 9 3950X - makes the only reason for my why there is a difference for the same "version".

I have a Ryzen 5 1600.

gavin19 commented 4 years ago

I have a Ryzen 5 1600.

I get the same 74 24 as you, and also a Gen 1 (1800x). File size is also different (854KB), and it was signed 24/9/19.

I'm still using a pre 1.3 build which doesn't need any special tweaks to run. Are the newer versions even worth using for Gen 1 anyway? The only difference I can see is that the newer versions have the SMT toggle.

Edit: The main draw was that I could set CPU frequencies/voltage without needing to reboot. Newer versions (>1.5, maybe since 1.3) require a reboot, which defeats the purpose for me. I use 1.0.1.0239 (ideally I'd like 1.2.x but impossible to find). With Windows I can only either get max (4GHz), or 2.2GHz (enabling power saving mode).

EDIT: Changed to a 3600 and the offset matches the other Zen 2 offsets.

For those not sure what to do -

tautomer commented 4 years ago

It's 0x0158C0 for my Ryzen Master version 2.1.1.1472 and I have a 3800X. So Ryzen Master binary is different for different CPU's?

gabriel-peracio commented 4 years ago

Tl;DR: I have a 2700x and my offset was 0x0125E9. Seems like the binaries are different.

My Ryzen master version is 2.1.1.1472 and AMD Ryzen Master.exe has a SHA-1 of 9470C71DB450FAD40B4972AD8B22F10B3086174E.

I could not find anything appropriate at 0x0158c7 so here's what I did:

  1. Download IDA freeware
  2. Open AMD Ryzen Master.exe (it will ask you for a bunch of things. I don't know what difference they make. The defaults were fine for me. You probably have to run IDA as admin so that it is able to edit the file in C:/Program Files/)
  3. hit ctrl+L (or jump>jump by name)
  4. select aVirtualization in the window that opens
  5. on the window that opens, right click the blue aVirtualization (it's the second "column") and select Jump to xref to operand.... You should now see a graph visualization of the code. This is the code that invokes the nag message box (since it references the string contained in that message)
  6. Double click the arrows going into said box (do not make the mistake I did and click the arrows going away from the box, this is the code that displays the nag message, there's no point to going there). This will take you to whatever code invoked the one you're currently looking at. Keep going "backwards" until you find a box that looks like the one in the tweet (https://twitter.com/steeve/status/1222277573624975366/photo/1). It ends with a jz to some offset.
  7. Click the jz. On the info bar at the bottom of the window, you will see the address. Mine was 000125E9.
  8. Armed with that offset, you can now open whatever your hex editor is and go to that offset. You should see 0F 84. Change that to 90 E9.
  9. Profit

I know nothing about IDA and this was my first time debugging like this. I'm glad I had that tweet with the screenshots so I could at least see if I was getting closer!

This was fun πŸ˜…

WestCruX commented 4 years ago

Tl;DR: I have a 2700x and my offset was 0x0125E9. Seems like the binaries are different.

My Ryzen master version is 2.1.1.1472 and AMD Ryzen Master.exe has a SHA-1 of 9470C71DB450FAD40B4972AD8B22F10B3086174E.

I could not find anything appropriate at 0x0158c7 so here's what I did:

  1. Download IDA freeware
  2. Open AMD Ryzen Master.exe (it will ask you for a bunch of things. I don't know what difference they make. The defaults were fine for me.)
  3. hit ctrl+L (or jump>jump by name)
  4. select aVirtualization in the window that opens
  5. on the window that opens, right click the blue aVirtualization (it's the second "column") and select Jump to xref to operand.... You should now see a graph visualization of the code. This is the code that invokes the nag message box (since it references the string contained in that message)
  6. Double click the arrows going into said box (do not make the mistake I did and click the arrows going away from the box, this is the code that displays the nag message, there's no point to going there). This will take you to whatever code invoked the one you're currently looking at. Keep going "backwards" until you find a box that looks like the one in the tweet (https://twitter.com/steeve/status/1222277573624975366/photo/1). It ends with a jz to some offset.
  7. Click the jz. On the info bar at the bottom of the window, you will see the address. Mine was 000125E9.
  8. Armed with that offset, you can now open whatever your hex editor is and go to that offset. You should see 0F 84. Change that to 90 E9.
  9. Profit

I know nothing about IDA and this was my first time debugging like this. I'm glad I had that tweet with the screenshots so I could at least see if I was getting closer!

This was fun πŸ˜…

Can you make a little video to explaine how to edit? From the fifth point i'm lost πŸ˜… thanks a lot in advance!

gabriel-peracio commented 4 years ago

Maybe the following images help:

Steps 3 and 4: ida1

Step 5: ida2

Steps 5 and 6 (after confirming your selection, you should arrive here. Notice the current selected node has a blue highlight at the top. Double clicking the arrows leading into that box focuses on whatever box leads to that one. You can also visually follow the arrows if you prefer): ida3

Step 7 (You can reach this box fairly quickly, by double clicking the red arrow at the top of the image above, then just copy the address IDA gives you): ida4

tommyvct commented 4 years ago

@gabriel-peracio Hell yeah it worked!!!!! Thank you so much!!!!

rwilliams commented 4 years ago

So can we pin down how many different versions there are of the executable per release? I've got a 3950x and used 0x0158C7. Also I can update the main post with the current offsets per version if folks can provide them for 2000's and 1000's cpu's.

Stanzilla commented 4 years ago

3900x and 0x0158c7

rwilliams commented 4 years ago

I'll try and keep the main post updated as offsets get posted.

tautomer commented 4 years ago

3800x and 0x150C0. I guess it's related to generations and aslo die configurations, since 3900x/3950x have different offset from 3800x. So the offset for 3700x should also be 0x158C0.


@rwilliams oops, I made a typo. It's 158C0. Sorry about that.

skythian commented 4 years ago

@gabriel-peracio Amazing. Nice job! For Threadripper 1900X the offset is 0x00c5a2.

Xeno1177 commented 4 years ago

Used 0x0158C7 for 3900x and confirmed the offset with IDA using the instructions above. When running Ryzen Master, the splash screen displays then the system reboots. Any thoughts on what I might have done wrong? Running Master 2.1.1.1472

thomasczer commented 4 years ago

https://github.com/microsoft/WSL/issues/4771#issuecomment-593188388 Can confirm this worked on my 3600 too. Thanks!

WestCruX commented 4 years ago

Maybe the following images help:

Steps 3 and 4: ida1

Step 5: ida2

Steps 5 and 6 (after confirming your selection, you should arrive here. Notice the current selected node has a blue highlight at the top. Double clicking the arrows leading into that box focuses on whatever box leads to that one. You can also visually follow the arrows if you prefer): ida3

Step 7 (You can reach this box fairly quickly, by double clicking the red arrow at the top of the image above, then just copy the address IDA gives you): ida4

Thank you very much! Y've saved my Ryzen Master!

stevefan1999-personal commented 4 years ago

Tl;DR: I have a 2700x and my offset was 0x0125E9. Seems like the binaries are different.

My Ryzen master version is 2.1.1.1472 and AMD Ryzen Master.exe has a SHA-1 of 9470C71DB450FAD40B4972AD8B22F10B3086174E.

I could not find anything appropriate at 0x0158c7 so here's what I did:

1. Download IDA freeware

2. Open `AMD Ryzen Master.exe` (it will ask you for a bunch of things. I don't know what difference they make. The defaults were fine for me. You probably have to run IDA as admin so that it is able to edit the file in `C:/Program Files/`)

3. hit `ctrl+L` (or `jump`>`jump by name`)

4. select `aVirtualization` in the window that opens

5. on the window that opens, right click the blue `aVirtualization`  (it's the second "column") and select `Jump to xref to operand...`. You should now see a graph visualization of the code. This is the code that invokes the nag message box (since it references the string contained in that message)

6. Double click the arrows going into said box (do not make the mistake I did and click the arrows going away from the box, this is the code that displays the nag message, there's no point to going there). This will take you to whatever code invoked the one you're currently looking at. Keep going "backwards" until you find a box that looks like the one in the tweet (https://twitter.com/steeve/status/1222277573624975366/photo/1). It ends with a `jz` to some offset.

7. Click the `jz`. On the info bar at the bottom of the window, you will see the address. Mine was `000125E9`.

8. Armed with that offset, you can now open whatever your hex editor is and go to that offset. You should see `0F 84`. Change that to `90 E9`.

9. Profit

I know nothing about IDA and this was my first time debugging like this. I'm glad I had that tweet with the screenshots so I could at least see if I was getting closer!

This was fun πŸ˜…

I might have an alternative way to do this.

So if you decompile the function you can see much clearer what that jump is doing.

And sub_14003E5E0 is can actually be called "CheckVirtualizationBasedSecurityStatus", according to one snippet in the decompiled function:

Let's go back to the original function, then we can clearly deduce that "CheckVirtualizationBasedSecurityStatus" is an out function, and we passed a temporary variable probably so that this will store the value determining whether the system is running under hypervisor or not.

Let's go back to the assembly, you can see that all is making sense:

Thus, we can either patch the jump, or we can actually patch the function call.

The signature to the call I found out is "E8 ? ? ? ? 44 39 6D A8". This is not guaranteed for future major updates if the execution path/optimization is changed.

We can then patch the call with nops. Very vile but it should work.

Aaaaaaaand success! I patched it with nops and I can launch my Ryzen Master!

However this will probably invalidate the digital signature, and AVs/ACs will be susceptible to that application. Remember to restore your backup file after using the patched Ryzen Master.

Stanzilla commented 4 years ago

There is a a new version, 2.2.0.1543, which still does not work with VBS enabled.

AntiPhotonz commented 4 years ago

For my ryzen 3900x, the offset for version 2.2.0.1543 is 0x0163E7.

Allaen commented 4 years ago

For my ryzen 3900x, the offset for version 2.2.0.1543 is 0x0163E7.

Can you tell which new value we should enter at the offset? Thanks

rwilliams commented 4 years ago

https://github.com/microsoft/WSL/issues/4771#issuecomment-593633375

Armed with that offset, you can now open whatever your hex editor is and go to that offset. You should see 0F 84. Change that to 90 E9.

rwilliams commented 4 years ago

For my ryzen 3900x, the offset for version 2.2.0.1543 is 0x0163E7.

Works for 3950x as well.

stevefan1999-personal commented 4 years ago

Well, regarding that I have also made a little Go script that automatically patches the Ryzen Master to work with WSL2 -- Based on my method:

package main

import (
    "bufio"
    "errors"
    "fmt"
    "io"
    "os"
    "path"
    "time"

    "rsc.io/binaryregexp"
)

type PatchUnitExecutableInfo struct {
    dirPath string
    name    string
}

type PatchUnit struct {
    regex      *binaryregexp.Regexp
    executable PatchUnitExecutableInfo
}

var ryzenMaster = PatchUnit{
    binaryregexp.MustCompile("(\u00E8.{4})\u0044\u0039\u006D\u00A8"),
    PatchUnitExecutableInfo{path.Join(os.Getenv("ProgramW6432"), "AMD", "RyzenMaster", "bin"), "AMD Ryzen Master.exe"},
}

func patchRyzenMaster() error {
    joinDirPath := func(name string) string {
        return path.Join(ryzenMaster.executable.dirPath, name)
    }

    if fp, err := os.OpenFile(joinDirPath(ryzenMaster.executable.name), os.O_RDWR, 0666); err != nil {
        return err
    } else {
        defer fp.Close()
        createBackup := func() error {
            t := time.Now()
            formatted := fmt.Sprintf("%d-%02d-%02dT%02d-%02d-%02d",
                t.Year(), t.Month(), t.Day(),
                t.Hour(), t.Minute(), t.Second())
            fp.Seek(0, io.SeekStart)
            if fpBackup, err := os.Create(joinDirPath(fmt.Sprintf("%s-%s.bak", ryzenMaster.executable.name, formatted))); err != nil {
                return err
            } else {
                defer fpBackup.Close()
                _, err := io.Copy(fpBackup, fp)
                return err
            }
        }

        reader := bufio.NewReader(fp)
        i, err := fp.Seek(0, io.SeekCurrent)
        if err != nil {
            return err
        }
        strMatch := ryzenMaster.regex.FindReaderSubmatchIndex(reader)
        if len(strMatch) <= 0 {
            return errors.New("can't find the signature")
        }
        fmt.Printf("[+] Found the signature from Ryzen Master at 0x%X!\n", strMatch[2])
        if err := createBackup(); err != nil {
            return err
        }
        fmt.Println("[+] Backup of Ryzen Master created!\n")
        if _, err = fp.Seek(i, io.SeekStart); err != nil {
            return err
        }
        if _, err = fp.WriteAt([]byte{0x90, 0x90, 0x90, 0x90, 0x90}, int64(strMatch[2])); err != nil {
            return err
        }
        fmt.Printf("[+] Written NOPs to 0x%X!\n", strMatch[2])
    }
    return nil
}

func main() {
    if err := patchRyzenMaster(); err != nil {
        panic(err)
    } else {
        fmt.Println("Ryzen Master is now patched to work with WSL2!")
    }
}

Now golang is really making me sick. I hope in the future I don't have to work with Golang, this is really really long and annoying and verbose as hell. (well, there are much more worse language such as Python)