Skip to content

Conversation

@susMdT
Copy link

@susMdT susMdT commented Mar 4, 2024

Replaced how the syscall stubs are used

  • Rather than calling NtProtectVirtualMemory on the stub to make it RX and flip back to RW, a sacrificial method is jitted which contains enough space for the syscall stub to be written into.
  • The jitted method address is RWX, so no protect calls are needed
  • unsafe code is used to copy the stub bytes directly so no need for Marshal.Copy or w/e. only tested on .net framework.

Added wow64 support

  • Added a wow64 stub Wow64IndirectSyscallStub in Syscalls.cs and added questionable (but working) logic to GetSyscallStub to account for wow64
  • Wow64 has only been tested for the syscall related stuff and not the generic class

Added more unit tests

  • Added more unit tests. in x64 1000 runs went cleanly but in x86 would GenericTests.GetUnloadedLibraryAddress would fail after 20 or so iterations.
  • unit tests changed to .net framework instead of .net 8

@rasta-mouse
Copy link
Owner

Hi @susMdT, thanks for the awesome PR. What's the reason for the Unit Tests needing to be .NET Framework?

@susMdT
Copy link
Author

susMdT commented Mar 11, 2024

Glad you like the changes, I've been wanting to contribute this technique to a project for a while and this one seemed perfect.

I changed the unit tests to .NET Framework since I saw that the Sample was in .net framework, if I'm not mistaken. Additionally, this JIT technique (originally from am0nsec's hellsgate implementation) works on .net framework, and only .net 5/6. I haven't gotten it successfully working on 7/8 nor did I see as many RWX pages as before; I suspect there are changes which break the tech.

If you would like, I could modify the PR to account for different versions of .NET by checking if the technique is possible and falling back to a dynamic call to ntprotect if it is not possible

@rasta-mouse
Copy link
Owner

Ah fair enough, I don't anticipate many .NET (core) projects using this, (sorry @checkymander). I was more asking because the project didn't want to load for me in Rider 😅

@susMdT
Copy link
Author

susMdT commented Mar 11, 2024

Oh, I've been using visual studio and had to do some manual work to make the project files work, so that might explain the jank, sorry about that. Yeah I didn't expect many .net (core) projects using this since I thought most tooling is done in framework(?), but idk much 🤷

@checkymander
Copy link

Ah fair enough, I don't anticipate many .NET (core) projects using this, (sorry @checkymander). I was more asking because the project didn't want to load for me in Rider 😅

Despite this statement I'm still using it 😂

Couldn't you target it for .net standard? That way both could use it easily

@rasta-mouse
Copy link
Owner

The code generator itself is .NET Standard 2.0, so it will codegen for both Framework and Core. The question would be if the actual JIT magic code that it generates is actually useable on both. Based on what @susMdT has experienced, we can expect it to work for any(?) .NET Framework version, as well as .NET 5/6, but nothing above.

@susMdT
Copy link
Author

susMdT commented Mar 11, 2024

I'll do more testing, but at least for .net 5/6 and framework 4+ it works fine. As a fallback, I can add a check to see if the jit tech is possible and fall back on the original ntprotect call if its not possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants