显示标签为“Perl”的博文。显示所有博文
显示标签为“Perl”的博文。显示所有博文

2010/09/06

How to Crack Excel VBA Password

Let's make it faster! I did a Perl script to handle the string replacement for you!




#!/usr/bin/perl -W

use strict;
use warnings;

use IO::File;

print "Reset .XLA Password AS: ZZZZXXXX\n";

my $fname;
while ($fname = shift) {
my $fh = new IO::File;
my $fx = new IO::File;

# backup
#qx(copy $_ $_.orig) if [ -f $_ ];

# open file
if ($fh->open("< $fname")) {
$fh->binmode();

$fx->open("> $fname.new") || die qq(unable to create $fname.new! $@\n);
$fx->binmode();

my $l;
while ($l = <$fh>) {
$l =~ s/CMG="\w+"/CMG="C2C06EAE34B234B230B630B6"/;
$l =~ s/DPB="\w+"/DPB="848628F028AF45AF4550BBB0458ED7A55404135266B71BBB11B340F5CB0445BD26CDE2C6BA5A"/;
$l =~ s/GC="\w+"/GC="4644EA326E363137313731"/;

# write into new file.
print $fx $l;
}

$fh->close();
$fx->close();

# rename
qx(ren $fname $fname.orig);
qx(ren $fname.new $fname);

# print ok
print "$fname ... done!\n";
}
}

2010/03/15

My First Perl XS module

In recent days, I created my first Perl XS module -- Perl Win32::Oleaccxs.
Win32::Oleaccxs is a module which depended on Microsoft Active Accessibility UI API to go through all the GUI widgets in Microsoft Windows system. This module is just a simple wrapper to the client APIs. By using this module, you can navigate most of the Windows GUI widgets by using Perl.

This is very early version -- v0.01, It is undocumented yet. I will finish the document and upload it to CPAN some times later. :)

2010/02/08

sub GetTreeViewItemRect of Win32::GuiTest functions

Win32::GuiTest is a powerful tool for Windows GUI testing. I love it! This is a small function which allow GuiTest to send Mouse Events to the item inside TreeCtrl.




#!/usr/bin/perl
## Initially generated by Win32-GuiTest Recorder (v1.03)

## Pragmas/Directives
use strict;
use warnings;

use 5.010;

## Imports
use Win32::GuiTest qw/:ALL/;

$Win32::GuiTest::debug = 0; # Set to "1" to enable debug output.

use constant {
    TVM_EXPAND        => 0x1100 + 2,
    TVM_GETITEMRECT   => 0x1100 + 4,
    TVM_GETNEXTITEM   => 0x1100 + 10,
    TVM_SELECTITEM    => 0x1100 + 11,
    TVM_GETITEM       => 0x1100 + 12,
    TVM_ENSUREVISIBLE => 0x1100 + 20,
    TVGN_ROOT   => 0,
    TVGN_NEXT   => 1,
    TVGN_CHILD  => 4,
    TVGN_CARET  => 9,
    TVE_EXPAND  => 2,
};

=item
    Helper function to go through Items inside TreeCtrl.
    It is as same as the internal function of Win32::GuiTest
    But it allows to use REGEX as the item name
=cut
sub xTVPathWalk
{
    my $hwnd     = shift;
    my $tvitem   = shift;
    my $text_buf = shift;
    my $hItem    = shift;
    my $max_buf  = shift;
    my $delay    = shift;
    my @parts    = @_;
    SendMessage( $hwnd, TVM_ENSUREVISIBLE(), 0, $hItem );
    while( $hItem != 0 ){
        my $str_long = pack( "L L L L L L L L L L",
            0x41, #mask (TVIF_TEXT | TVIF_CHILDREN)
            $hItem, #hItem
            0, #state
            0, #stateMask
            $text_buf->{ 'ptr' }, #pszText
            100, #cchTextMax
            0, #iImage
            0, #iSelectedImage
            0, #cChildren
            0  #lParam
        );

        WriteToVirtualBuffer( $tvitem, $str_long );
        SendMessage( $hwnd, TVM_GETITEM(), 0, $tvitem->{ 'ptr' } );
        my $text = ReadFromVirtualBuffer( $text_buf, $max_buf );
        $text =~ s/\0.+$//;
        my $struct = ReadFromVirtualBuffer( $tvitem, 40 );
        my @fields = unpack( "L10", $struct );
        my $titlere = $parts[0];
        if( $text =~ /$titlere/i ){
            SendMessage( $hwnd, TVM_EXPAND(), TVE_EXPAND(), $hItem );
            #
            # Give the node some time to expand...
            #
            select(undef, undef, undef, $delay) if $delay;
            if( @parts == 1 ){
                return $hItem;
            }
            if( $fields[ 8 ] ){
                my $hChild = SendMessage( $hwnd,
                                       TVM_GETNEXTITEM(),
                                       TVGN_CHILD(),
                                       $hItem );
                shift( @parts );
                return xTVPathWalk( $hwnd,
                                   $tvitem,
                                   $text_buf,
                                   $hChild,
                                   $max_buf,
                                   $delay,
                                   @parts );
            }
        }else{
            $hItem = SendMessage( $hwnd,
                                  TVM_GETNEXTITEM(),
                                  TVGN_NEXT(),
                                  $hItem );
        }
    }
    return 0;
}    

=item GetTreeViewItemRect
 Return the RECT of Item related to Screen.
 Parameters are as same parameters as SelTreeViewItem
=cut
sub GetTreeViewItemRect
{
    my $hwnd = shift;
    my $path = shift;
    my $max_buf = shift;
    my $delay = shift;

    if( !$max_buf ){
        $max_buf = 124;
    }
    if( !$delay ){
        $delay = 0.50;
    }
    
    my @parts = split( /\|/, $path );
 
    my $tvitem;
    eval{
        $tvitem = AllocateVirtualBuffer( $hwnd, 50 );
    };
    if( $@ ){
        die "Allocation failed with message ---> $@";
    }
    
    my $text_buf = AllocateVirtualBuffer( $hwnd, $max_buf );

    my $item_rect = AllocateVirtualBuffer( $hwnd, 16 );
 
    my $hItem = SendMessage( $hwnd, TVM_GETNEXTITEM(), TVGN_ROOT(), 0 );
    $hItem = xTVPathWalk( $hwnd,
                          $tvitem,
                          $text_buf,
                          $hItem,
                          $max_buf,
                          $delay,
                          @parts );
    SendMessage( $hwnd, TVM_SELECTITEM(), TVGN_CARET(), $hItem );

    my @rect = (0, 0, 0, 0);
    if ($hItem) {            # TVM_GETITEMRECT = 0x1104
        say "Got the item: $hItem";
        
        SendMessage( $hwnd, TVM_ENSUREVISIBLE(), 0, $hItem );

        WriteToVirtualBuffer( $item_rect, pack('L L L L', $hItem, 0, 0, 0));
        if (SendMessage ( $hwnd, TVM_GETITEMRECT(), 1, $item_rect->{ 'ptr' } ) ) {
            @rect = unpack('L4', ReadFromVirtualBuffer( $item_rect, 16 ) );
        }
    }
    FreeVirtualBuffer( $item_rect );
    FreeVirtualBuffer( $tvitem );
    FreeVirtualBuffer( $text_buf );

    @rect[0,1] = ClientToScreen( $hwnd, $rect[0], $rect[1] );
    @rect[2,3] = ClientToScreen( $hwnd, $rect[2], $rect[3] );

    return @rect;
}

=item SendMouseToTreeViewItem($hwndTreectrl, $path, $mouseevents)
    $hwndTrectrl - the HWND of TreeCtrl
    $path - full path of TreeCtrl item
    $mouseevents - mouse events, please refer to Win32::GuiTest::SendMouse
=cut
sub SendMouseToTreeViewItem {
    
    my $hwnd = shift;
    my $path = shift;

    my @rect = GetTreeViewItemRect($hwnd, $path);
    if ($rect[2] - $rect[0] != 0) {
        MouseMoveAbsPix($rect[0] + 1, $rect[1] + 1);
        SendMouse(shift);
    }
}



Here is a exameple. It will find the first `Windows Explorer' window,

my @windows = FindWindowLike(undef,undef,"ExploreWClass");
if (scalar @windows) {
SetForegroundWindow($windows[0]);
SetActiveWindow($windows[0]);
my ($treectl) = FindWindowLike($windows[0], undef, 'SysTreeView32');
if ($treectrl) {
SendMouseToTreeViewItem($treectl, 'desktop|my computer|c:|perl', '{leftclick}{leftclick}')
}
}

2010/01/20

Perl regular expression tip: return all the matched things


Perl的正则表达式异常强悍,介绍一个不太引人注意但是又非常有用的功能:那就是返回所有匹配到的内容:“使用 //g 匹配”。 这时 $var =~ /regex/g 将会返回一个array,里面有所有匹配到的内容。如果在正则表达式中定义了group,就返回所有的groups;如果没有定义group,就返回所有匹配到的内容。
In list context, //g returns a list of matched groupings, or if there are no groupings, a list of matches to the whole regexp. So if we wanted just the words, we could use

        @words = ($x =~ /(\w+)/g);  # matches,
                                    # $word[0] = 'cat'
                                    # $word[1] = 'dog'
                                    # $word[2] = 'house'
需要注意,需要在一个 list context。说简单一点,就像上面的例子做就好。把匹配的结果赋值给一个array。

2009/12/21

Perl Threads

不得不说,perl 在M$ windows 下面实现的模拟fork真的是不堪一用,有很多限制,比如说: 不能fork 超过64次。也不能怪Perl,windows 对进程的处理就跟 Unix 大不相同!不过好在对于Thread的支持 Windows倒是没什么大问题。

给一个Windows下Perl多线程编程的小例子,自己留着慢慢用:) 里面用到:线程同步,变量共享。(需要Perl 5.8或者以上版本来支持 threads模块; say 这个好像是 Perl 5.10的feature, 其实就就print自动帮你加一个回车换行!)

use strict;
use warnings;

use feature qw(switch say);

use threads;
use threads::shared;
use Thread::Semaphore;

my $n = 9;

# shared variant across threads
my $arg :shared;

sub thread_proc
{
    my $sem = shift;

    for (1..$n) {
        # TODO: prepare works.
        sleep(1); # dummy 
        
        # wait until main thread wait me up!
        $sem->down;

        # TODO: Do my business~~~
        say "thread: $arg"; # dummy task
        sleep(1);   # dummy
    }

    say "thread_proc is over";
}

my $sem = new Thread::Semaphore();
my $thr = threads->create('thread_proc', $sem);
$sem->down; # Lock the semaphore

# Main thread
for(1..9)
{           
    # TODO: prepare works
    $arg = "$_ String " . ($_ * 1273);
    say "main: $arg";

    # Wait up the thread
    $sem->up;

    # TODO: Do some other works.
    sleep(3); # dummy task;
}

# wait for the thread to die
$thr->join();

print "end \n";

2009/07/14

Hex string to ASCII string in Perl

If you want to convert a string "ABCDEFG" to Hex mode like "07,41,42,43,44,45,46,47" -- a length prefix with all the others in HEX mode. How to do it in Perl?

You can do
$to = join(",", map { unpack('H2', $_) } chr(length($from)), split(/(?=.)/, $from));

or
$to = join(",", map { unpack('H2', $_) } split(/(?=.)/, pack('W/a', $from)));


How to do the reverse??? A question for you :P

2008/12/11

Mapping remote TCP port to local via HTTPS Proxy

上次说的Perl代码供大家参考

功能:把远端的应用服务端口通过HTTPS代理服务器映射成本地端口。这对于那些不支持HTTPS代理的TCP应用还有点儿小用处! :D


#!/usr/bin/env perl
#
# Use remote HTTPS PROXY to tunnel the remote service to local!
# Author: Yi Zhao
#   Blog: linuxyz.blogspot.com
#
# Based on original "ssltunnel.pl" by Alex Hornby <alex@hornby.org.uk>
# $Id: ssltunnel.pl,v 1.17 2003/06/10 14:54:16 alex Exp $
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#

package httpsproxy;

use strict;
my $VERSION=1.0;

use IO::File;
use IO::Select;
use IO::Socket;
use Net::SSL;
use Getopt::Long;
use MIME::Base64;

my %options = (
    proxyport=>443,
    reproxyport=>8080,
    localaddr=>"127.0.0.1",
    localport=>8080,
);

sub usage
{
    print STDERR <<EOF;
usage: perl httpsproxy.pl [options] [remote-host:port]
Tunnels a TCP/IP connection through an http proxy using SSL.

WARNING: Only use this if you have the proxy administrator\'s permission
WARNING: The authors of this package offer no warranty

options:
    --help                        This help
    --proxyhost 1.2.3.4           Mandatory proxy host port (default 443)
    --proxyport 443               Optional proxy host port (default 443)
    --proxyuser <username>        Optional proxy user name
    --proxypasswd pass            Optional proxy pass word
    --useragent agent             Optional user agent name
    --reproxyhost 1.2.3.4         Optional intermediate http proxy host
    --reproxyport 123             Optional intermediate http proxy host port (default 8080)
    --reproxyuser <username>      Optional intermediate http proxy user name
    --reproxypasswd pass          Optional intermediate http proxy pass word
    --localaddr 1.2.3.4           Optional local addr to listen on (default 127.0.0.1)
    --localport 123               Optional local port to listen on (default 8080)

e.g. To run a local http proxy to the remote HTTPS proxy

./httpsproxy.pl --proxyhost 10.1.1.80 \
  --proxyport 443 --localport 80  www.abc.com:80

EOF
    exit(1);
}

# Parse command line arguments
sub parseArgs
{
    GetOptions(\%options, qw/dumpfile=s
                   proxyhost=s proxyport=i proxyuser=s proxypasswd=s useragent=s
                   reproxyhost=s reproxyport=i reproxyuser=s reproxypasswd=s reuseragent=s
                   localaddr=s localport=i
                   debug! help!
                   log-file=s pidfile=s/);

    if ( $options{help} ) {
        usage();
    }

    for (@ARGV) {
        if (m/^([^:]*):(.*)$/) {
            $options{desthost} = $1;
            $options{destport} = int($2) || getservbyname($2, 'tcp') || die "unknown port";
            print "Mapping $options{desthost}:$options{destport} as $options{localaddr}:$options{localport}\n";
        }
    }
    
    if ( !defined($options{proxyhost}) ) {
        print STDERR "error: You must give a proxyhost\n";
        usage();
    }
}

# This is really inefficient, but we only use it for reading the proxy response
# so that does not really matter.
sub xgetline($)
{
    my $proxy = shift;
    my $val="";
    my $buf;
    do {
        $proxy->read($buf, 1);
        $val .= $buf;
    } until ($buf eq "\n");

    $val;
}

sub httpProxy
{
    my ( $proxy, $desthost, $destport, $proxyuser, $proxypasswd ) = @_;
    # Force flushing of socket buffers

    # The actual connect
    $proxy->print("CONNECT " .  $desthost . ":" .
                      $destport . " HTTP/1.0\r\n");
    if ( $options{debug} ) {
        print STDERR "CONNECT " .  $desthost . ":" .
                      $destport . " HTTP/1.0\n";
    }

    # Basic auth if needed
    if ( $proxyuser ) {
        my $auth = encode_base64(
            $proxyuser . ":" . $proxypasswd);
        $proxy->print("Proxy-authorization: Basic $auth\r\n");
        if ( $options{debug} ) {
            print STDERR "Proxy-authorization: Basic $auth"
        }
    }

    # User agent name if needed
    if ( $options{useragent} ) {
        $proxy->print("User-Agent: " . $options{useragent} . "\r\n");
        if ( $options{debug} ) {
            print STDERR "User-Agent: " . $options{useragent} . "\n";
        }
    }

    # end of headers
    $proxy->print("\r\n");

    my $status;

    # Wait for HTTP status code, bail out if you don't get back a 2xx code.
    #$_ = $proxy->getline();
    #$_ = $proxy->getchunk();
    $_ = xgetline($proxy);
    next if /^[\r]*$/;
    ($status) = (split())[1];
    die("Received a bad status code \"$status\" from proxy server\n$_")
        if ( int($status/100) != 2 );

    while($_ = xgetline($proxy)) {
        chomp;   # Strip <LF>
        last if /^[\r]*$/;                # Empty line or a single <CR> left

        if ( $options{debug} ) {
            print STDERR "Got extra data [$_]\n";
        }
    }

    return $status;
}

sub connectProxy
{
    if ( $options{reproxyhost} ) {
        # proxy support
        $ENV{HTTPS_PROXY} = qq(http://$options{reproxyhost}:$options{reproxyport});

        # proxy_basic_auth
        $ENV{HTTPS_PROXY_USERNAME} = $options{reproxyuser} if $options{reproxyuser};
        $ENV{HTTPS_PROXY_PASSWORD} = $options{reproxypass} if $options{reproxypass};
    }

    # debugging (SSL diagnostics)
    $ENV{HTTPS_DEBUG} = $options{debug} ? 1 : 0;
  
    my $proxy = new Net::SSL (
        PeerAddr => $options{proxyhost},
        PeerPort => $options{proxyport},
        Proto => 'tcp',
    );

    die "Error connecting to proxy host $options{proxyhost} " .
        "port $options{proxyport}: $!\n" unless $proxy;

    # Force flushing of socket buffers
    $proxy->autoflush(1);

    # only if the remote host are speficied
    httpProxy($proxy, $options{desthost}, $options{destport},
        $options{proxyuser}, $options{proxypasswd} )
    if ( $options{desthost} );

    return $proxy;
}

sub connectLocal
{
    my $listen = new IO::Socket::INET (
        Listen=> 5,
        LocalAddr => $options{localaddr},
        LocalPort => $options{localport},
        Proto => 'tcp',
        Reuse => 1,
    );

    die "can't listen on " . $options{localaddr} . ":"
        . $options{localport} unless $listen;

    print STDERR "Accepting network clients on " .
        $options{localaddr} . ":" .$options{localport} . "\n";

    my %client2proxy;
    my %proxy2client;

    my $s = IO::Select->new();
    $s->add($listen);

    my $dumpfh;
    if ( $options{dumpfile} ) {
        $dumpfh = new IO::File($options{dumpfile}, "w")
            or die "could not open dump file $_";
        $dumpfh->autoflush(1);
    }

    while ( 1 ) {
        my @res = IO::Select::select($s, undef, undef, 3600);
        if ( @res == 0 ) {
            print STDERR "got select error\n";
            last;
        }
        my ($read, $write, $error) = @res;

        # Check for disconnect
        for my $fh ( @$error ) {
            print STDERR "socket $fh is in error\n";
            $s->remove($fh);
            exit();
        }

        # Process handles ready to read;
        for my $fh ( @$read  ) {

            if ( $fh == $listen ) {
                my $client = $listen->accept();
                $client->autoflush(1);
                $s->add($client);
                my $proxy = connectProxy();
                $s->add($proxy);
                print STDERR "New connection from " . $client->peerhost() . "\n";
                $client2proxy{$client} = $proxy;
                $proxy2client{$proxy} = $client;
            } else {
                my $destfh;
                my $isclient = 0;
                if ( exists( $client2proxy{$fh} ) ) {
                    $destfh = $client2proxy{$fh};
                    $isclient = 1;
                } elsif ( exists( $proxy2client{$fh} ) ) {
                    $destfh = $proxy2client{$fh};
                }

                my $num = sysread($fh, $_, 4096);
                if ( $num) {
                    syswrite($destfh, $_, $num);
                    # Optional dump of traffic
                    if ( $dumpfh ) {
                        if ($isclient) {
                            $dumpfh->print("client[$_]\n");
                        } else {
                            $dumpfh->print("proxy[$_]\n");
                        }
                    }
                } else {
                    $s->remove($fh);
                    $s->remove($destfh);
                    if ( $isclient ) {
                        print STDERR "client disconnected\n";
                        delete($client2proxy{$fh});
                        delete($proxy2client{$destfh});
                    } else {
                        print STDERR "proxy disconnected\n";
                        delete($client2proxy{$destfh});
                        delete($proxy2client{$fh});
                    }
                    close($fh);
                    close($destfh);

                    if(%proxy2client == 0 ) {
                        print STDERR "last client disconnected\n";
                    }
                }
            }
        }
    }
}

parseArgs();
connectLocal();

0;

__END__

2007/05/06

Perl 5.8 PerlIO feature

With the new PerlIO feature and Unicode support in Perl 5.8, it is possible to do the internal encoding change with only a few lines of code.

Please check the code below. It will be able to read the GBK input from STDIN and convert it to UTF-8 to STDOUT. :)


#!/usr/bin/perl -W

use encoding "gbk", STDOUT => "utf8";
while(<>){print};


Power and Simple. :D

BlockChain 相关电子书

@copyright of Sam Chadwick   - https://thehub.thomsonreuters.com/groups/bitcoin/blog/2017/09/10/blockchain-paper Blockchain Papers A c...