reverse engineering is usually about trying to understand a partially/mostly concealed system/interface, while for this case everything is already visible, but hard to understand.
By that definition, analyzing compiled native code would be "un-obfuscating".
IMO, deobfuscation is a subset of reverse engineering - which at a push I would define as "taking a program from the form it is distributed into a preferred form for modification/understanding".
Seriously. I didn't think the article was going to be just prettifying a 1 liner by hand. Looking back, it's actually cringe-y that he calls this reverse engineering. You know what real reverse engineering is? Figuring out the code from the output image only.
Hold on - would you say unpacking something packed by e.g. UPX by hand (silly example) wouldn't be reverse engineering? This is just unpacking a packed program, which definitely is reverse engineering.
I'd say it fits Wikipedia's definition of reverse engineering pretty well: "The process often involves disassembling something ... and analyzing its components and workings in detail."
Nice. But it does highlight a trend in modern programming languages such as Ruby etc. where these one line shorthand methods are used to such an extent these days that new programmers to the project have to spend an inordinate amount of time reverse engineering some of these shortcuts to make sense of program flow and understand the program in their heads.
Take the simple, quick initialiser:
foo ||= 1
Instead of the more verbose
if foo.nil?
foo = 1
end
Undoubtedly, the first line is a much cooler version, but like skinny jeans was once cool - getting in and out of them far outweighed the cool factor.
I can't agree, if you are a Ruby programmer you immediately know what's going on in the first line and it's definitely more readable - you see it at a glance instead of having to scan three lines.
Inline conditionals can be a blessing and a curse. In this case, it is absoluteley alright to use them (I find it also more elegant). But I have also seen things like:
cyberferret explicitly said it's a good idea to avoid shorthand methods because new programmers don't understand them, and you're making the argument that they're OK because experienced programmers will understand them. The essence of your argument is that if you've used the language enough to know what the or-equals statement means then you'll know what it means. I'm not convinced that's a good reason.
For that specific example though, it's so common in the colloquial Ruby language that all normal Ruby programmers should learn and use it. If you're just taking about readability, the time saved skimming during your career is worth the time spent learning the idiom once in your life.
Cyberferrit said new programmers to the project, not specifically new to the language or programming itself.
Working on emulation software I commonly run across snippets such as `res = !!iRegisterVal` which results in some C newbies scratching their heads as to why a useless double negation would be there. But for more seasoned developers its intent can pretty easily recognized...
It is a shorthand method of casting to a boolean value - C didn't have a true bool type until "recently" (but did have the concept of truthiness, where true is `is not 0`), so many projects and libraries use `#define TRUE 1`, and #define FALSE 0` or some similar variant.
So rather than write `foo ? TRUE : FALSE` or being more explicit `(foo != 0) ? 1 : 0`, you can just do `!!foo`.
No. It is not so simple as that. Some developers don't like mindfuck with cryptic lines all the time. But as with placement of curly braces, the coding convention battle rages on. Btw the old symmetric C-style is the only right way ;)
Unfortunately, it's not actually an initialiser. Type confusion is really common in Ruby programs, sadly.
The construct in parent assigns 1 if foo is "falsey", not strictly if it is nil. Even if foo is already initialised but contains a "falsey" value it will be assigned 1.
But in Ruby only false and nil are "falsey", so unless the variable was accidentally set to false (not impossible) the construct behaves as an initializer.
Also, the first version always assigns the value if the type is bool and set to false, which I have seen messed up a lot of times. It's not equivalent to a check for nil.
This doesn't highlight that trend. Writing a 128 byte demo is an art, and done for fun. This isn't conciseness out of laziness or coolness, it's a challenge in its own right. I think you vastly underappreciate how hard it is to put cool visuals in so little space. It doesn't really have much to do with ordinary programming.
It's like saying F1 racing is cool but it does highlight a trend of reckless driving in highways.
||= is an operator though. It's Ruby, and it hides away unnecessary details once you take 10 seconds to read about what it does, so I don't think that's a fair example for what you're pointing out. Now if we're talking about endless chaining of enumerators all on one line, then yes, that bullshit needs to stop.
This is the exact kind of mindset that lead to the creation of Java and Go: "The programmer is too dumb. Let's reduce and constrain what programmers can do." Go just takes it to the extreme until you can't read an entire function on a single screen but have to scroll through piles of code and error handling all mucked together.
> Go just takes it to the extreme until you can't read an entire function on a single screen but have to scroll through piles of code and error handling all mucked together.
That's the cynical way of looking at it (also sounds like you haven't read or written much go code). As someone who has written go code full time for 2 years, here's another perspective.
It's not about "the programmer is too dumb", it's about people of varying skill levels working on really, really large code bases. A junior, mid, and senior can all work on the same business problems. Conversely, if you have a senior ruby dev, they will write these terse, elegant, functional-chained methods that require much time to digest and conceptualize. This leads to wasted programmer time. All the elegance and terseness I have seen in the wild, it has never once saved anyone time, minus the few 10's of seconds it saved the programmer who wrote it who thought they were being "clever" because they wrote that if statement in one line instead of three. Code is maintained and read more than it is written. Go encourages writing code for the reader.
Also, "piles of error handling" is preferred. Go treats errors as values that you can program around. It took a while for me to shed the bad habits of languages prior (ruby, python, javascript, java and c#) but afterwards I fell in love. Handle your errors -- right there where they happen. Never again do I have to deal PokeMon try/catching.
34 comments
[ 2.0 ms ] story [ 83.3 ms ] threadIMO, deobfuscation is a subset of reverse engineering - which at a push I would define as "taking a program from the form it is distributed into a preferred form for modification/understanding".
I bet there are a myriad frameworks to do it aswell.
Deobsufucizer.js Reverse-sj.io
Take the simple, quick initialiser:
Instead of the more verbose Undoubtedly, the first line is a much cooler version, but like skinny jeans was once cool - getting in and out of them far outweighed the cool factor.cyberferret explicitly said it's a good idea to avoid shorthand methods because new programmers don't understand them, and you're making the argument that they're OK because experienced programmers will understand them. The essence of your argument is that if you've used the language enough to know what the or-equals statement means then you'll know what it means. I'm not convinced that's a good reason.
Working on emulation software I commonly run across snippets such as `res = !!iRegisterVal` which results in some C newbies scratching their heads as to why a useless double negation would be there. But for more seasoned developers its intent can pretty easily recognized...
So rather than write `foo ? TRUE : FALSE` or being more explicit `(foo != 0) ? 1 : 0`, you can just do `!!foo`.
For example,
This returns "true" or "false", instead of a (truthy) User object or a (falsy) nil.[0] https://gist.github.com/jfarmer/2647362
It's much cleaner, doesn't pollute the code with extra stuff not pertinent to the problem (if, end), and keeps it straight to the point.
It's not at all different to tons of other constructs, like:
or:The construct in parent assigns 1 if foo is "falsey", not strictly if it is nil. Even if foo is already initialised but contains a "falsey" value it will be assigned 1.
This is different from huge one-liners, which I think are almost always inappropriate.
It's like saying F1 racing is cool but it does highlight a trend of reckless driving in highways.
That's the cynical way of looking at it (also sounds like you haven't read or written much go code). As someone who has written go code full time for 2 years, here's another perspective.
It's not about "the programmer is too dumb", it's about people of varying skill levels working on really, really large code bases. A junior, mid, and senior can all work on the same business problems. Conversely, if you have a senior ruby dev, they will write these terse, elegant, functional-chained methods that require much time to digest and conceptualize. This leads to wasted programmer time. All the elegance and terseness I have seen in the wild, it has never once saved anyone time, minus the few 10's of seconds it saved the programmer who wrote it who thought they were being "clever" because they wrote that if statement in one line instead of three. Code is maintained and read more than it is written. Go encourages writing code for the reader.
Also, "piles of error handling" is preferred. Go treats errors as values that you can program around. It took a while for me to shed the bad habits of languages prior (ruby, python, javascript, java and c#) but afterwards I fell in love. Handle your errors -- right there where they happen. Never again do I have to deal PokeMon try/catching.
Q: Whats that math/graphing app you have screenshots of?