Obfuscated Python hack

  • Thread starter Steven D'Aprano
  • Start date
S

Steven D'Aprano

Kids, don't try this at home!

In Python 2.7, run this:

exec((lambda *fs: reduce(lambda f, g: lambda x: f(g(x)), fs))(*([lambda
s: s[1::2]+s[-2::-2]]*54))('motcye;cye._n8fo_drs(d4+)vle=5 ua.8)
(isedamr.ticspt spt rpi'))


Then run these:

10 - 6 == 10 - 5
4 + 1 == 7 - 1
2*2 == 10//2




A shiny penny for the first person to explain what's going on.[1]




[1] Offer expires April 1st 2014.
 
T

Tim Chase

Kids, don't try this at home!

In Python 2.7, run this:

exec((lambda *fs: reduce(lambda f, g: lambda x: f(g(x)),
fs))(*([lambda s:
s[1::2]+s[-2::-2]]*54))('motcye;cye._n8fo_drs(d4+)vle=5 ua.8)
(isedamr.ticspt spt rpi'))


Then run these:

10 - 6 == 10 - 5
4 + 1 == 7 - 1
2*2 == 10//2

A shiny penny for the first person to explain what's going on.[1]

Stripping off the exec() call makes it pretty transparent that you're
attempting (successfully on some platforms) to set the value of "4"
to "5". But a cute hack.

-tkc
 
C

Chris Angelico

Stripping off the exec() call makes it pretty transparent that you're
attempting (successfully on some platforms) to set the value of "4"
to "5". But a cute hack.

And not on Windows inside IDLE, where attempting to use 4 results in a
===== RESTART ===== crash. But a nice try.

ChrisA
 
S

Steven D'Aprano

And not on Windows inside IDLE, where attempting to use 4 results in a
===== RESTART ===== crash.

Sounds like a bug in IDLE.

What happens if you try it in Windows without IDLE, just using the
standard interactive interpreter?
 
I

Ian Kelly

Sounds like a bug in IDLE.

What happens if you try it in Windows without IDLE, just using the
standard interactive interpreter?

Actually, probably a 32/64-bit issue. The code as supplied caused a
segfault on my 64-bit Linux install. I had to change the offset to 16
to see it work.
 
C

Chris Angelico

Sounds like a bug in IDLE.

What happens if you try it in Windows without IDLE, just using the
standard interactive interpreter?

It works fine without IDLE.

Python 2.7.4 (default, Apr 6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win
32
exec((lambda *fs: reduce(lambda f, g: lambda x: f(g(x)), fs))(*([lambda s: s
[1::2]+s[-2::-2]]*54))('motcye;cye._n8fo_drs(d4+)vle=5 ua.8)(isedamr.ticspt spt
rpi'))True


In IDLE:
exec((lambda *fs: reduce(lambda f, g: lambda x: f(g(x)), fs))(*([lambda s: s[1::2]+s[-2::-2]]*54))('motcye;cye._n8fo_drs(d4+)vle=5 ua.8)(isedamr.ticspt spt rpi'))
10 - 6 == 10 - 5
================================ RESTART ================================

There's a bit of a pause before the RESTART line comes through, and
repeating the equality check after that comes back with a
straight-forward False.

Running IDLE from a terminal gives this:

C:\Documents and Settings\M>\python27\python -m idlelib.idle

----------------------------------------
Unhandled server exception!
Thread: SockThread
Client Address: ('127.0.0.1', 4414)
Request: <socket._socketobject object at 0x0127ADC0>
Traceback (most recent call last):
File "C:\python27\lib\SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\python27\lib\SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "C:\python27\lib\SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\python27\lib\idlelib\rpc.py", line 503, in __init__
SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr)
File "C:\python27\lib\SocketServer.py", line 649, in __init__
self.handle()
File "C:\python27\lib\idlelib\run.py", line 268, in handle
rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
File "C:\python27\lib\idlelib\rpc.py", line 280, in getresponse
response = self._getresponse(myseq, wait)
File "C:\python27\lib\idlelib\rpc.py", line 300, in _getresponse
response = self.pollresponse(myseq, wait)
File "C:\python27\lib\idlelib\rpc.py", line 424, in pollresponse
message = self.pollmessage(wait)
File "C:\python27\lib\idlelib\rpc.py", line 376, in pollmessage
packet = self.pollpacket(wait)
File "C:\python27\lib\idlelib\rpc.py", line 357, in pollpacket
self._stage0()
File "C:\python27\lib\idlelib\rpc.py", line 364, in _stage0
self.bufneed = struct.unpack("<i", s)[0]
error: unpack requires a string argument of length 4

*** Unrecoverable, server exiting!
----------------------------------------


So... I'd say this isn't so much a bug in IDLE as a limitation:
"depends on the universe being sane". I mean, honestly. You just
changed the meaning of four! :)

ChrisA
 
C

Chris Angelico

Actually, probably a 32/64-bit issue. The code as supplied caused a
segfault on my 64-bit Linux install. I had to change the offset to 16
to see it work.

My test was a 32-bit Python 2.7.4, for what it's worth.

ChrisA
 
G

Gregory Ewing

Tim said:
Stripping off the exec() call makes it pretty transparent that you're
attempting (successfully on some platforms) to set the value of "4"
to "5".

But you have to do that in *another* Python session, because
the first one is broken in interesing ways, e.g.
(lambda *fs: reduce(lambda f, g: lambda x: f(g(x)), fs))(*([lambda s:
s[1::2]+s[-2::-2]]*54))('motcye;cye._n8fo_drs(d4+)vle=5 ua.8)(isedamr.ticspt
spt rpi')
File "<stdin>", line 1
SyntaxError: name 'z' is local and global

I never knew that error message existed! Is it even possible
to get it from a non-broken Python?

To answer my own question, apparently yes:
.... global x
....
File "<stdin>", line 1
SyntaxError: name 'x' is local and global

You learn something every day...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top