From: bufie
Subject: (semi-newbie question) make macro unexpandable?
Date: 
Message-ID: <obtqc.73234$536.11878588@attbi_s03>
Hi,

I am developing a macro that will be used for a security license check
(using 3rd party calls).  The reason for the macro is to more securely
"wrap" these additional calls to prevent the parameters from being traced.
It's easy enough to do it all inline, but I'd like to be able to let others
use the "wrapper" function/macros without being able to see what's going on
inside of them.

(this is related to my other recent thread about tracing, and incorporates
the suggested changes)

at first I had a couple of macro that looked like this (with some stuff
stripped out that is irrelevant to this discussion):

(defmacro my-license-check (key1 key2 key3 key4)
  (let ((*trace-output* (make-broadcast-stream))
    (okay)
    )
    (setq okay (license-check key1 key2 key3 key4))
    okay
    )
  )

Since I didn't want anyone to be able to trace my "wrapper" call, I used a
macro so it would be expanded inline at compile time. Also, since I wanted
to let others use these calls, the above macro looked like it would do the
trick -- "macroexpand" only returned the result of "okay" so my code was
safe.

So I thought I was home free...  I could compile the file with my macro
definitions in it, and then let others load this file, use my licensing
macros in their code, and when they compiled their code they'd get my macros
expanded inline so they wouldn't need to ship my macro definition file.

but not so fast...

It turns out that the above macro definition (without any backquotes)
expands great when the macro is defined, but at compile time only the result
of the macro gets compiled in (i.e. no license checking is actually done at
runtime).  So I figured I could solve this problem by slightly modifying the
above macro to:

(defmacro my-license-check (key1 key2 key3 key4)
 ` (let ((*trace-output* (make-broadcast-stream))
    (okay)
    )
    (setq okay (license-check ,key1 ,key2 ,key3 ,key4))
    okay
    )
  )

and this will still be expanded inline at compile time (right?).  so there
is no problem at runtime, but the problem is now that my macro definitions,
even when compiled, can be examined using macroexpand to see what is being
done.

Is there a way to prevent these macros from being expanded?  Any other
thoughts on how to protect this code?

Thank you in advance for any help,

bufie

From: Joe Marshall
Subject: Re: (semi-newbie question) make macro unexpandable?
Date: 
Message-ID: <wu39h3in.fsf@ccs.neu.edu>
"bufie" <·····@spamneggs.com> writes:

>
> Is there a way to prevent these macros from being expanded?  

One trick is to develop two such macros and only distribute one of
them.  Use the other internally.


> Any other thoughts on how to protect this code?

Ultimately, you can't.  You can only make it hard to reverse
engineer.  You might be able to make it so hard to reverse engineer
that no one would bother.
From: bufie
Subject: Re: (semi-newbie question) make macro unexpandable?
Date: 
Message-ID: <2AOqc.80446$xw3.4480715@attbi_s04>
Hi all,

thanks for the comments.  I appreciate the ideas that have been shared.

> > Is there a way to prevent these macros from being expanded?
>
> One trick is to develop two such macros and only distribute one of
> them.  Use the other internally.

Nice idea!

> > Any other thoughts on how to protect this code?
>
> Ultimately, you can't.  You can only make it hard to reverse
> engineer.  You might be able to make it so hard to reverse engineer
> that no one would bother.

Ok, so here's an (ugly) idea that I think might do the trick (though I would
most likely need some help with implementation):

known issues:
1) the security system definitely needs an overhaul since the keys
themselves are vulnerable (but I can't control this partince our application
is an add-in module for another application)
2) I want to protect the code that I developed to do the license checking.
3) the keys need to be protected.

So, what if I had a macro that the user could link into their code that did
something like this:
1) create a global variable
2) stick the keys into this global variable (preferably encrypted -- how do
I do this?)
3) call a separate (compiled) function that does all the license checking
(most likely with dummy parameters to fool traces)
4) read the function result, either from the return value or from another
global var created by the function (or both)
5) unbind the global var

then the separate function would do similar things as above:
1) read the info from the global var (and decrypt if necessary)
2) unbind the global var (this way the global var is only in existence for a
very short time)
3) do the license check
4) create a new global var
5) stick a set of results (more than just the expected result) into the
global var (to help check for someone redefining the license function)
6) return some value to the calling macro

This approach should allow me to keep the license-checking methodology
buried in the compiled function, and to pass parameters back and forth in a
(hopefully) more difficult-to-trace manner. (esp. if I can dynamically
assign the names of the global variables, perhaps using time-coding or
something).

Any thoughts on whether this would work (and how well)?

thanks,

bufie
From: ·········@random-state.net
Subject: Re: (semi-newbie question) make macro unexpandable?
Date: 
Message-ID: <c8do9m$amf3n$2@midnight.cs.hut.fi>
bufie <·····@spamneggs.com> wrote:

> I am developing a macro that will be used for a security license check
> (using 3rd party calls).  The reason for the macro is to more securely
> "wrap" these additional calls to prevent the parameters from being traced.

I confess I have no idea what you meant by these three lines. Can you
clarify?

On a similar note: how would you prevent someone from attaching a debugger
to the process and tracing the execution stepwise? Unless you control the
box they're running on you can't.

> It's easy enough to do it all inline, but I'd like to be able to let others
> use the "wrapper" function/macros without being able to see what's going on
> inside of them.

If others can use your macro they can always obtain the exansion, remove
any trace hackery you've done and use it then.

Unless I'm wastly misunderstanding your meaning it seems to me that you
need to rethink your approach to these issues. Preventing anyone from
seeing what arguments go into a given function (beyond simple obfuscation)
isn't necessarily doable at all -- if the keys are vulnerable your security
architecture needs an upgrade.

Cheers,

  -- Nikodemus
From: Svein Ove Aas
Subject: Re: (semi-newbie question) make macro unexpandable?
Date: 
Message-ID: <4utqc.2272$RL3.58507@news2.e.nsc.no>
bufie wrote:

> Hi,
> 
> I am developing a macro that will be used for a security license check
> (using 3rd party calls).  The reason for the macro is to more securely
> "wrap" these additional calls to prevent the parameters from being
> traced. It's easy enough to do it all inline, but I'd like to be able to
> let others use the "wrapper" function/macros without being able to see
> what's going on inside of them.
> 
> (this is related to my other recent thread about tracing, and
> incorporates the suggested changes)
> 
> at first I had a couple of macro that looked like this (with some stuff
> stripped out that is irrelevant to this discussion):
> 
> (defmacro my-license-check (key1 key2 key3 key4)
>   (let ((*trace-output* (make-broadcast-stream))
>     (okay)
>     )
>     (setq okay (license-check key1 key2 key3 key4))
>     okay
>     )
>   )
> 
> Since I didn't want anyone to be able to trace my "wrapper" call, I used
> a macro so it would be expanded inline at compile time. Also, since I
> wanted to let others use these calls, the above macro looked like it
> would do the trick -- "macroexpand" only returned the result of "okay"
> so my code was safe.
> 
> So I thought I was home free...  I could compile the file with my macro
> definitions in it, and then let others load this file, use my licensing
> macros in their code, and when they compiled their code they'd get my
> macros expanded inline so they wouldn't need to ship my macro definition
> file.
> 
> but not so fast...
> 
> It turns out that the above macro definition (without any backquotes)
> expands great when the macro is defined, but at compile time only the
> result of the macro gets compiled in (i.e. no license checking is
> actually done at
> runtime).  So I figured I could solve this problem by slightly modifying
> the above macro to:
> 
> (defmacro my-license-check (key1 key2 key3 key4)
>  ` (let ((*trace-output* (make-broadcast-stream))
>     (okay)
>     )
>     (setq okay (license-check ,key1 ,key2 ,key3 ,key4))
>     okay
>     )
>   )
> 
> and this will still be expanded inline at compile time (right?).  so
> there is no problem at runtime, but the problem is now that my macro
> definitions, even when compiled, can be examined using macroexpand to
> see what is being done.
> 
> Is there a way to prevent these macros from being expanded?  Any other
> thoughts on how to protect this code?

(declare (optimize (debug 0)); might help a bit.

I know this probably isn't what you want to hear, but you're asking the
impossible. There may be ways to stop this particular problem, but when
you get right down to it there is no way whatsoever to stop the customer
from breaking your security, if the program is going to run on his
computer.

Historically, *no* software security system has ever remained uncracked,
and Lisp is possibly the worst possible compiled language to try it in.
Your options are really just one of two:

- Trust your customer, and only use a very light/nonexistent security
system.
- Move some of the code into a serial (USB) dongle of some sort. This has
been shown to work, but it makes updates a pain, not to mention using
your program at all.
From: Tayssir John Gabbour
Subject: Re: (semi-newbie question) make macro unexpandable?
Date: 
Message-ID: <866764be.0405182009.41f802e3@posting.google.com>
Svein Ove Aas <··············@brage.info> wrote in message news:<····················@news2.e.nsc.no>...
> Historically, *no* software security system has ever remained uncracked,
> and Lisp is possibly the worst possible compiled language to try it in.
> Your options are really just one of two:
> 
> - Trust your customer, and only use a very light/nonexistent security
> system.
> - Move some of the code into a serial (USB) dongle of some sort. This has
> been shown to work, but it makes updates a pain, not to mention using
> your program at all.

Some people apparently find that having anti-cracking schemes is a
profitable investment; the goal is to "keep honest people honest."
Like any investment, I'd scrutinize and ask around whether it's
actually a profitable one.

There are sites like:
http://www.inner-smile.com/nocrack.phtml

Incidentally, Autocad has some experiences with dongles.. not that I
think this is germane to the topic:
http://www.fourmilab.ch/autofile/www/chapter2_48.html
http://www.fourmilab.ch/autofile/www/chapter2_80.html

WRT obfuscation, without having really thought about it in lisp's
context, it seems rather fun to write one in lisp. A problem of course
is debugging issues. I've used a couple of obfuscators for Java, and
I've found one version of the popular Dash-O-Pro to be brittle. I did
not trust the damn thing. If one goes this route, the code must be
engineered with the goal of easily isolating the scenario which
triggered obfuscator bugs.