Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: Rebol Product Suggestion.

From: joel:neely:fedex at: 24-Jun-2001 3:16

Gabriele Santilli wrote:
> JN> Unless RT adds a primitive that's the equivalent of > > JN> do decrypt somestring > JN> somestring: "" >
Let me detail this to do-crypt: make native! [voodoo-stuff] [ hidden-buffer: decrypt voodoo-stuff block-buffer: load hidden-buffer clear hidden-buffer do block-buffer clear block-buffer ] (terrible hypothetical REBOL style, just to make the point).
> Yes, but then again with proper reverse engeneering one could > get to the source anyway. A "lossy" conversion, instead, > guarantees that noone can get to the original source in any > way. >
Assuming that there's no such thing as perfectly secure encryption, there's always *some* way to crack something. As you pointed out earlier, compiled binaries can be analyzed and disassembled. However, few people have sufficient time, money, tools, skills, patience, and motivation (i.e., "cost" factors) to reverse engineer a reasonably-sized binare. IMHO the game is about simply raising the costs high enough that most people won't bother. That's why I suggest the "do-crypt" option. If the decrypted source only exists in a buffer long enough for REBOL to load it to an internal data structure, which only exists long enough to be DOne, and all of the above is done within a native that can't be examined with SOURCE, then the distributed source code is much more secure than if the decryption were done by the user and/or left in a user- accessible place in memory. Of course, the attacker could still hook up a logic analyzer, use an ICE debugger, or run a Pentium emulator on his friendly neighborhood Beowulf, etc., but those options all raise the costs beyond most users' means. You're absolutely right that "shrouding" the code (in the sense we were discussing and I illustrated) would further raise the costs if combined with do-crypt.
> what about: > > propercase: func [s] > [head lowercase next uppercase/part copy s 1] >
Nice! (But you didn't show how that change would affect the shrouded copy! ;-)
> JN> result: copy nextsep: "" > > BTW, in these cases I usually write: > > result: clear "" > ; ... > copy result > > because that will probably require less memory allocations. > After calling the function a couple times, indeed, the result > buffer will automatically end up being as large as needed and > no more memory allocations and copying will be needed in > future calls, except for the explicit final copy. (Well, I > couldn't resist giving my $0.02. :) >
That's an interesting approach; let me think out loud... result: copy "" ;... result ... copies a trivial string initially, then reallocates and copies (some number of times/quantities) as the result grows during each function invocation. result: clear "" ;... copy result ... on repeated use: clears and copies a string with allocation equal to the longest result produced in any use. I can think of all sorts of interesting benchmarks for the behavior of CLEAR, COPY, and APPEND (the hidden allocations) but the surface-level trade-off would seem to be a variation on the classical time-for-space. If an abnormally large result occurred early in a long-running process, then option two would keep that amount of memory tied up and subsequently unused forever (i.e., until REBOL quits). That being the case, does result: make string! some-normally-large-enough-size ;... result sound like a middle-ground compromise to you?
> JN> - Replace simple constants/expressions with more obscure > JN> expressions > > Mainly for strings, so that they are not easyly readable by > the "intruder". >
Depending on the application, one may be as likely to want to hide some "magic numbers" as well. The technique works for both. Didn't you notice that I used index? head lOOO1 as a shrouded way to get a 1? ;-)
> JN> yet know how to program the required knowledge. I'll be > JN> fascinated to see any progress you might make! Good > luck! > > I'll need luck, I know! :-) But I think it can be done to some > extent... >
Agreed. I had been thinking about the "full blown" problem of taking an arbitrary REBOL source file and trying to shroud it. Unfortunately, the task of figuring out which words were my words versus system words (versus somebody-else's words?) began to look quite hairy given the possibility of DO and BIND appearing in the code. One of the cleverest shrouding tricks I've seen used "key words" randomly as replacements for local variables, etc. The analog in REBOL would be to turn something like ply: func [ {create a string from series and separator arguments} ser [series!] {series of values to be collected} sep [string! char!] {value to go between elements} /local result {accumulator for string} nextsep {what precedes next item?} ][ result: copy nextsep: "" foreach item ser [ repend result [nextsep item] nextsep: sep ] result ] into ply: func [print [series!] = [string! char!] /local probe word? ] [ probe: copy word?: "" foreach to print [ repend probe [ word? to ] word?: = ] probe ] which actually works... ;-) Highly effective shrouding IMHO, but requires even more semantic knowledge of REBOL to pull it off. -jn- ------------------------------------------------------------ Programming languages: compact, powerful, simple ... Pick any two! joel'dot'neely'at'fedex'dot'com