all groups > dotnet interop > january 2005 >
You're in the

dotnet interop

group:

Launching the .NET environment


Launching the .NET environment Pete Davis
1/31/2005 2:16:37 PM
dotnet interop:
First of all, I'm going to try to avoid going into a complete description of
what we're trying to do as it would take a great deal of text to explain the
reasoning and the actualy design.

Essentially, we are going to have a launcher application in unmanaged C++
that's going to launch our .NET application.

Now, once our .NET application is running, I want to access a COMVisible
object in the assembly from the launcher app.

Now here's the kind of weird part:

The launcher application needs to have a COM-type object that it creates
that the .NET app can call back into. It basically works like this:

Launch .NET environment with assembly.
Launcher gets .NET COMVisible object (let's call it ObjA)
Launcher passes it's "COM-type" object (ObjB) to the .NET app via a method
call to ObjA.
The .NET app can then communicate with the Launcher by calling methods in
ObjB

I know this is probably really contorted, but there are really important
reasons why it has to be done along these lines.

Here's a problem. I said "COM-type" object. The object created by the
launcher should only be creatible from within the launcher application. It
should not be an object that can be created by an outside application. On
the other hand

Can anyone give me an idea of how to go about this? Would I create a TLB for
ObjA to import in the .NET app to get the object "signature"?

I'll try to explain our requirements without going into excessive detail.

We have a client/server application. The client is written in .NET. But it's
very important in our case that the client is "trusted". That is, we need to
ensure that the client application hasn't been hacked and modified in any
way. Now, there's no 100% way of doing this, but this is the best we can
come up with and we're satisfied that it's safe enough to suit our purposes.

First of all, we considered obfuscation w/string encryption of the .NET app,
but we decided that's not quite safe enough.

The launcher application is obfuscated w/string encryption, but since it's
native code, it will be much harder to reverse engineer (of course it's
always possible, but unlikely in our case). We don't trust the .NET
application, so the launcher basically does an SHA1 hash of the .NET app to
verify that it is the authentic release version of the application.

The launcher application has an encryption key and algorithm which it uses
to encrypt data for the .NET app. Now, the reason I came up with this
particular architecture is that we don't want any other application trying
to access the encryption algorithm. So, if the the launcher instantiates the
..NET COM visible object and passes its own COM object via a method, then we
can be fairly sure that no other apps have access.

So, anyway, if anyone can tell me the following two things, I'd really
appreciate it:

1: A pointer to the docs on how to launch a .NET application from an
unamanged app.

2: How to create the "COM-type" object on the C++ side.

3: Does anyone see any security flaws in this design other than the obvious,
"no security is 100%".

Thanks

Pete

RE: Launching the .NET environment Daniel Petersson, Cefalo
1/31/2005 10:23:03 PM
Hi Pete,

A lot info here but I'll with a question, why dont you just use
strong names on your assemblies? If you apply strong names
clr will enforce a few checks prior to loading the assembly;
such as tamper protection and versioning. Ofcourse there is
no 100% guarantee for any security but since strong names
are based on PKI they handle the tampering protection very well.
(Note ALL assemblies needs to be signed to avoid tampering)

ok now for you questions: a COM type object? What you need
is a COM object that cant be externaly creatable. Ok, the easy
solution is to add a class like this:

class ATL_NO_VTABLE MyInternalCoClass
: public CComObjectRootEx<CComMultiThreadModel>,
public IMyInterface
{
// needs COM_MAP
};

then create an object using the CreateInstance method on CComObjectRootEx,

CComObject<MyInternalCoClass> *pMyObject = NULL;
HRESULT hRes = CComObject<MyInternalCoClass>::CreateInstance(&pMyObject);

Know you have a COM object that isn't possible to create outside the
application.

If you need to launch .NET application from within your native
code, check the CorBindToRuntimeEx(...) method.
Another simple way to launch a managed application from within
your native application is to register a class in the managed assembly
for COM interop, then you can use CoCreateInstance to do the
jump into managed code. (this however don't give you the full
controll over the runtime and loading as CorBindToRuntimeEx( ... ) does.

I would encourage you to use strong names instead of this rather
complex solution. Since there is no 100% security, as you pointed out,
it is better to go with the pre built one and be productive. Strong names
provide tamper protection at the lowest possible level, since it uses
hashes to guarantee that the assembly isn't tampered with.
This can be combined with an authenticode signature.

//daniel

[quoted text, click to view]
Re: Launching the .NET environment Pete Davis
2/2/2005 4:49:08 PM
Daniel,

Thanks for the info. That's exactly what I needed.

As for strong names, we are using strong names, but what I suppose I
neglected to mention is that communications with the server is done via
sockets. There's no real way to prove to the server that the client hasn't
been tampered with or even a completely different application pretending to
be the client.

Does that make sense?

Pete



<Daniel Petersson>; "Cefalo" <daniel.petersson@cefalo.se.donotspam> wrote in
message news:3F7D6E46-98F0-44AB-9702-FDA4B2366F5F@microsoft.com...
[quoted text, click to view]

AddThis Social Bookmark Button