Objo: A Very Promising Development Environment

You joke but it’s already on the roadmap… :grinning_face:

Are you sure???

I wanted to believe that so I opened the app to test and the whole Objo.Studio.Services.Licensing source code is there in plain C#

Maybe but a lot of experience and time is needed to get something from the assembler. In this case .Net takes like 5 seconds to get the plain C# source code :roll_eyes:

By the way, @Garry, I hope there is an EULA with the classic you shall not decompile but an EULA is NOT enforceable In contract law if you never showed it at any stage of downloading or using the app and get the user to agree with it.

I didn’t say Garry uses AOT, I have no idea about that. Only that you can compile that way.

I suppose that since .NET APIs are well known and there’s reference source for a most of it, some sense could be made of calls into that, even from the machine code generated by AOT compilation.

In any case, the bytecode of a compiled Objo app resides in a separate .objoc file and that is run by a custom VM and the byecode format has not been reverse engineered. It probably could be, by a sufficiently motivated person. But Garry has already said he will be offering encryption for it.

My own view is that your best defense against bad actors is to innovate too fast for them to keep up – and Garry is definitely doing that.

There are two separate things being discussed here, so it’s worth clarifying them.

Objo Studio is written in C# and .NET. A .NET decompiler can reconstruct a C# representation from compiled assemblies. That does not mean the original source files are stored inside the application in plain text. The original comments, formatting, project structure and other information are absent but decompiled output could be readable. NativeAOT or obfuscation can raise the effort required, but neither makes software impossible to analyse.

Apps created with Objo are different. They do not contain the developer’s original Objo source code. Published apps contain custom Objo bytecode, and release builds remove comments, source locations, line numbers and local-variable names. It would be misleading to claim that reverse engineering is impossible, because anything running on somebody else’s computer can potentially be analysed, but this is very different from recovering the original project and source code in a few seconds.

Further bytecode-protection options are on the roadmap. I will not describe them as “uncrackable”; the goal is to provide commercially sensible protection that raises the effort involved without compromising application reliability.

for pretty obvious reason, I don’t discuss the implementation of Studio’s licensing or other security-sensitive measures publicly.

Objo Studio already has published terms and conditions, linked from within Studio, which address reverse engineering subject to applicable law. The separate point about how prominently those terms are presented is fair, and I’ll review that. Their enforceability in any particular situation is a legal and jurisdiction-specific question, not something that can be settled by me in a forum post.

Could it not compile to .NET byte code ? I mean is there good reason why you have your own byte code on top of already interpreted language ?

MS has good API to help you compile any language into the .NET byte code.

Yes, Objo could compile to .NET IL, and it’s something I have considered.

My custom VM was chosen deliberately. It gives Objo complete control over its language semantics, memory management, async scheduler, event context and runtime object model. It also makes the edit–run–debug cycle very fast and allows the debugger and profiler to operate directly in terms of Objo source rather than translated CLR concepts.

Strictly speaking, this is not an interpreted language running on another interpreter. The C# implementation of the VM is normally JIT-compiled to native machine code by .NET; the VM then interprets Objo bytecode.

Producing IL is certainly possible, especially with the APIs available in recent .NET versions. Emitting instructions is only the easy part, though. Preserving Objo’s exact behaviour, including ARC and deterministic destruction, closures, events, generics, async fibres, native methods, introspection and debugging, would effectively mean maintaining a second compiler backend and then validating it against the VM.

Ordinary .NET IL would make decompilation easier, not harder, because excellent .NET decompilers already exist. The more interesting possibility would be an optional IL backend followed by NativeAOT compilation. That could improve execution speed and make published applications harder to analyse, although NativeAOT brings its own restrictions and compatibility work.

My preferred architecture would therefore be to retain the custom VM for development, running and debugging, while leaving open the possibility of an optional IL/NativeAOT release backend in the future. It is a worthwhile idea, but not a simple substitution for the existing bytecode VM.