GithubHelp home page GithubHelp logo

dewera / lunar Goto Github PK

View Code? Open in Web Editor NEW
583.0 27.0 102.0 398 KB

A lightweight native DLL mapping library that supports mapping directly from memory

License: MIT License

C# 96.45% C++ 1.82% Batchfile 0.14% CMake 1.59%
dll-injection reverse-engineering windows-internals

lunar's Introduction

Lunar

A lightweight native DLL mapping library that supports mapping directly from memory

Deprecation Notice

Please checkout https://github.com/jdewera/lunar for a continuation of this project.

As of 10/2023 this repository is deprecated and the project is now being maintained under a new account/repository due to some issues encountered with this account. There are some minor differences between the versions for maintainabiltiy sake (prefer private ntdll functions instead of manual setup) but otherwise they should be compatible.


Notable features

  • Control flow guard setup
  • Exception handler initialisation
  • Security cookie generation
  • Static TLS initialisation
  • SxS dependency resolution
  • TLS callback execution
  • WOW64 and x64 support

Caveats

  • The latest version of the PDB for ntdll.dll is downloaded and cached on disk by the library

Getting started

The example below demonstrates a basic implementation of the library

var process = Process.GetProcessesByName("")[0];
var dllFilePath = "";
var flags = MappingFlags.DiscardHeaders;
var mapper = new LibraryMapper(process, dllFilePath, flags);

mapper.MapLibrary();

LibraryMapper Class

Provides the functionality to map a DLL from disk or memory into a process

public sealed class LibraryMapper

Constructors

Initialises an instance of the LibraryMapper class with the functionality to map a DLL from memory into a process

public LibraryMapper(Process, Memory<byte>, MappingFlags);

Initialises an instance of the LibraryMapper class with the functionality to map a DLL from disk into a process

public LibraryMapper(Process, string, MappingFlags);

Properties

The base address of the DLL in the process

public nint DllBaseAddress { get; }

Methods

Maps the DLL into the process

public void MapLibrary();

Unmaps the DLL from the process

public void UnmapLibrary();

MappingFlags Enum

Defines actions that the mapper should perform during the mapping process

[Flags]
public enum MappingFlags

Fields

Default value

MappingsFlags.None

Specifies that the header region of the DLL should not be mapped

MappingsFlags.DiscardHeaders 

Specifies that the entry point of any TLS callbacks and the DLL should not be called

MappingsFlags.SkipInitRoutines

lunar's People

Contributors

dewera avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lunar's Issues

Importing problems

Predefined type 'System.Runtime.CompilerServices.IsExternallnit' is not defined or imported after i set the language version to 9.0. am i doing something wrong?

Freezes program while injecting -> waiting for URL URI response

Hey I am using your Library and trying ot inject a dll doing it the following way:

var process = Process.GetProcessesByName(ProcessName)[0];
var dllFilePath = Path.GetTempPath() + DllName + ".dll";
var flags = MappingFlags.None;
var mapper = new LibraryMapper(process, dllFilePath, flags);
mapper.MapLibrary();

Somehow the injector freezes while injecting, and I traced it down to this function in SymbolHandler.cs:

using var response = await httpClient.GetAsync(new Uri($"https://msdl.microsoft.com/download/symbols/{pdbData.Path}/{pdbData.Guid:N}{pdbData.Age}/{pdbData.Path}"));

I kept waiting for a few minutes but nothing happened, I guess it waits for a response but can't reach the url?

The first 2 requests worked, then it just freezed the program.

dotnet Standard

Changing project type to dotnet standard with a nuget package would be nice for those who use dotnet framework for the winforms

Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

This is an awesome project that I saw months ago and finally have a reason to use now!
Just cloned the repo, compiled it, and added it as an assembly reference my project is using .net core 3.1.
This is what my code looks like:

var dllstring = base64encoded_dll;
ReadOnlyMemory<byte> data = Convert.FromBase64String(dllstring);
Process process = Process.GetCurrentProcess();
var libraryMapper = new Lunar.LibraryMapper(process, data);
libraryMapper.MapLibrary();

It also crashes with the same error if instead of data I give it a path to my dll on disk.
This the stack trace:

Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Collections.Immutable.ImmutableDictionary`2.get_Item(TKey key)
   at Lunar.RemoteProcess.ProcessManager.ResolveDllName(String dllName)
   at Lunar.RemoteProcess.ProcessManager.GetFunctionAddress(Module module, ExportedFunction exportedFunction)
   at Lunar.RemoteProcess.ProcessManager.GetFunctionAddress(String moduleName, String functionName)
   at Lunar.LibraryMapper.BuildImportAddressTable()
   at Lunar.LibraryMapper.MapLibrary()

Could not install package 'Lunar-RPatch 1.1.0'.

I'm trying to install the package but I can't install it.
My project framework is .Net Framework 4.8 Dev,
If not fixed can I have the download instead?

Exception
Severity Code Description Project Line Suppression State File Error Could not install package 'Lunar-RPatch 1.1.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.8', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

Failed to load the dependency KERNEL32.dll into the process

when i inject DLL to application, it shows me that

Unhandled exception. System.ApplicationException: Failed to load the dependency KERNEL32.dll into the process
   at Lunar.LibraryMapper.LoadDependencies() in G:\My_Projects\ExSharpBase\Lunar\LibraryMapper.cs:line 723
   at Lunar.LibraryMapper.MapLibrary() in G:\My_Projects\ExSharpBase\Lunar\LibraryMapper.cs:line 107
   at VIP.Program.<>c.<StartTaskGame>b__17_5() in G:\My_Projects\ExSharpBase\Program.cs:line 201
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)

My program is X64
The target is x86.

System.ApplicationException: "Failed to load a dependency of the DLL"

I've mapped a pretty simple library into a game on Roblox:

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
  if (dwReason == DLL_PROCESS_ATTACH) {
    MessageBoxA(NULL, "test", "", NULL);
  }

  return TRUE;
}

Which resulted in this exception:

Not quite sure what's happening 🤔🤔
Let me know if this is an issue on my end

Crashed when importing

this is weird, i imported the whole thing (and now im using .NET Core 5.0) but whenever i tries to close and save visual studio, it gave me the 'bad exception' notification and not long after that visual studio crashed. any idea to fix this?
note : this wont happen if i dont import MappingFlags.cs and LibraryMapper.cs for some reason?

Section Alignment

Sections are not aligned correctly, that makes some relocations target a different page which may belong to another section with a different protection access and will trigger page access exception.

[How to test]
Just compile any C++ DLL with Visual Studio 2019 and try to map it, into any process. The .data section will be wrongly mapped, which in turn will trigger a page access exception when trying to set the global variable: "is_initialized_as_dll" on "scrt_initialize_crt" function.

[How to fix]
In MapSections method:

int? sectionAlignment = _peImage.Headers.PEHeader?.SectionAlignment;
var sectionSize = section.VirtualSize > section.SizeOfRawData ? section.VirtualSize : section.SizeOfRawData;
if (sectionAlignment != null)
{
sectionSize = (sectionSize + sectionAlignment.Value - 1) - (sectionSize + sectionAlignment.Value - 1) % sectionAlignment.Value;
}

And use the aligned section size instead of the SizeOfRawData.
Thanks.

Inconsistent Directory Names Crash

While messing around with how well the injector handled different files, I ran into an issue on my desktop where some of the files were not named how the program was expecting and getting an out-of-bounds index error.

In the function GetManifestDirectories in the file ActivationContext.cs around line 108 is where the function is defined.

When it iterates the directories and parses the names, it expects the names to be ...Version_Language_Hash
But in the case a file is not named in that convention (such as "Backup", "Temp", anything not conforming to this style) will cause the out-of-bounds error.

private IEnumerable<ManifestDirectory> GetManifestDirectories()

Out of the range of valid values. (Parameter 'length') -> GetRelocations()

Unhandled exception. System.AggregateException: One or more errors occurred. (Specified argument was out of the range of valid values. (Parameter 'length'))
---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'length')
at Lunar.PortableExecutable.DataDirectories.RelocationDirectory.GetRelocations()+MoveNext() in C:\Users\James\Downloads\Lunar-master\Lunar\PortableExecutable\DataDirectories\RelocationDirectory.cs:line 29
at System.Collections.Concurrent.Partitioner.DynamicPartitionerForIEnumerable1.InternalPartitionEnumerable.GrabChunk_Buffered(KeyValuePair2[] destArray, Int32 requestedChunkSize, Int32& actualNumElementsGrabbed)
at System.Collections.Concurrent.Partitioner.DynamicPartitionerForIEnumerable1.InternalPartitionEnumerator.GrabNextChunk(Int32 requestedChunkSize) at System.Collections.Concurrent.Partitioner.DynamicPartitionEnumerator_Abstract2.MoveNext()
at System.Threading.Tasks.Parallel.<>c__DisplayClass44_02.<PartitionerForEachWorker>b__1(IEnumerator& partitionState, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion) --- End of stack trace from previous location --- at System.Threading.Tasks.Parallel.<>c__DisplayClass44_02.b__1(IEnumerator& partitionState, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at System.Threading.Tasks.TaskReplicator.Replica1.ExecuteAction(Boolean& yieldedBeforeCompletion) at System.Threading.Tasks.TaskReplicator.Replica.Execute() --- End of inner exception stack trace --- at System.Threading.Tasks.TaskReplicator.Run[TState](ReplicatableUserAction1 action, ParallelOptions options, Boolean stopOnFirstFailure)
at System.Threading.Tasks.Parallel.PartitionerForEachWorker[TSource,TLocal](Partitioner1 source, ParallelOptions parallelOptions, Action1 simpleBody, Action2 bodyWithState, Action3 bodyWithStateAndIndex, Func4 bodyWithStateAndLocal, Func5 bodyWithEverything, Func1 localInit, Action1 localFinally)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.ThrowSingleCancellationExceptionOrOtherException(ICollection exceptions, CancellationToken cancelToken, Exception otherException)
at System.Threading.Tasks.Parallel.PartitionerForEachWorker[TSource,TLocal](Partitioner1 source, ParallelOptions parallelOptions, Action1 simpleBody, Action2 bodyWithState, Action3 bodyWithStateAndIndex, Func4 bodyWithStateAndLocal, Func5 bodyWithEverything, Func1 localInit, Action1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable1 source, ParallelOptions parallelOptions, Action1 body, Action2 bodyWithState, Action3 bodyWithStateAndIndex, Func4 bodyWithStateAndLocal, Func5 bodyWithEverything, Func1 localInit, Action1 localFinally)
at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable1 source, Action1 body)
at Lunar.LibraryMapper.RelocateImage() in C:\Users\James\Downloads\Lunar-master\Lunar\LibraryMapper.cs:line 633
at Lunar.LibraryMapper.MapLibrary() in C:\Users\James\Downloads\Lunar-master\Lunar\LibraryMapper.cs:line 126
at InjectorV2.Program.Main(String[] args) in C:\Users\James\Downloads\InjectorV2 (1)\InjectorV2\Program.cs:line 51

How to execute functions of injected dll ?

Hi,
Let's assume we have injected a dll from the memory to another process.
Now the question is : "How to execute/call a function which is available on that dll" ?
Thank you.

Freezes on inject

Hey, I've added the lunar.dll as a reference to my loader.

I've also added this code:

Process process = Process.GetProcessesByName("")[0];
MappingFlags flags = MappingFlags.None;
LibraryMapper mapper = new LibraryMapper(process, GameDetails.DLLPath, flags);

mapper.MapLibrary();

But everytime the loader and the game freezes..

I've also tried with:

MappingFlags flags = MappingFlags.DiscardHeaders;

I still get the same issue. Am I missing something or doing anything wrong?

Version Mismatch System.Runtime

I have a Windows Forms Application in .Net Framework 4.7.2 and when i add the reference to lunar.dll it give me this error Severity Code Description Project File Line Suppression State
Error CS1705 Assembly 'Lunar' with identity 'Lunar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'System.Runtime' with identity 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' PWNED Trainer
Please help im unsure what i have done wrong here.

Duplicate Key in _moduleCache when calling GetModule(string name)

ArgumentException: An item with the same key has already been added. Key: NTDLL.dll

This exception was originally thrown at this call stack:
System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(T)
System.Collections.Generic.Dictionary<TKey, TValue>.TryInsert(TKey, TValue, System.Collections.Generic.InsertionBehavior)
System.Collections.Generic.Dictionary<TKey, TValue>.Add(TKey, TValue)
Lunar.Remote.ProcessContext.GetModule(string) in ProcessContext.cs
Lunar.Remote.ProcessContext.ResolveForwardedFunction(string) in ProcessContext.cs
Lunar.Remote.ProcessContext.GetFunctionAddress(string, string) in ProcessContext.cs
Lunar.LibraryMapper.BuildImportAddressTable.AnonymousMethod__13_0(Lunar.PortableExecutable.Structures.ImportDescriptor) in LibraryMapper.cs
System.Threading.Tasks.Parallel.PartitionerForEachWorker.AnonymousMethod__1(ref System.Collections.IEnumerator, int, out bool)
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(System.Exception)
...
[Call Stack Truncated]

Injected DLL doesn't show up in the PEB module list

I am using Lunar to inject a DLL into a process which works fine. However, I wanted to debug the DLL and I am unable to do so because the PEB module list doesn't have the DLL listed. This prevents Visual Studio from triggering a breakpoint in the DLL code after attaching to the injected EXE because the DLL is not present in the module list. I understand that this is probably due to manual mapping, however I have a legitimate usecase where-in I don't want to do stealth DLL injection. Is there a possibility you could add the functionality to update the PEB module list by adding an extra parameter to MapLibrary()?

Partial Read/Write Exception

Unhandled exception. System.ComponentModel.Win32Exception (299): Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
   at System.Diagnostics.NtProcessManager.EnumProcessModulesUntilSuccess(SafeProcessHandle processHandle, IntPtr[] modules, Int32 size, Int32& needed)
   at System.Diagnostics.NtProcessManager.GetModules(Int32 processId, Boolean firstModuleOnly)
   at System.Diagnostics.NtProcessManager.GetFirstModule(Int32 processId)
   at System.Diagnostics.Process.get_MainModule()
   at Lunar.FileResolution.FileResolver.ResolveFilePath(ActivationContext activationContext, String fileName) in C:\Users\Me\source\repos\Lunar\Lunar\FileResolution\FileResolver.cs:line 27
   at Lunar.LibraryMapper.LoadDependencies() in C:\Users\Me\source\repos\Lunar\Lunar\LibraryMapper.cs:line 464
   at Lunar.LibraryMapper.MapLibrary() in C:\Users\Me\source\repos\Lunar\Lunar\LibraryMapper.cs:line 118
   at Specter.Program.Main(String[] args) in C:\Users\Me\source\repos\I\S\Program.cs:line 18

Map myself?

Hello,
is it not allowed to map a library to my own process? I'm trying this little sample code:

LibraryMapper mapper = new LibraryMapper(Process.GetCurrentProcess(), @"C:\Users\sam\Desktop\libwebp.dll");
mapper.MapLibrary();

But it just stucks at line 33 SymbolHandler -> GetSymbol -> Dbghelp.SymInitialize.

inject problem stuck

Target: steam.exe (x86)
dll: https://github.com/altoid29/VAC3_Dumper (x86)
Xenos inject it's with no problem, but not Lunar.

image
Stuck on 183 line in ProcessContext.cs
Here is callstack:
image
I waited 5 minutes, but nothing happening, it's just stuck in InitialiseTlsData on

 if (Kernel32.WaitForSingleObject(threadHandle, int.MaxValue) == -1)

x86 inject problem

Win 10 x64 22H2
Error is here:
1.

if (_processContext.Architecture == Architecture.X86)
        {
            try
            {
                functionTableAddress = _processContext.GetNtdllSymbolAddress("LdrpInvertedFunctionTables"); //<---- first going here
            }

            catch
            {
                functionTableAddress = _processContext.GetNtdllSymbolAddress("LdrpInvertedFunctionTable");
            }
        }
  1. In internal Symbol GetSymbol(string symbolName) in SymbolHandler.cs
....
....
if (!Dbghelp.SymFromName(currentProcessHandle, symbolName, out Unsafe.As<byte, SymbolInfo>(ref symbolInformationBytes[0])))
        {
            throw new Win32Exception(); //<----- throwing error here
        }
  1. Next is catch block with
functionTableAddress = _processContext.GetNtdllSymbolAddress("LdrpInvertedFunctionTable");
  1. But for this time error throwing here (SymbolHandler.cs GetSymbol)
   if (symbolTableAddress == 0)
        {
            throw new Win32Exception();
        }

If i comment

InsertExceptionHandlers();

in MapLibrary in LibraryMapper.cs
then its going works

General helper methods.

The library works great but there are a few functionalities that should be public and not internal, for example the method GetExportedFunction in the class ExportDirectory is really helpful if after mapping you need to modify some exported global variable or need to retrieve any exported symbol.

For now i just added a method in LibraryMapper.cs that calls the GetExportedFunction with the own DllBaseAddress and works fine. Also i believe the immediate execution after mapping should be split into two methods, one for mapping and one for executing, the reason is some one might want to modify the mapped code (virtualize, encrypt, etc) or write into shared memory before DLLMain gets called.

Thanks for your time.

System.ComponentModel.Win32Exception: 'Illegal access to a memory area.'

I've reported an issue with Bleak before I saw you retired it and suggested Lunar instead. I gave Lunar a try and downloaded the current master code, but sadly it also fails (with a different exception though):
System.ComponentModel.Win32Exception: 'Illegal access to a memory area.' at Lunar.Extensions.ProcessExtensions.ReadStructure[T](Process process, IntPtr structureAddress)

Local values:

structureAddress = 0xffffffff82798ba8
structureBlock.Length = 0x000000a8

--------------- (and from ReadModules() method:) --------------- 
entry.InMemoryOrderLinks.Flink = 0x82798bb0
loaderData.InMemoryOrderModuleList.Blink = 0x827986e0
entry.BaseDllName.Buffer = 0x0ccfb0d0
entry.BaseDllName.Length = 0x0016
entry.DllBase = 0x6f350000
inMemoryOrderLinksOffset = 0x0000000000000008

Call stack:

Lunar.dll!Lunar.Extensions.ProcessExtensions.ReadStructure<Lunar.Native.Structures.LdrDataTableEntry32>(System.Diagnostics.Process process, System.IntPtr structureAddress) Line 94	C#
Lunar.dll!Lunar.RemoteProcess.PebAccessor.ReadModules() Line 47	C#

Target process is 32bit, DLL i want to inject is C++ 32bit.

Few features ideas/wishlist

Hi,
I would like to suggest some small, some big changes that might be useful:

  1. Expose image size of the mapped library,
  2. Add (optional?) argument to MapLibrary, for specifying desired allocation address, as in VirtualAllocEx.
  3. Allow for swapping pinvoke functionality with user defined code - would require swapping extension methods on Process, into some wrapper class, and some public interface taken as an argument in LibraryMapper constructor. Would allow users to bypass process protections etc.

Thanks for making this library, hope You'll consider some of those :)

Only certain windows versions compatible?

Hey, I have a slight issue with your Lunar mapping library (which I love btw, makes everything so much easier so thanks a lot for making it). The only issue is that I believe it doesn't work on specific window builds such as Windows 10 20H2 (19042.906). Whereas, it will work fine on the windows build Windows 10 20H2 (19043.867).

Basically, when injecting the DLL it comes up with the error
System.ApplicationException: Failed to load the dependency KERNEL32.dll into the process at Lunar.LibraryMapper.LoadDependencies() at Lunar.LibraryMapper.MapLibrary()

Testing it on other Windows versions such as 1909 etc work perfectly fine too, so is it an issue due to the windows version? If so, would there be anyway to fix it?

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.