Search code examples
interopcom-interop

Can I change the signature of a COM Interop method from the one generated by Visual Studio?


We are using a third-party COM API from NET. Currently Visual Studio & presumably TLBIMP is used to generate the Interop wrapper DLL.

The generated interface of one specific method provided to NET is not the one we'd prefer to use. Is it possible to change the COM interop code so that the method signature presented to NET is different? We can't change the COM interfaces or TLB used because it's third-party code.

The actual example is as follows:

The method in question is where one passes a cleartext password. The current code goes as follows:

  1. Our password handling returns a System.Security.SecureString (password is encrypted in memory).
  2. We marshal the SecureString to a BSTR (annoyingly cleartext but can be zeroed afterwards to reduce exposure).
  3. BSTR is converted to a System.String (Oops! This will be immutable, potentially never garbage collected, and keep the cleartext password around in memory).
  4. COM Interop function wrapping third-party library takes System.String & marshals it again to a BSTR.
  5. Third party COM API takes the BSTR and hopefully handles it in a vaguely secure way.

It is steps 2 & 3 I'd like to avoid. I can't change the fact that the third party API is handling a cleartext password, but I'd like at least the code we have control over to minimise the presence of the cleartext in memory.

I'd like to change the signature of the NET method to take a SecureString instead of a String - NET can already marshal a SecureString to a BSTR, so the COM interop code could still present the same data to the actual COM API, but without the horrible step of creating a String. Can this be done?


Solution

  • Yes, but you need to write the code for the interop interface manually, and then you can of course change the type of the parameters as you like.

    I would probably start by creating the interop assembly using tlbimp. Then I would decompile it using Reflector and placing these sources in a separate class library project, modifying the interface as needed and use this assembly as the interop assembly.