Page 1 of 2

Help getting Dot Net 4 to work in Purebasic

Posted: Thu Mar 22, 2012 9:56 am
by Project Mayu
This is my code so far, my goal is to get it to work in x64 but for now in x86 I can get up to loading the dot net assembly and at that point it fails

Code: Select all

Interface ICLRMetaHost
  QueryInterface(a.l, b.l)
  AddRef()
  Release()
  GetRuntime(a.l, b.l, c.l)
  GetVersionFromFile(a.l, b.l, c.l)
  EnumerateInstalledRuntimes(a.l)
  EnumerateLoadedRuntimes(a.l, b.l)
  RequestRuntimeLoadedNotification(a.l)
  QueryLegacyV2RuntimeBinding(a.l, b.l)
  ExitProcess(a.l)
EndInterface

Interface ICLRRuntimeInfo
  QueryInterface(a.l, b.l)
  AddRef()
  Release()
  GetVersionString(a.l, b.l)
  GetRuntimeDirectory(a.l, b.l)
  IsLoaded(a.l, b.l)
  LoadErrorString(a.l, b.l, c.l, d.l)
  LoadLibrary(a.l, b.l)
  GetProcAddress(a.l, b.l)
  GetInterface(a.l, b.l, c.l)
  IsLoadable(a.l)
  SetDefaultStartupFlags(a.l, b.l)
  GetDefaultStartupFlags(a.l, b.l, c.l)
  BindAsLegacyV2Runtime()
  IsStarted(a.l, b.l)
EndInterface

Interface ICorRuntimeHost ; Common Language Runtime Hosting Interface
  QueryInterface(riid.l,ppvObj.l)
  AddRef()
  Release()
  CreateLogicalThreadState()
  DeleteLogicalThreadState()
  SwitchInLogicalThreadState(pFiberCookie.l)
  SwitchOutLogicalThreadState(pFiberCookie.l)
  LocksHeldByLogicalThread(pCount.l)
  MapFile(hFile.l,hMapAddress.l)
  GetConfiguration(pConfiguration.l)
  Start()
  Stop()
  CreateDomain(pwzFriendlyName.p-unicode,*pIdentityArray.IUnknown,pAppDomain.l)
  GetDefaultDomain(pAppDomain.l)
  EnumDomains(hEnum.l)
  NextDomain(hEnum.l,pAppDomain.l)
  CloseEnum(hEnum.l)
  CreateDomainEx(pwzFriendlyName.p-unicode,*pSetup.IUnknown,*pEvidence.IUnknown,pAppDomain.l)
  CreateDomainSetup(pAppDomainSetup.l)
  CreateEvidence(pEvidence.l)
  UnloadDomain(*pAppDomain.IUnknown)
  CurrentDomain(pAppDomain.l)
EndInterface

Interface Int__Assembly
  GetToString()
  Equals(a)
  GetHashCode()
  GetType()
  CodeBase()
  EscapedCodeBase()
  GetName()
  GetName_2(a)
  GetFullName()
  GetEntryPoint()
  GetType_2(a)
  GetType_3(a,b)
  GetExportedTypes()
  GetTypes()
  GetManifestResourceStream(a,b)
  GetManifestResourceStream_2(a)
  GetFile(a)
  GetFiles()
  GetFiles_2(a)
  GetManifestResourceNames()
  GetManifestResourceInfo(a)
  GetLocation()
  GetEvidence()
  GetCustomAttributes(a,b)
  GetCustomAttributes_2(a)
  IsDefined(a,b)
  GetObjectData(a,b)
  add_ModuleResolve(a)
  remove_ModuleResolve(a)
  GetType_4(a,b,c)
  GetSatelliteAssembly(a)
  GetSatelliteAssembly_2(a,b)
  LoadModule(a,b)
  LoadModule_2(a,b,c)
  CreateInstance(a)
  CreateInstance_2(a,b)
  CreateInstance_3(a,b,c,d,e,f,g)
  GetLoadedModules()
  GetLoadedModules_2(a)
  GetModules()
  GetModules_2(a)
  GetModule(a)
  GetReferencedAssemblies()
  GetGlobalAssemblyCache()
EndInterface

Interface Int__AppDomain
  QueryInterface(riid.l,ppvObj.l)
  AddRef()
  Release()
  Hidden1()
  Hidden2()
  Hidden3()
  Hidden4()
  GetToString()
  Equals(a)
  GetHashCode()
  GetType()
  InitializeLifetimeService()
  GetLifetimeService()
  GetEvidence()
  add_DomainUnload(a)
  remove_DomainUnload(a)
  add_AssemblyLoad(a)
  remove_AssemblyLoad(a)
  add_ProcessExit(a)
  remove_ProcessExit(a)
  add_TypeResolve(a)
  remove_TypeResolve(a)
  add_ResourceResolve(a)
  remove_ResourceResolve(a)
  add_AssemblyResolve(a)
  remove_AssemblyResolve(a)
  add_UnhandledException(a)
  remove_UnhandledException(a)
  DefineDynamicAssembly(a,b)
  DefineDynamicAssembly_2(a,b,c)
  DefineDynamicAssembly_3(a,b,c)
  DefineDynamicAssembly_4(a,b,c,d,e)
  DefineDynamicAssembly_5(a,b,c,d)
  DefineDynamicAssembly_6(a,b,c,d,e,f)
  DefineDynamicAssembly_7(a,b,c,d,e,f)
  DefineDynamicAssembly_8(a,b,c,d,e,f,g)
  DefineDynamicAssembly_9(a,b,c,d,e,f,g,h)
  CreateInstance(a,b)
  CreateInstanceFrom(a,b)
  CreateInstance_2(a,b,c)
  CreateInstanceFrom_2(a,b,c)
  CreateInstance_3(a,b,c,d,e,f,g,h,i)
  CreateInstanceFrom_3(a,b,c,d,e,f,g,h,i)
  Load(a)
  Load_2.i(a.p-bstr)
  Load_3(a)
  Load_4(a,b)
  Load_5(a,b,c)
  Load_6(a,b)
  Load_7(a,b)
  ExecuteAssembly(a,b)
  ExecuteAssembly_2(a)
  ExecuteAssembly_3(a,b,c)
  GetFriendlyName()
  GetBaseDirectory$()
  GetRelativeSearchPath()
  GetShadowCopyFiles()
  GetAssemblies()
  AppendPrivatePath(a)
  ClearPrivatePath()
  SetShadowCopyPath(a)
  ClearShadowCopyPath()
  SetCachePath(a)
  SetData(a,b)
  GetData(a)
  SetAppDomainPolicy(a)
  SetThreadPrincipal(a)
  SetPrincipalPolicy(a)
  DoCallBack(a)
  GetDynamicDirectory()
EndInterface

pClrHost.ICLRMetaHost
pRunInfo.ICLRRuntimeInfo
pRuntimeHost.ICorRuntimeHost
pDomain.IUnknown
myAppDomain.Int__AppDomain
loadedAssembly.Int__Assembly

corlib.i = OpenLibrary(#PB_Any, "mscoree.dll")
If corlib <> 0
  MessageRequester("Test","It's Open")
  hr.i = CallFunction(corlib,"CLRCreateInstance",?CLSID_CLRMetaHost,?IID_ICLRMetaHost,@pClrHost)
  If hr = #S_OK 
    MessageRequester("Text","Bind")
    version.s = "v4.0.30319"
    hr = pClrHost\GetRuntime(@version,?IID_ICLRRuntimeInfo,@pRunInfo)
    If hr = #S_OK
      MessageRequester("Test","Have Runtime")
      fLoadable.l
      hr = pRunInfo\IsLoadable(@fLoadable)
      If hr = #S_OK
        If fLoadable = 1
          hr = pRunInfo\GetInterface(?CLSID_CorRuntimeHost,?IID_ICorRuntimeHost,@pRuntimeHost)
          If hr = #S_OK
            MessageRequester("Test","Runtime loaded")
            hr = pRuntimeHost\Start()
            If hr = #S_OK
              hr = pRuntimeHost\CreateDomain("MyDomain",0,@pDomain)
              If hr = #S_OK
                MessageRequester("Test","Got domain")
                myAppDomain = pDomain
                hr = pDomain\QueryInterface(?IID_AppDomain,@myAppDomain)
                If hr = #S_OK
                  MessageRequester("Test","Got interface to domain")
                  temp.s
                  temp = ".\Test\Test\bin\Release\Test.dll"+Chr(0)+Chr(0)
                  OnErrorGoto(?LoadError)
                  hr = myAppDomain\Load_2(temp)
				          If hr = #S_OK
				            MessageRequester("Test","ExecuteAssembly")
				            Goto Cleanup
				          Else
				            MessageRequester("Test","Error loading assembly "+Str(hr))
				          EndIf
				          Goto Cleanup
				          LoadError:
				          MessageRequester("Test", "Load error " + ErrorMessage())
				          Cleanup:
				          myAppDomain\Release()
				          myAppDomain = Null
				        Else
				          MessageRequester("Test", "Unable to get interface to domain")
				        EndIf
                pDomain\Release()
                pDomain = Null
              EndIf
              pRuntimeHost\Stop()
            EndIf
            pRuntimeHost\Release()
            pRuntimeHost = Null
          EndIf
        Else
          MessageRequester("Test","Dot Net 4.0 can not be loaded")
        EndIf
      EndIf
      pRunInfo\Release()
      pRunInfo = Null
    Else
      MessageRequester("Error",Hex(hr))
    EndIf
    pClrHost\Release()
    pClrHost = Null
  Else
    MessageRequester("Error",Hex(hr))
  EndIf
  CloseLibrary(corlib)
  corlib = Null
Else
  MessageRequester("Test", "Not Open")
EndIf

DataSection
  IID_ICLRMetaHost:
    Data.l $D332DB9E
    Data.w $B9B3, $4125
    Data.b $82, $07, $A1, $48, $84, $F5, $32, $16  
    
  CLSID_CLRMetaHost:  
    Data.l $9280188d
    Data.w $e8e, $4867
    Data.b $b3, $c, $7f, $a8, $38, $84, $e8, $de
    
  IID_ICLRRuntimeInfo:
    Data.l $BD39D1D2
    Data.w $BA2F, $486a
    Data.b $89, $B0, $B4, $B0, $CB, $46, $68, $91
    
  CLSID_CorRuntimeHost:
    Data.l $cb2f6723
    Data.w $ab3a, $11d2
    Data.b $9c, $40, $00, $c0, $4f, $a3, $0a, $3e  

  IID_ICorRuntimeHost:  ; {CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}
    Data.l $CB2F6722
    Data.w $AB3A,$11D2
    Data.b $9C,$40,$0,$C0,$4F,$A3,$A,$3E
    
  IID_AppDomain:  ; {05F696DC-2B29-3663-AD8B-C4389CF2A713}
    Data.l $05F696DC
    Data.w $2B29,$3663
    Data.b $AD,$8B,$C4,$38,$9C,$F2,$A7,$13
    
  CLSID_AppDomain:  ;{5FE0A145-A82B-3D96-94E3-FD214C9D6EB9}
    Data.l $5FE0A145
    Data.w $A82B,$3D96
    Data.b $94,$E3,$FD,$21,$4C,$9D,$6E,$B9
    
  EndDataSection
  

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Wed Mar 28, 2012 4:45 am
by IdeasVacuum
Hmm, no doubt you have a reason but I think it's a lot easier to just code in C# if you really need to work with .Net. Square pegs, round holes etc.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Wed Mar 28, 2012 4:48 am
by idle
IdeasVacuum wrote: Square pegs, round holes etc.
:lol: yep even if you do it from c# it's still like that

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Sun Apr 01, 2012 5:13 pm
by Project Mayu
I have this already working in Powerbasic, but since Powerbasic does not have a x64 version, I wanted to try to get it to work in Purebasic.

It is handy to have an app that tells you the you need to install Dot Net 4.0, or some other required component, instead of just crashing.

It also can be used to prevent de-compiling. Since the resulting Dot Net Metadata can be inserted into the Native EXE, reflector will not work on it.

It would also let me understand a deeper level into Purebasic.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Sun Apr 01, 2012 8:21 pm
by idle
sorry I can't help, not on windows but if you have it working in PowerBasic why not post that
along with the PureBasic port.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Mon Apr 02, 2012 9:07 am
by Project Mayu

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Mon Apr 02, 2012 2:02 pm
by SFSxOI
I I compile your code in unicode I get to this part:

Code: Select all

MessageRequester("Test","Got interface to domain")
Then it crashes here:

Code: Select all

temp.s
                  temp = ".\Test\Test\bin\Release\Test.dll"+Chr(0)+Chr(0)
                  OnErrorGoto(?LoadError)
...at the "OnErrorGoto(?LoadError)" line with the error "Error loading assembly -2146234297" from the line:

If I do not compile it unicode (compile in ansi) it doesn't get that far at all and only gets to the "MessageRequester("Text","Bind")"

Is this the type of thing your talking about when you say it doesn't work?

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Mon Apr 02, 2012 3:12 pm
by Rings
i got the same result as SFSxOI(compile in unicode mode needed ).
The Functions \Load_2 is not the same as in the powerbasic example.
is there any place in the net where to look at these functions in the interface ?

Load_2 = Load Assembly from file ?

Load_3 = Load Assembly from Memory ?

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Mon Apr 02, 2012 4:13 pm
by SFSxOI
Hmmmm... isn't "Load_2(temp)" supposed to be a bstr varient - and should not the 'temp' have been loaded from the varient?

.. or something like that

anyway, according to the code interface - Load_2.i(a.p-bstr)

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Mon Apr 02, 2012 4:51 pm
by fsw
SFSxOI wrote:...at the "OnErrorGoto(?LoadError)" line with the error "Error loading assembly -2146234297" from the line...
Seems to me to be a signed/unsigned type issue.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Mon Apr 02, 2012 6:15 pm
by SFSxOI
fsw wrote:
SFSxOI wrote:...at the "OnErrorGoto(?LoadError)" line with the error "Error loading assembly -2146234297" from the line...
Seems to me to be a signed/unsigned type issue.
yeah, thats what its sort of looks like to me too. Made me wonder about the declaration for the Load_2() in the Int__AppDomain interface, if it would cause the same thing.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Tue Apr 03, 2012 7:08 am
by Project Mayu
I kind of Like Load3 (no locking of the file, what and the file can come from any source), but since I did not yet know enough about Purebasic, I figured I would try to get Load2 working.
Most of the interface stuff in Powerbasic was gathered using the Powerbasic com browser, but since Purebasic does not have one of those, I have been trying to do it all by hand.
The Powerbasic version was ported from a C++ version, and a lot of help from the Powerbasic community.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Tue Apr 03, 2012 7:34 am
by SFSxOI
What is the C++ source, more correctly, where can we get it to take a look?

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Wed Apr 04, 2012 3:27 pm
by Project Mayu
Sorry I don't have the link saved anymore, if I remember correctly it was on the Microsoft Blog, or one of the blogs for a Microsoft Employee.

Re: Help getting Dot Net 4 to work in Purebasic

Posted: Wed Apr 04, 2012 3:52 pm
by ultralazor
FYI PB is FASM

Also embedding the .NET binary in non-MSIL EXE won't be any more secure than obfuscating the MSIL of a .NET binary. If your solution ever becomes in-demand it won't matter anyway, crack teams will rebuild it in a couple days tops and have it released.

.NET obfucators are actually better than machine code ones also, because they don't decrypt or allocate original code at runtime. Machine code ones at best put all original code through a light decryption and some instruction handlers and they can all be traced and dumped, or inlined on the fly.