Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re: Fun with duff's device and AUTOLOAD

by ambrus (Abbot)
on Feb 24, 2004 at 21:30 UTC ( #331531=note: print w/replies, xml ) Need Help??

in reply to Fun with duff's device and AUTOLOAD

Now I've got 3 different reports that the script does not work. Someone said it even did not work on Solaris. I can not reproduce the bad behaivior so it will be difficult to track down the bug, especially because it seems to run on most machines.

(Update @ 2006 may 24: it seems I could finally reproduce the error on a machine. I'll try to investigate it if I have time.)

I'll however explain where I've got the numbers and why they translate to a sensible message. I've got the basic idea after the thread $#="%c"; possible bug.

The trick is that $#="%c"; print 3.14; is entirely unlike printf "%c", 3.14;. Just try $#="%d"; print 10;! It does not print 10, rather, it prints 0 (i386) or some stupid number depending on the endianndess of your cpu. This is because when formatting numbers a la $#, perl calls sprintf (or some equivalent) with $# as a format and the number as a floating point number to the stack. I don't know where this is in the source, probably hidden somewhere in sv.c, but I'm quite sure it works like this.

Update: I'd be glad if someone could point me to the guilty code.

The floating-point numbers are given so that when represented as a double, their upper and lower 4 bytes are both the same small integer, the ascii code of a character in the message. I had to put the same integer twice, so that the code would work in both intel-endian and sparc-endian cpu's. Really, if you consider only one kind of cpus, half as much numbers would have been enough. Let me show this.

Type perl -we 'print join ", ", unpack "d*", pack "l*", unpack "c*", "perl"; print $/;'. This prints (on intel) 2.14321574942828e-312, 2.29175545480573e-312. Now using this numbers you can write perl -we '$#="%c%c"; print 2.14321574942828e-312, 2.29175545480573e-312; print $/;', which prints perl. I created the obfu in a very similar way.

The problem is that all this will fail if your perl was compiled with long double support, as the floating point format is quite different. There may be other problems why the script did not run for some people, which I currently don't know. Please check that your perl is not compiled with long doubles. Just run use Config; print qq[@Config{"nvtype","nvsize"}\n]; if it prints double 8, that is good. If it prints long double 12, the obfu will not work. There may also be issues about 64-bitness, I can not check that. Note that I have not tried the obfu from Windows, but in theory it should work.

Replies are listed 'Best First'.
Re: Re: Fun with duff's device and AUTOLOAD
by John M. Dlugosz (Monsignor) on Feb 25, 2004 at 20:59 UTC
    I get "double 8" on ActiveState under win2k, yet the obfu doesn't work.

    It does seem to have some issue with %c not working the same as printf, though. Printing 65 gives a nul character output, not 'A'. Printing 3.14 gives the bytes FD 91 BA B8 94 9F. Your print 2.14321574942828e-312, 2.29175545480573e-312; example prints "perl" as expected!

      Maybe I wasn't clear in the explanation.

      $#="%c";print 65; should not print an A. It pushes 65.0 (a double) and "%x" on the C stack, and calls sprintf. Then sprintf sees "%c", so tries to pop an int from the stack. 65.0 is represented as the bytes (00 00 00 00 00 40 50 40)hex, but an int is just 4 bytes so it pops (00 00 00 00)hex which is 0 as an int so it prints a nul char. (On sparc, however, it will get (40 50 40 00)hex, which is 67437568, so it will either print a null character or a multibyte character sequence corresponding to unicode chr 67437568, depending on the version of Perl.)

      Dlugosz, I guess your cpu is an x86, correct me if it isn't.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://331531]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2017-11-25 11:57 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (355 votes). Check out past polls.