Flux RSS

Lua tricks: Carbonite obfuscation

I don't know if this fits exactly in the "Rant" category, or if I should create a "Praise" one, because I'm not sure if I'm utterly amazed or disgusted, but this definitely gets my attention.

There's one addon for World of Warcraft called Carbonite, which made a controversy some time ago, because it wasn't free. It was even subscription-based, costing a couple of dollars a month to be able to use it. I've been wondering a long time how they were able to do a proper license check, but the addon itself was heavily obfuscated using several layers.

Obfuscating something in a language that's actually plain text is somehow very difficult. I've seen HTML pages encapsulated in a javascript file that would self-unencrypt using RC4 where you have to provide the password, for example. But in the case of Carbonite, the authors wanted to match a certain number of criterias:

  1. The process had to be transparent for their subscribers, as they only had to log in with their registered character to unlock the addon;
  2. The process had to be limited in time;
  3. The process had to be strong and very difficult to circumvent.

Now, when Blizzard decided to release a new policy about addons, forbidding to sell or obfuscate addons, the people at Carbonite released their version 3.001 which was free and somehow unobfuscated. You may want to have a look at this old beast as it's still available for download at wowinterface, but allow me to show you what's interesting in it. Note that future versions of the addon got rid of what I'm going to show there.

As I said, there was already several layers of obfuscations, but in all cases when you have an obfuscation, if the inner process isn't something strong or unusual, people might just be able to find a loophole to skip all the first layers of obfuscation and directly get to the point.

Here's some code extract from Carbonite 3.001, where the upper parts of obfuscations were removed, which means most of the function names and variable isn't horribly mangled. I'll let you see for yourself what the full version of it is, but search for the words "I68". Again, this word was mangled before the 3.0 release.

Nx.I68={}
function Nx.I68:Run()
self.Sta3={}
self.Reg={}
self.CCz=false
self.CCn=false
for n=0,15 do
self.Reg[n]=0
end
local mem1=self.Mem
while true do
local pc=self.PC
local op=mem1[pc]*256+mem1[pc+1]
pc=pc+2
self.PC=pc
local h4=self.RS(op,12)
[...]
function Nx.I68:Tes()
local s={"1251000103C0000123C000554005301...
self:Loa1(s)
self:Run()
end
function Nx.Sec:VaT()
local s={"125100041F90000101C4E41068000004EE806...
Nx.I68:Loa1(s)
Nx.I68:Run()
local dt=Nx.I68:GeR(0)
local x=110802
if dt>=x then
[...]
function Nx.I68:GeR(reg)
return self.Reg[reg]
end
function Nx.I68:GeS5(add1)
local s=""
local b=self.Mem[add1]
while b~=0 do
s=s .. Nx.st_(b)
add1=add1+1
b=self.Mem[add1]
end
[...]
function Nx.I68:Ini()
self.And=Nx.ba_
self.Or=Nx.bo_
self.RS=Nx.rs_
self.LoS1=Nx.ILS
self.BiM={}
[...]

Now, what does that mean exactly ? Well, my best guess is the following: "I68" stands for a virtual processor they invented, probably a pun of i86 or something. This processor has some memory, probably something like 64Kb, as the pointers seems to be 16 bits large as indicated by "mem1[pc]*256+mem1[pc+1]", and the Run function actually reads opcodes one after the other, interprets them, and go on with the execution. The machine seems to have a few general registers, as indicated by "GeR" that'd be "Get Register" at my best guess, which, anyway, returns something in an array called "Reg", and so on and so forth. The opcodes are wired to some of the Lua internal functions, and the "LoS1" opcode is a quite wicked piece of obfuscation somewhere that's just trying to do a LoadString in Lua itself.

So at the end, the "license" for Carbonite was only that: a lengthy string of hex characters that would contain byte code, executed within the virtual machine itself, in order to check you character's name and the time of the day to see if your license was still valid.

That's one of the most clever usage of a license string I've ever seen. I mean, most of the time, it's either some random numbers checked online, or numbers with some very obfuscated self-checksums, or even an heavily encrypted string. This is the first time I'm seeing a license code being a true byte-code. The very disturbing part is that this is a virtual machine written using a language that is a virtual machine itself. So adding that with obfuscation on the top of it, that was probably one of the most wicked protection that went past my eyes, even though I haven't seen so many of them.

Still, if my brain admits this is a brilliant piece of obfuscation, my guts are still somewhat disgusted by it. That's clever job, but at the end, what a load of work being finally trash... such a waste... that'll keep in my book as a strange gem, just in case.

Comments

1. On Thursday, October 1 2009, 02:53 by Starhiker

Sorry to use this channel for asking this, but I could not find your e-mail address. What happened to WoW Paper Idol, and will it ever be back? Please answer to my e-mail. Jim