Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #72407 > unrolled thread

Obfuscated Python hack

Started bySteven D'Aprano <steve+comp.lang.python@pearwood.info>
First post2014-06-02 12:11 +0000
Last post2014-06-03 01:56 +1000
Articles 8 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Obfuscated Python hack Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-06-02 12:11 +0000
    Re: Obfuscated Python hack Tim Chase <python.list@tim.thechases.com> - 2014-06-02 07:27 -0500
      Re: Obfuscated Python hack Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-06-03 17:40 +1200
    Re: Obfuscated Python hack Chris Angelico <rosuav@gmail.com> - 2014-06-02 23:23 +1000
      Re: Obfuscated Python hack Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-06-02 15:38 +0000
        Re: Obfuscated Python hack Ian Kelly <ian.g.kelly@gmail.com> - 2014-06-02 09:47 -0600
        Re: Obfuscated Python hack Chris Angelico <rosuav@gmail.com> - 2014-06-03 01:55 +1000
        Re: Obfuscated Python hack Chris Angelico <rosuav@gmail.com> - 2014-06-03 01:56 +1000

#72407 — Obfuscated Python hack

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-06-02 12:11 +0000
SubjectObfuscated Python hack
Message-ID<538c69d5$0$29978$c3e8da3$5496439d@news.astraweb.com>
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.

-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [next] | [standalone]


#72409

FromTim Chase <python.list@tim.thechases.com>
Date2014-06-02 07:27 -0500
Message-ID<mailman.10557.1401712081.18130.python-list@python.org>
In reply to#72407
On 2014-06-02 12:11, Steven D'Aprano wrote:
> 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



[toc] | [prev] | [next] | [standalone]


#72473

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2014-06-03 17:40 +1200
Message-ID<bv55emFcik2U1@mid.individual.net>
In reply to#72409
Tim Chase wrote:
> 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 'fs' is local and global

 >>> lambda z: 42
   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:

 >>> def f(x):
...  global x
...
   File "<stdin>", line 1
SyntaxError: name 'x' is local and global

You learn something every day...

-- 
Greg

[toc] | [prev] | [next] | [standalone]


#72410

FromChris Angelico <rosuav@gmail.com>
Date2014-06-02 23:23 +1000
Message-ID<mailman.10558.1401715441.18130.python-list@python.org>
In reply to#72407
On Mon, Jun 2, 2014 at 10:27 PM, Tim Chase
<python.list@tim.thechases.com> wrote:
> 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

[toc] | [prev] | [next] | [standalone]


#72417

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-06-02 15:38 +0000
Message-ID<538c9a78$0$29978$c3e8da3$5496439d@news.astraweb.com>
In reply to#72410
On Mon, 02 Jun 2014 23:23:53 +1000, Chris Angelico wrote:

> On Mon, Jun 2, 2014 at 10:27 PM, Tim Chase
> <python.list@tim.thechases.com> wrote:
>> 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. 

Sounds like a bug in IDLE.

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



-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#72418

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-06-02 09:47 -0600
Message-ID<mailman.10562.1401724099.18130.python-list@python.org>
In reply to#72417
On Mon, Jun 2, 2014 at 9:38 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Mon, 02 Jun 2014 23:23:53 +1000, Chris Angelico wrote:
>
>> On Mon, Jun 2, 2014 at 10:27 PM, Tim Chase
>> <python.list@tim.thechases.com> wrote:
>>> 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.
>
> 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.

[toc] | [prev] | [next] | [standalone]


#72419

FromChris Angelico <rosuav@gmail.com>
Date2014-06-03 01:55 +1000
Message-ID<mailman.10563.1401724555.18130.python-list@python.org>
In reply to#72417
On Tue, Jun 3, 2014 at 1:38 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Mon, 02 Jun 2014 23:23:53 +1000, Chris Angelico wrote:
>
>> On Mon, Jun 2, 2014 at 10:27 PM, Tim Chase
>> <python.list@tim.thechases.com> wrote:
>>> 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.
>
> 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'))
>>> 10 - 6 == 10 - 5
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

[toc] | [prev] | [next] | [standalone]


#72420

FromChris Angelico <rosuav@gmail.com>
Date2014-06-03 01:56 +1000
Message-ID<mailman.10564.1401724608.18130.python-list@python.org>
In reply to#72417
On Tue, Jun 3, 2014 at 1:47 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Mon, Jun 2, 2014 at 9:38 AM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> On Mon, 02 Jun 2014 23:23:53 +1000, Chris Angelico wrote:
>>
>>> On Mon, Jun 2, 2014 at 10:27 PM, Tim Chase
>>> <python.list@tim.thechases.com> wrote:
>>>> 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.
>>
>> 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.

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

ChrisA

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web