I try to give my idea about reversing, not an answer, because I myself hope that I can find it, moreover I am quite sure that any expert here may say that what I think is crappy but I beg a generosity from the community.
The "reverse engineering" a program is rather to verify whether the program has some properties or not, than to reverse from binary code to source code (we can imagine that there are some properties that we can observe easily in the source code but not in the binary code), then the "obfuscation" is to prevent the program from such an algorithmic verification.
In the perfect (i.e. theoretical) world, some very general results assert several things. First, the Rice's theorem (as previously mentioned by @perror) and a more constructive result of Landi. W assert that a general verificator does not exist, that means we cannot write a verificator V so that when we gives V an arbitrary program P and a non-trivial property p (a trivial property is one that exists in all programs, e.g. the magic byte MZ exists in all PE files is a trivial property), V can answer P has p or not. So that means the perfect obfuscation exists ?, the answer is trivially No, that is because we never require a such strong verificator (that gives deterministic answer for all programs), we need only a verificator for some useful classes of programs.
Second, Barak et al (as previously mentioned also by @perror) asserts a somehow contradict result: there are some classes of programs that cannot be obfuscated, namely no matter what they are obfuscated, that is easy to write a verificator to answer these programs have a given property p (or not). There is actually no contradiction here because the Rice's theorem applies in the context of "all programs" and the result of Barak et al applies for the context of "several programs", indeed we have:
Third, the result of Wee. H says that we can always hide (i.e. obfuscate) some properties given a class of special programs named point functions. Again, that does not mean the obfuscation is possible in general because this result applies in the context of "several programs".
Fourth, the result of Garg. S et al says that we can obfuscate any program so that any property computed from the obfuscated one is "trivial". So that means the perfect obfuscator exists?, and if it exists then it contradict to the result of Barak et al?, obviously No, because the two results have used actually two different definitions of triviality, in the first one a property is trivial if it exists in all programs having the same semantics (so this definition is weaker than in the second one).
In the real (i.e. practial) world, I have so little experience that I cannot give any useful idea. But I doubt that the game obfuscator vs de-obfuscator will evolve in some very clever ways and we still have many gaps to work in (as an obfuscator or as a de-obfuscator).