Skip to content

Commit

Permalink
[Msvc] Big Types Refactor (part 1)
Browse files Browse the repository at this point in the history
Freezing objects still seems broken
  • Loading branch information
RemoteNet committed Feb 7, 2025
1 parent 71adc54 commit 057543f
Show file tree
Hide file tree
Showing 27 changed files with 1,191 additions and 709 deletions.
6 changes: 3 additions & 3 deletions src/RemoteNET.Tests/RttiTypesFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public void AddFunctionImpl_DifferentDeclaringClassOnFunc_DifferentDeclaringType
string childTypeLongName = "Peek::Child";
TypeDump? typeDump = new TypeDump()
{
Type = childTypeLongName,
FullTypeName = childTypeLongName,
Assembly = "libPeek_lies.dll"
};
RemoteRttiType? childType = new RemoteRttiType(null, childTypeLongName, "libPeek_lies.dll");
Expand Down Expand Up @@ -290,7 +290,7 @@ public void AddFunctionImpl_SameDeclaringClassOnFunc_SameDeclaringType()
string childTypeLongName = "Peek::Child";
TypeDump? typeDump = new TypeDump()
{
Type = childTypeLongName,
FullTypeName = childTypeLongName,
Assembly = "libPeek_lies.dll"
};
RemoteRttiType? childType = new RemoteRttiType(null, childTypeLongName, "libPeek_lies.dll");
Expand Down Expand Up @@ -344,7 +344,7 @@ public void UndecoratingConstRef_ParseType_NoMethod()
string childTypeLongName = "Peek::WClass";
TypeDump? typeDump = new TypeDump()
{
Type = childTypeLongName,
FullTypeName = childTypeLongName,
Assembly = "libPeek_lies.dll"
};
RemoteRttiType? childType = new RemoteRttiType(null, childTypeLongName, "libPeek_lies.dll");
Expand Down
22 changes: 11 additions & 11 deletions src/RemoteNET/Internal/Reflection/DotNet/RemoteTypesFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,16 @@ private Type Create(ManagedRemoteApp app, string fullTypeName, string assembly)

public Type Create(ManagedRemoteApp app, TypeDump typeDump)
{
Type shortOutput = _resolver.Resolve(typeDump.Assembly, typeDump.Type);
Type shortOutput = _resolver.Resolve(typeDump.Assembly, typeDump.FullTypeName);
if (shortOutput != null)
{
return shortOutput;
}

RemoteType output = new RemoteType(app, typeDump.Type, typeDump.Assembly, typeDump.IsArray);
RemoteType output = new RemoteType(app, typeDump.FullTypeName, typeDump.Assembly, typeDump.IsArray);

// Temporarily indicate we are on-going creation
_onGoingCreations[new Tuple<string, string>(typeDump.Assembly, typeDump.Type)] = output;
_onGoingCreations[new Tuple<string, string>(typeDump.Assembly, typeDump.FullTypeName)] = output;

string parentType = typeDump.ParentFullTypeName;
if (parentType != null)
Expand All @@ -171,10 +171,10 @@ public Type Create(ManagedRemoteApp app, TypeDump typeDump)
AddMembers(app, typeDump, output);

// remove on-going creation indication
_onGoingCreations.Remove(new Tuple<string, string>(typeDump.Assembly, typeDump.Type));
_onGoingCreations.Remove(new Tuple<string, string>(typeDump.Assembly, typeDump.FullTypeName));

// Register at resolver
_resolver.RegisterType(typeDump.Assembly, typeDump.Type, output);
_resolver.RegisterType(typeDump.Assembly, typeDump.FullTypeName, output);

return output;
}
Expand Down Expand Up @@ -215,7 +215,7 @@ private void AddProperties(ManagedRemoteApp app, TypeDump typeDump, RemoteType o
{
try
{
return ResolveTypeWhileCreating(app, typeDump.Type, "prop__resolving__logic",
return ResolveTypeWhileCreating(app, typeDump.FullTypeName, "prop__resolving__logic",
propDump.Assembly, propDump.TypeFullName);
}
catch (Exception e)
Expand Down Expand Up @@ -252,7 +252,7 @@ private void AddEvents(ManagedRemoteApp app, TypeDump typeDump, RemoteType outpu
{
try
{
return ResolveTypeWhileCreating(app, typeDump.Type, "event__resolving__logic", eventType.Assembly, eventType.TypeFullName);
return ResolveTypeWhileCreating(app, typeDump.FullTypeName, "event__resolving__logic", eventType.Assembly, eventType.TypeFullName);
}
catch (Exception e)
{
Expand All @@ -275,7 +275,7 @@ private void AddFields(ManagedRemoteApp app, TypeDump typeDump, RemoteType outpu
{
try
{
return ResolveTypeWhileCreating(app, typeDump.Type, "field__resolving__logic",
return ResolveTypeWhileCreating(app, typeDump.FullTypeName, "field__resolving__logic",
fieldDump.Assembly, fieldDump.TypeFullName);
}
catch (Exception e)
Expand Down Expand Up @@ -305,7 +305,7 @@ private void AddGroupOfFunctions(ManagedRemoteApp app, TypeDump typeDump, List<T
{
// In case of a generic type we have no way to "resolve" it
// We are just creating a dummy type
return new RemoteType(app, typeDump.Type, "FakeAssemblyForGenericTypes", typeDump.IsArray, true);
return new RemoteType(app, typeDump.FullTypeName, "FakeAssemblyForGenericTypes", typeDump.IsArray, true);
}
else
{
Expand All @@ -316,7 +316,7 @@ private void AddGroupOfFunctions(ManagedRemoteApp app, TypeDump typeDump, List<T
// void MyOtherMethod(System.Text.StringBuilder sb) <-- The 'sb' parameter WILL get here
try
{
Type paramType = ResolveTypeWhileCreating(app, typeDump.Type, func.Name, methodParameter.Assembly,
Type paramType = ResolveTypeWhileCreating(app, typeDump.FullTypeName, func.Name, methodParameter.Assembly,
methodParameter.FullTypeName);
if (paramType == null)
{
Expand Down Expand Up @@ -351,7 +351,7 @@ private void AddGroupOfFunctions(ManagedRemoteApp app, TypeDump typeDump, List<T
{
try
{
return ResolveTypeWhileCreating(app, typeDump.Type, func.Name,
return ResolveTypeWhileCreating(app, typeDump.FullTypeName, func.Name,
func.ReturnTypeAssembly, func.ReturnTypeFullName);
}
catch (Exception e)
Expand Down
8 changes: 4 additions & 4 deletions src/RemoteNET/Internal/Reflection/Rtti/RttiTypesFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ private Type Create(RemoteApp app, string fullTypeName, string assembly)

public Type Create(RemoteApp app, TypeDump typeDump)
{
Type shortOutput = _resolver.Resolve(typeDump.Assembly, typeDump.Type);
Type shortOutput = _resolver.Resolve(typeDump.Assembly, typeDump.FullTypeName);
if (shortOutput != null)
{
return shortOutput;
}

RemoteRttiType output = new RemoteRttiType(app, typeDump.Type, typeDump.Assembly);
RemoteRttiType output = new RemoteRttiType(app, typeDump.FullTypeName, typeDump.Assembly);

// Temporarily indicate we are on-going creation
_onGoingCreations[new Tuple<string, string>(typeDump.Assembly, typeDump.Type)] = output;
_onGoingCreations[new Tuple<string, string>(typeDump.Assembly, typeDump.FullTypeName)] = output;

string parentType = typeDump.ParentFullTypeName;
if (parentType != null)
Expand All @@ -124,7 +124,7 @@ public Type Create(RemoteApp app, TypeDump typeDump)
AddMembers(app, typeDump, output);

// remove on-going creation indication
_onGoingCreations.Remove(new Tuple<string, string>(typeDump.Assembly, typeDump.Type));
_onGoingCreations.Remove(new Tuple<string, string>(typeDump.Assembly, typeDump.FullTypeName));

// Register at resolver
_resolver.RegisterType(output);
Expand Down
4 changes: 2 additions & 2 deletions src/RemoteNET/Internal/RemoteObjectRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private void ThrowIfReleased()
public InvocationResults InvokeMethod(string methodName, string[] genericArgsFullTypeNames, ObjectOrRemoteAddress[] args)
{
ThrowIfReleased();
string typeFullName = $"{_typeInfo.Assembly}!{_typeInfo.Type}";
string typeFullName = $"{_typeInfo.Assembly}!{_typeInfo.FullTypeName}";
return CreatingCommunicator.InvokeMethod(RemoteObjectInfo.PinnedAddress, typeFullName, methodName, genericArgsFullTypeNames, args);
}

Expand Down Expand Up @@ -132,7 +132,7 @@ public void RemoteRelease()
public override string ToString()
{
return $"RemoteObjectRef. Address: {RemoteObjectInfo.PinnedAddress} (0x{RemoteObjectInfo.PinnedAddress:x16}), " +
$"TypeFullName: {_typeInfo.Type}";
$"TypeFullName: {_typeInfo.FullTypeName}";
}

internal ObjectOrRemoteAddress GetItem(ObjectOrRemoteAddress key)
Expand Down
2 changes: 1 addition & 1 deletion src/RemoteNET/RemoteApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public abstract class RemoteApp : IDisposable
/// </summary>
public virtual Type GetRemoteType(Type localType) => GetRemoteType(localType.FullName, localType.Assembly.GetName().Name);
public virtual Type GetRemoteType(CandidateType candidate) => GetRemoteType(candidate.TypeFullName, candidate.Assembly);
public virtual Type GetRemoteType(TypeDump typeDump) => GetRemoteType(typeDump.Type, typeDump.Assembly);
public virtual Type GetRemoteType(TypeDump typeDump) => GetRemoteType(typeDump.FullTypeName, typeDump.Assembly);


public abstract RemoteObject GetRemoteObject(ulong remoteAddress, string typeName, int? hashCode = null);
Expand Down
6 changes: 4 additions & 2 deletions src/ScubaDiver.API/Interactions/Dumps/TypeDump.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace ScubaDiver.API.Interactions.Dumps
{
[DebuggerDisplay("ManagedTypeDump of {" + nameof(Type) + "} (Assembly: {" + nameof(Assembly) + "})")]
[DebuggerDisplay("ManagedTypeDump of {" + nameof(FullTypeName) + "} (Assembly: {" + nameof(Assembly) + "})")]
public class TypeDump
{
[DebuggerDisplay("{" + nameof(ReturnTypeName) + "} {" + nameof(Name) + "}(...)")]
Expand Down Expand Up @@ -88,6 +88,8 @@ public override string ToString()
public string ReturnTypeAssembly { get; set; }
public string ReturnTypeName { get; set; }
public bool IsReturnTypeGenericParameter { get; set; }
public bool IsInherited { get; set; }


public TypeMethod()
{
Expand Down Expand Up @@ -239,7 +241,7 @@ public class TypeMethodTable
public long Address { get; set; }
}

public string Type { get; set; }
public string FullTypeName { get; set; }
public string Assembly { get; set; }

public bool IsArray { get; set; }
Expand Down
7 changes: 7 additions & 0 deletions src/ScubaDiver/DiverBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public DiverBase(IRequestsListener listener)
private string MakeHelpResponse(ScubaDiverMessage arg)
{
var possibleCommands = _responseBodyCreators.Keys.ToList();
possibleCommands.Sort();
return JsonConvert.SerializeObject(possibleCommands);
}

Expand Down Expand Up @@ -127,6 +128,9 @@ public string QuickError(string error, string stackTrace = null)

private void HandleDispatchedRequest(object obj, ScubaDiverMessage request)
{
if (request.UrlAbsolutePath != "/ping")
Logger.Debug($"[{DateTime.Now.ToLongTimeString()}][HandleDispatchedRequest] New request to {request.UrlAbsolutePath}");
Stopwatch sw = Stopwatch.StartNew();
string body;
if (_responseBodyCreators.TryGetValue(request.UrlAbsolutePath, out var respBodyGenerator))
{
Expand All @@ -143,6 +147,9 @@ private void HandleDispatchedRequest(object obj, ScubaDiverMessage request)
{
body = QuickError("Unknown Command");
}
sw.Stop();
if (request.UrlAbsolutePath != "/ping")
Logger.Debug($"[{DateTime.Now.ToLongTimeString()}][HandleDispatchedRequest] Done with request to {request.UrlAbsolutePath}. Elapsed: {sw.ElapsedMilliseconds} ms");

request.ResponseSender(body);
}
Expand Down
2 changes: 1 addition & 1 deletion src/ScubaDiver/DotNetDiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ static TypeDump ParseType(Type typeObj)

TypeDump td = new()
{
Type = typeObj.FullName,
FullTypeName = typeObj.FullName,
Assembly = typeObj.Assembly.GetName().Name,
Methods = methods,
Constructors = ctors,
Expand Down
11 changes: 10 additions & 1 deletion src/ScubaDiver/DynamicMethodGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,16 @@ static bool RunPatchInPosition(HarmonyPatchPosition position, DetouredFuncInfo h
// If the argument is a pointer, indicate it with a NativeObject
// TODO: SecondClassTypeInfo is abused here
string fixedArgType = argType[..^1].Trim();
argsToForward[i] = new NativeObject(arg, new SecondClassTypeInfo(hookedFunc.DeclaringClass.ModuleName, fixedArgType));

// split fixedArgType to namespace and name
// Look for last index of "::" and split around it
int lastIndexOfColonColon = fixedArgType.LastIndexOf("::");
// take into consideration that "::" might no be present at all, and the namespace is empty
string namespaceName = lastIndexOfColonColon == -1 ? "" : fixedArgType.Substring(0, lastIndexOfColonColon);
string typeName = lastIndexOfColonColon == -1 ? fixedArgType : fixedArgType.Substring(lastIndexOfColonColon + 2);

SecondClassTypeInfo typeInfo = new SecondClassTypeInfo(hookedFunc.DeclaringClass.ModuleName, namespaceName, typeName);
argsToForward[i] = new NativeObject(arg, typeInfo);
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/ScubaDiver/Hooking/DetoursNetWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public bool AddHook(TypeInfo typeInfo, UndecoratedFunction methodToHook, Harmony
// Fallback, Try directly with pointers
Console.WriteLine($"[DetoursNetWrapper] Hooking with LoadLibrary + GetProcAddress failed, trying direct pointers. Target: {methodToHook.Module.Name}!{methodToHook.UndecoratedFullName}");
IntPtr module = new IntPtr((long)methodToHook.Module.BaseAddress);
IntPtr targetFunc = new IntPtr(methodToHook.Address);
IntPtr targetFunc = new IntPtr((long)methodToHook.Address);
success = Loader.HookMethod(module, targetFunc, tramp.DelegateType, tramp.GenerateMethodInfo, tramp.GeneratedDelegate);

return success;
Expand All @@ -90,7 +90,7 @@ public bool AddHook(TypeInfo typeInfo, UndecoratedFunction methodToHook, Harmony
public bool RemoveHook(UndecoratedFunction methodToUnhook, HarmonyWrapper.HookCallback callback)
{
IntPtr module = new IntPtr((long)methodToUnhook.Module.BaseAddress);
IntPtr targetFunc = new IntPtr(methodToUnhook.Address);
IntPtr targetFunc = new IntPtr((long)methodToUnhook.Address);

if (!_methodsToGenMethods.TryGetValue(methodToUnhook, out MethodInfo genMethodInfo))
return false;
Expand Down
Loading

0 comments on commit 057543f

Please sign in to comment.