Encryption

Hi @TechDojo,

Yes, this is all done at the post-export level, my project is in a private Github repo and I just pull in Lua source and assets from the Codea export into an existing project with all my custom stuff…

I’ll write up the source encryption process and post here in a day or two…

I understand your two-phase approach but feel it may be difficult to pull off as you would need to return an image object a la readImage() from a lua function registered in the C code… You could theoretically store image data as an XOR-ed two-dimensional array and then read that in and recompose the image using the Codea/Lua image:set(x, y, colour) functions…but that would be quite slow…

Brookesi

@brookesi - so is it possible to actually use luac to compile the codea output files and still use them in the exported xCode project?

I was thinking of writing a little program that takes a codea project and reads in the info.plist file and concatenates all the lua files into a single entity ready for running through an obfuscator and or compiler. I’d like to make the process as simple as possible so I can make it part of the workflow from exporting from Codea through to running in xCode.

Hi @TechDojo,

Sorry, long time away from the forum…

So, yes, it is possible, and we are doing that, it is a little involved, so here goes:

You need to download and install the 32 and 64 bit versions of Lua to your Mac

I then have a shell script that lists all the .lua files in the correct compilation order (you could probably generate this from plist) and then calls the 32 and 64 bit luac executable on those files to generate a 32 and 64 bit version of lua bytecode in the .codea directory.

I then move all the .lua files out of the .codea directory to a safe area except the two bytecode files…

I then create a Main.lua that looks like:

-- Bootstrap
function setup()
    local status, error = loadBytecode()
    if(status == 0) then
        -- setup() now points to 'real' setup(), invoke it!
        setup()
    else
        print(\"Failed to load bytecode: status:\", status, \", error:\", error)
     end
end

Then in the common AddOn .mm file I register a static function called loadBytecode that reads in the files like:

    NSString* nsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"InfestedMars.codea"];
    NSString* nsFileName = [NSString stringWithFormat:@"InfestedMars%s.obf", ARCH];
    nsPath = [nsPath stringByAppendingPathComponent:nsFileName];

where ARCH is a constant based on:

#if __LP64__
const char* ARCH = "_64.bc";
#else
const char* ARCH = "_32.bc";
#endif

then you read that file into an NSData object and do:

    int status = luaL_loadbuffer(state, data.bytes, data.length, ARCH);
    if(status == 0) {
        lua_pcall(state,0,0,0);
    }
    const char* error = lua_tostring(state,-1);
    
    lua_pushinteger(state, status);
    lua_pushstring(state, error);
    
    return 2;
}

Sorry, i couldnt paste my exact code, but the above basically loads the bytecode file into the Lua VM based on the architecture when you call the loadBytecode function, which then overrides the setup() function etc. with the Lua VM so when you call setup() again the whole shebang uses the bytecode…

Hope that makes sense…

I actually encrypt the bytecode and then decrypt on the fly so no plaintext source is bundles with the app…

There is actually another way I’m looking at which is to use the bin2c executable in the Lua bin dir which will convert the Lu code into C arrays which can then be loaded…

Let me know if you need more info…

Brookesi

Hi @brookesi - that’s a great help thank you.
I was planning on writing a little source obfuscator that just minimises the source and optionally does a little name-munging on local variables, although I had a little D’oh moment when I realised that if all the code was in a single .lua file the “local’s” in each chunk would get in each others way (I tend to make use of local scope to enforce OO style encapsulation) - so I’d need to keep to separate files (although I was going to munge the names).

I know it’s not a perfect solution but I figured it was a start (although yours does sound a lot better and I’ll experiment with it to see if I can get it working).

I don’t normally have a problem with not protecting assets and actually sharing code etc, but currently it’s so easy to take a Codea app from the app store, look in the .ipa and then basically recreate the entire project back in Codea for simple editing and then re-releasing that even the most noob hacker could probably manage it, plus I was considering selling some of my projects on a site like http://www.chupamobile.com/ and opening it up for sponsorship / rebranding myself.

Heyy @TechDojo,

My pleasure. Yes, you would generally need to maintain the file structure otherwise you would need a set of ‘module’ namespaces, so every local is a table element, or something, bit nasty anyway ;))

Re: your last paragraph, yeah, just a little too easy to rip stuff off…

Hmmm… chupamobile sounds interesting, as we now have a generic engine pretty much…thank you,

Brookesi