Proxy DLL® app

What is Proxy DLL

Our Proxy DLL® app allows your .NET application to invoke a normal class library (DLL) on a remote computer as if the DLL is on your computer.

No extra coding is needed:

  • In a few mouse clicks, you generate a proxy DLL from the original DLL which you want to remotely invoke. The proxy DLL is also a normal .NET DLL and, by default, has the same public interface as the original DLL.
  • Before publishing, you can inspect the generated C# source code, edit method bodies, remove public methods you do not want to expose, and save the edited version. When the original DLL is upreved, SkyBridge can merge your edits into the newly generated proxy source.
  • On the remote computer which has the original DLL, you download and start our Proxy DLL® app, which registers the original DLL as a layer-4 RPC service listening for remote invocations.
  • On your own computer, you add a reference to the proxy DLL in your Visual Studio project, build it and run it.
  • When your code calls a method on the proxy DLL, the method creates a layer-4 RPC consumer to remotely invoke the namesake on the original DLL and get the result back instantly.

This way, your app doesn't even know that what it is invoking is not the original DLL, because the proxy DLL behaves as the original DLL.

How it works

Skybridge Proxy DLL flowchart
  1. On the computer with the proxy DLL, the app invokes a method on the proxy DLL.
  2. The proxy DLL method serializes the invocation details into a JSON string then a byte array and sends it to the SkyBridge® server using a RPC consumer.
  3. The server relays the byte array to the RPC service inside the Proxy DLL® app on the original-DLL computer.
  4. The Proxy DLL® app converts the received byte array to a JSON string, then parses the JSON to get the method invocation details, and uses it to invoke the corresponding method in the original DLL on behalf of the proxy DLL.

    If the invocation details doesn't match any method on the original DLL, it throws an exception which pops out of the proxy DLL method on the proxy-DLL computer.

Whatever data the original DLL method returns, the RPC service returns to the RPC consumer via the server. The proxy DLL method returns to the app. The round trip happens in 100 ms.

Points of innovation

  1. The contract IS the original DLL. gRPC, Thrift, and most cross-process RPC frameworks require you to write a contract file (.proto, .thrift) by hand. Proxy DLL reads the original DLL's metadata directly — no contract file, no rebuild ceremony.
  2. Drop-in interface compatibility. The generated proxy DLL has the same namespaces, types, and method signatures as the original. Your caller code recompiles against the proxy without a single line changed. No other maintained RPC framework offers this.
  3. Editable generated source. The generated C# is not a black box. You can inspect it, edit method bodies, remove public methods you do not want to expose, compile it, and publish the reviewed version.
  4. Layered on top of SkyBridge® RPC, not beside it. Proxy DLL inherits firewall traversal, double encryption, and sub-100 ms round trips from the lower layer. One layer of plumbing to maintain, not two.

See also: What Claude AI thinks of us.

Points of excellence

  1. Your existing code, unchanged, talks to a remote computer. Recompile against the proxy DLL and your method calls now execute on the original-DLL computer — across continents, behind firewalls. No serialisation code, no client library, no special handling.
  2. A round trip between a computer in Australia and one in the US takes as short as 0.2 second.
  3. The SkyBridge® server is extremely light-weighted and efficient. A single server can handle thousands of round trips each second.
  4. No learning curve: two minutes to download and configure.
  5. No ongoing effort after initial setup. It just feels as if everyone is coding on the same computer.
  6. Where this fits. Collaborating with partners or contractors without sharing source code; granting third parties fine-grained access to specific functions; driving fleets of remote machines from a central app. Each of these is awkward or impossible with conventional RPC.

Security

Double encryption

Double encryption
  • The connection between your code and our server is encrypted with the latest TLS.
  • The server never inspects or logs the data it relays between the services and consumers.
  • By simply passing true to an "endToEndEncryption" Boolean parameter of the Consumer()'s InvokeService() method, you can enable end-to-end encryption (E2EE) between your consumer and the target service. This way, even if our server is compromised, the hacker cannot understand the data being relayed.

EV Code Signing

EV code signing

To give you peace of mind, all of our software products are signed with an EV (Extended Validation) Code Signing Certificate issued by Sectigo, one of the Certificate Authorities trusted by Microsoft Windows. Sectigo put us through a stringent and lengthy process to verify Front Edge Software's legal identity, registered address, and right to operate under that name.

This signature on our products holds us accountable for every binary we ship, and guarantees that no one else can distribute fake apps claiming to be ours.

See details of EV code signing.

The original DLL is the sandbox

As you can see in the data flow chart, the invocation data that is sent to the original DLL computer must match a method on the original DLL by signature, otherwise an exception will be thrown. So, even if a malicious party managed to alter the invocation data despite of the double encryption in data transit, it cannot make the proxy DLL remote invocations listener do anything except calling a method on the original DLL.

Therefore, Cross-Site Scripting (XSS) is impossible. The original DLL is the sandbox that an attacker can never get out of.

Inside in the generated proxy DLL

Following is the "AddNewTeam" function in an original DLL (in the example project). It opens the database context, adds a new team, saves the change, and returns the new team as a DTO.

public static DTOs.Team AddNewTeam(string teamName)
{
    using (var ctx = Utilities.GetDataContext())
    {
        var team = new Team
        {
            TeamId = Guid.NewGuid(),
            Name = teamName,
        };

        ctx.Teams.Add(team);
        ctx.SaveChanges();
        return team.GetDto();
    }
}

Following is the code in the "AddNewTeam" function in the generated proxy DLL:

public static FrontEdge.ProxyDll.Examples.HumanResource.DTOs.Team AddNewTeam(System.String teamName)
{
    var functionCall = new FuncCall
    {
        ClassType = "FrontEdge.ProxyDll.Examples.HumanResource.DataAccess",
        FunctionName = "AddNewTeam",
    };

    var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full, ContractResolver = new FrontEdge.SkyBridge.ProxyDllCompanion.ConstructorBypassContractResolver() };
    functionCall.FunctionParameters = new FuncCallParam[1];

    functionCall.FunctionParameters[0] = new FuncCallParam
    {
        Name = "teamName",
        Type = "System.String",
        ParamValueJsonString = JsonConvert.SerializeObject(teamName, settings),
    };

    string functionCallJson = JsonConvert.SerializeObject(functionCall);
    byte[] functionCallBytes = Encoding.UTF8.GetBytes(functionCallJson);

    try
    {
        byte[] responseBytes = Task.Run(() => __ApiContainer.Api.InvokeService(Guid.Parse(__ApiContainer.OrigDllRPCServiceId), functionCallBytes)).Result;

        string responseJson = Encoding.UTF8.GetString(responseBytes);
        FuncCallResp response = JsonConvert.DeserializeObject<FuncCallResp>(responseJson);
        return (FrontEdge.ProxyDll.Examples.HumanResource.DTOs.Team)JsonConvert.DeserializeObject(response.ReturnedValueJsonString, settings);
    }
    catch (Exception ex)
    {
        var __remoteEx = FrontEdge.SkyBridge.ProxyDllCompanion.RemoteOrigDllException.TryFrom(ex);
        if (__remoteEx != null)
            throw __remoteEx;
        var __rootEx = ex is AggregateException __agg && __agg.InnerException != null ? __agg.InnerException : ex;
        System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(__rootEx).Throw();
        throw; // unreachable
    }
}
  1. It packages the invocation on itself into a JSON string, then convert it into a byte array.
  2. It sends the byte array to the original-DLL computer via SkyBridge® RPC by calling an RPC Consumer's InvokeService function.
  3. The invocation is received by the Proxy DLL® app's remote invocations listener via an RPC Service.
  4. The remote invocations listener invokes the "AddNewTeam" function of the original DLL and returns the result to the proxy DLL via SkyBridge® RPC, which becomes the returned byte array "responseBytes".
  5. The byte array is converted back to JSON and deserialised into a Team DTO, which is returned to the caller.
  6. The catch block makes sure that an exception thrown in the AddNewTeam function in the original DLL is rethrown by the same function in the proxy DLL, and that the exception carries both the local and remote stack traces.

2 minutes to setup the original-DLL computer

Original-DLL Computer UI
  1. On the computer that contains the original DLL, download SkyBridge® Proxy DLL - .NET Framework (.NET version will be released soon). It is a zip file containing all the binaries. You can place them in any folder.
  2. Double-click OriginalDllComputer.ConfigurationsManager.exe to launch the user interface in the screenshot above.
  3. Select your original DLL, enter the RPC service GUID and API key, and choose the .NET target framework for the generated proxy DLL.
  4. Review the invocable types, then click Save Settings To Config File. This generates and saves the Proxy DLL source code.
  5. Open the saved source code if you want to inspect it, compile it, edit method bodies, or remove public methods you do not want to expose.
  6. Click Publish Proxy DLL Code To Server when you are ready for proxy-DLL computers to download this version.
  7. Under Windows service, click Install Windows Service. The service listens for remote invocations and calls the original DLL.

2 minutes to setup the proxy-DLL computer

Proxy DLL Manager UI on the proxy-DLL computer
  1. Enter the RPC consumer GUID and API key that this proxy-DLL computer will use.
  2. Click Download new proxy DLL, select the published original DLL, and choose where the proxy DLL should be saved.
  3. Click the refresh button to load the published versions, choose the version you want, then download and compile it.
  4. If needed, open the downloaded source code, make local edits, and compile the edited proxy DLL.
  5. In the project that needs to reference this proxy DLL, add references to the proxy DLL and the required SkyBridge runtime packages.
  6. Finally, run the software on the remote computer and see the method calls cross the network.

Editing and version updates

Proxy DLL updates are deliberate. The original-DLL computer generates and publishes versions; each proxy-DLL computer can then refresh the version list and download the version it wants. Both sides can keep source-code edits under control instead of treating generated code as a black box.

  1. You change the public interface of the original DLL — for example, you add a parameter to a method, change a return type, or introduce a new method.
  2. The Proxy DLL® app on your original-DLL computer detects the new original DLL version and regenerates the Proxy DLL source code.
  3. You review the generated source code, optionally edit it, and click Publish Proxy DLL Code To Server when you are ready to publish that version. Edited code is validated against the generated public contract: you may remove generated public methods, but you cannot add new public methods or change signatures.
  4. On each proxy-DLL computer, the developer clicks the refresh button, chooses the desired version, and downloads it.

If the original DLL is upreved after you edited the proxy source, SkyBridge compares the previous generated source, your edited source, and the newly generated source. It can try to merge your edits into the new version. If the merge is not safe, you can either keep the old edited code and leave hosting paused, or discard the old edits and accept the newly generated proxy source.

The same merge workflow exists on the proxy-DLL computer. There the "base" is the source code downloaded from the server, because the proxy-DLL computer does not have the original DLL. Local edits can be merged into a newer downloaded version before compiling.

This keeps updates under the developer's control. A public interface change can break code that references the proxy DLL, so SkyBridge makes the new version visible without silently replacing a DLL that another project is using.

Changes that don't touch the public interface — for example, modifying the body of a method without changing its signature — don't require a new proxy DLL. The same proxy DLL keeps working, and the new behaviour takes effect immediately on the original-DLL computer.

User Cases

1. Remote Control

You are an instrument manufacturer with instruments being used in customer labs. Occasionally you need to remotely initiate the self-diagnosis process on the instruments and get back the result.

  • You create a normal .NET DLL with a StartDiagnosis and GetDiagnosisResult method, and place it in the instruments. You also put our Proxy DLL® app in them. By default the app is not running.
  • Using our Proxy DLL® app, in a few mouse clicks, you generate a proxy DLL from the above diagnosis DLL.
  • When you and the customer agree to do the remote diagnosis, the customer clicks a menu item "Allow Remote Diagnosis" on the instrument, which starts the Proxy DLL® app, which starts an RPC Service listening for remote invocations.
  • You run a remote diagnosis app from your premise, which invokes the two methods on the proxy DLL, which uses an RPC consumer to invoke the diagnosis DLL in the remote instrument to commence the self-diagnosis process and retrieve the result.

Without SkyBridge®, you have to create a similar technology stack yourself, including web infrastructure. With SkyBridge®, your programmers can concentrate on what they are good at - the instrument software.

2. Data Collection

The reversal of the above remote-control topology is that your instruments in customer labs act as RPC consumers which send data to your premise:

  • You create a normal .NET DLL which has a send-data method, which accepts the diagnosis data as a parameter and saves it in your database.
  • You put this original DLL and our Proxy DLL® app on a server in your premise. The Proxy DLL® app listens for remote invocations on this DLL.
  • You generate a proxy DLL from the original DLL, and place it in the instruments.
  • When an instrument needs to send data to your premise, it calls the send-data method on the proxy DLL, which remotely calls the send-data method on the original DLL.

3. Collaboration in software development

Mary and Peter work for different software houses and collaborate on developing a .NET application. Mary is coding a library, and Peter is coding another one.

To run the app, all components - the user interface, Mary's library and Peter's library must all be in the same binaries folder.

To allow each other to run the app, Mary gives Peter the proxy DLL generated from her library. Peter gives Mary the proxy DLL generated from his.

When Mary runs the app, Peter's proxy DLL on her computer remotely calls Peter's DLL on Peter's computer.

When Peter runs the app, Mary's proxy DLL on his computer remotely calls Mary's DLL on Mary's computer.

Therefore, when either runs the app, the source code on both computers is executed in real time, as if they are on the same computer.

Now let's say Peter's code has the following function:

List<Employee> GetEmployeesInProject (int projectId)

Peter changes it by adding an extra parameter:

List<Employee> GetEmployeesInProject (int projectId, EmployeeType employeeType)

Peter publishes the new Proxy DLL version. Mary then refreshes the version list on her proxy-DLL computer, downloads the new version, and rebuilds against the DLL that has the added employeeType parameter.

Using remote freelancer programmers has many benefits. This article discussed this topic thoroughly. The biggest roadblock is that lots of businesses don't feel comfortable to give the source code which contains their core IP to an overseas freelancer. Our Proxy DLL® technology removes this roadblock, because you can give the proxy DLL to the remote freelancer, which contains none of your business logic. This allows distributed collaborations in software development to explode in scale. The software industry will be fundamentally changed.

4. Expose your database in a fine-grained manner to a partner

You have a database in your secure private network. Your external partner needs to access some data in it. You want to run some complex safeguarding and filtering logic to decide what data they can access. You also want to do some transformation on your data, such as sanitizing customer emails (e.g. from "john.smith@gmail.com" to "j*@gmail.com") before it becomes available to your partner.

Without SkyBridge®, you have to write a custom web API and deploy it into the cloud for your partner to invoke.

With SkyBridge®, all you need to do is write a .NET DLL that performs all the elaborate safeguarding, filtering and transformation and returns the filtered and transformed data.

Then, give the proxy DLL to your partner. They can just reference it in their application. No one needs to understand any web technology.

Other use cases

If you are using proxy DLL in other use cases please let us know. It is good to share with others.

Documentations

SkyBridge® Proxy DLL Introduction