Pues no dispongo de la cadena original, las cadenas a decodificar ser铆an de 7 o 14 bytes.
No es para comprobar la integridad de las cadenas sino para decodificarla.
Tengo el c贸digo PERL que lo hace pero no se pasarlo a FWH/xHarbour, creo que es la funcion "
http://topic.csdn.net/u/20110316/02/eab0b8c6-9b21-4b7d-9bab-06a9ae556638.html
Perl code
#!/usr/bin/perl -w
#
# TCP Proxy Server for reverse engineering the Kinetic SBS-1e receiver
# Mark Street <marksmanuk@gmail.com>
#
use strict;
use Getopt::Std;
use IO::Socket;
use IO::Handle;
my $local_port 聽 聽= 10001;
my $target_ip 聽 聽= "141.22.13.108";
my $target_port 聽 聽= 10001;
my $MSG_LOGIN1 = "\x01\xE9\x5D\xC5\x53\xB1\xD7\xB7\x4E"; 聽 聽# Type 0x17
# Connect to SBS-1 as a TCP client:
#print "$0 Version 0.9.1 <marksmanuk\@gmail.com>\n";
#print "Connecting to SBS-1 on $target_ip:$target_port\n";
my $remote = IO::Socket::INET->new(
聽 聽 Proto 聽 聽=> "tcp",
聽 聽 PeerAddr => "$target_ip",
聽 聽 PeerPort => "$target_port" )
聽 聽 || die "Cannot connect to $target_ip:$target_port";
# Local decode mode
local_decode();
# ----------------------------------------------------------------------------
# Communicate with SBS-1 directly
# ----------------------------------------------------------------------------
sub local_decode
{
聽 聽 # Send Login1 string to SBS-1 and await reply.
聽 聽 # Reply will contain keys to be used to decode next reply.
聽 聽 # Magic keys: 聽 聽0x4857 = "HW"
聽 聽 # Magic keys: 聽 聽0x5958 = "YX"
聽 聽 # Magic keys: 聽 聽0x4431 = "D1"
聽 聽 # Magic keys: 聽 聽0x474A = "GJ"
聽 聽 #print "Sending Login 1 message...\n";
聽 聽 send_sbs(0x17, $MSG_LOGIN1, 0x4857, 0x5958);
聽 聽 my $rx = recv_sbs(0x27, 0x4431, 0x474A);
聽 聽 # Subsequent keys are returned in reply to login message:
聽 聽 # Tx Key = 5DE9 / 53C5
聽 聽 # Rx Key = 5D0D / 61FE
聽 聽 my @msg = split //,$rx->{msg};
聽 聽 my $tx_key1 = (ord ($msg[2]) << 8) + ord $msg[1]; 聽 聽
聽 聽 my $tx_key2 = (ord ($msg[4]) << 8) + ord $msg[3];
聽 聽
聽 聽 my $rx_key1 = (ord ($msg[10]) << 8) + ord $msg[9]; 聽 聽
聽 聽 my $rx_key2 = (ord ($msg[12]) << 8) + ord $msg[11];
聽 聽 # Send Login2 message and await reply. 聽Encoding will be:
聽 聽 # 02 - Key1, Key 2 - Key3, Key 4
聽 聽 #print "Sending Login 2 message...\n";
聽 聽 my $MSG_LOGIN2 = "\x02".substr($rx->{msg}, 9, 8);
聽 聽 send_sbs(0x18, $MSG_LOGIN2, $tx_key1, $tx_key2);
聽 聽 # Reply will contain inventory details.
聽 聽 $rx = recv_sbs(0x28, $rx_key1, $rx_key2);
聽 聽 my ($serial, $firmware, $build, $fpga1, $fpga2, $decoder1, $decoder2, $user1, $user2) =
聽 聽 聽 聽 unpack "xA8A16SCCCCCC", $rx->{msg};
聽 聽 print "\tSerial Number: $serial\n";
聽 聽 print "\tFirmware: 聽 聽 聽$firmware\n";
聽 聽 print "\tBuild: 聽 聽 聽 聽 $build\n";
聽 聽 printf "\tFPGA: 聽 聽 聽 聽 聽%d.%02d\n", $fpga1, $fpga2;
聽 聽 printf "\tDecoder: 聽 聽 聽 %d.%02d\n", $decoder1, $decoder2;
聽 聽 printf "\tUser F/W: 聽 聽 聽%d.%02d\n", $user1, $user2;
聽 聽 # We're logged in. 聽Wait for unsolicted events to come in.
聽 聽 print "Awaiting events...\n";
聽 聽 while(1)
聽 聽 {
聽 聽 聽 聽 #print "-"x78,"\n" if $args{v};
聽 聽 聽 聽 $rx = recv_sbs(undef, $rx_key1, $rx_key2);
聽 聽 # 聽 聽next unless $rx->{type} == 0x01;
聽 聽 # 聽 聽printf "Received Event: 0x%02X\n", $rx->{type};
聽 聽 聽 聽 Dump($rx->{msg});
聽 聽 }
聽 聽 exit;
}
# ----------------------------------------------------------------------------
# Local Receive Functions
# ----------------------------------------------------------------------------
my $rx_buffer = "";
sub recv_sbs
{
聽 聽 my $expected 聽 聽 = shift;
聽 聽 my $key1 聽 聽 聽 聽 = shift;
聽 聽 my $key2 聽 聽 聽 聽 = shift;
聽 聽 # SBS-1 can send bursts of messages that can arrive in a single
聽 聽 # concatenated packet from the socket. 聽We receive a fixed amount of data
聽 聽 # from the socket to a buffer then return complete messages to the caller.
聽 聽 my $buffer;
聽 聽 my $msg_type;
聽 聽 my $rx_msg;
聽 聽 while(1)
聽 聽 {
聽 聽 聽 聽 #printf "Waiting for Message Type 0x%02X...\n", $expected
聽 聽 聽 聽 # 聽 聽if defined $expected && $args{v};
聽 聽 聽 聽 recv($remote, $buffer, 1500, 0);
聽 聽 聽 聽 $rx_buffer .= $buffer;
聽 聽 聽 聽 die "Disconnected!" if length($buffer) == 0;
聽 聽 聽 聽 # Find end of message: 聽Remember 0x10 is escaped
聽 聽 聽 聽 next unless $rx_buffer =~ m/(?<!\x10)\x10\x03/g;
聽 聽 聽 聽 # This is hack to extract a complete un-escaped message including CRC.
聽 聽 聽 聽 my @val = split //,$rx_buffer;
聽 聽 聽 聽 my ($flag, $idx);
聽 聽 聽 聽 my $at_crc = 0;
聽 聽 聽 聽 $rx_msg = "";
聽 聽 聽 聽 for ($idx=0; $idx<length($rx_buffer); $idx++)
聽 聽 聽 聽 {
聽 聽 聽 聽 聽 聽 if ($val[$idx] eq "\x10" && $flag)
聽 聽 聽 聽 聽 聽 {
聽 聽 聽 聽 聽 聽 聽 聽 $flag = 0;
聽 聽 聽 聽 聽 聽 聽 聽 next;
聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 $at_crc++ if $at_crc; 聽 聽 聽 聽# 2 & 3
聽 聽 聽 聽 聽 聽 last if $at_crc == 4;
聽 聽 聽 聽 聽 聽 if ($val[$idx] eq "\x03" && $flag)
聽 聽 聽 聽 聽 聽 {
聽 聽 聽 聽 聽 聽 聽 聽 $at_crc = 1; 聽 聽
聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 if ($val[$idx] eq "\x10") {
聽 聽 聽 聽 聽 聽 聽 聽 $flag = 1;
聽 聽 聽 聽 聽 聽 } else {
聽 聽 聽 聽 聽 聽 聽 聽 $flag = 0;
聽 聽 聽 聽 聽 聽 }
聽 聽 聽 聽 聽 聽 $rx_msg .= $val[$idx];
聽 聽 聽 聽 }
聽 聽 聽 聽 # Chop message from buffer;
聽 聽 聽 聽 $rx_buffer = substr($rx_buffer, $idx, length($rx_buffer)-$idx);
聽 聽 聽 聽 $rx_buffer = "" if (length($rx_buffer) > 10000);
聽 聽 聽 聽 $msg_type = ord substr($rx_msg, 2, 1);
聽 聽 聽 聽 # Block until we receive specified message type:
聽 聽 聽 聽 last unless defined $expected;
聽 聽 聽 聽 last if defined $expected && $msg_type == $expected;
聽 聽 }
聽 聽 # Got it. 聽Strip the header and footer and separate into various parts:
聽 聽 my @msg = split //,$rx_msg;
聽 聽 my $rx_crc16 = (ord($msg[-2]) << 8) + ord($msg[-1]);
聽 聽 shift @msg; shift @msg; shift @msg;
聽 聽 pop @msg; pop @msg; pop @msg; pop @msg;
聽 聽 $rx_msg = join "",@msg;
聽 聽 # Descramble received message:
聽 聽 my $rx_clr = rx_decode($rx_msg, $key1, $key2);
聽 聽 # Verify received checksum:
聽 聽 my $crc16 = crc16(0x0000, 0x1021, $msg_type);
聽 聽 foreach my $byte (split //,$rx_clr)
聽 聽 {
聽 聽 聽 聽 $crc16 = crc16($crc16, 0x1021, ord $byte);
聽 聽 }
聽 聽 return { msg => $rx_clr, crc => $crc16, type => $msg_type };
}
sub rx_decode
{
聽 聽 my $rx_msg 聽 聽 = shift;
聽 聽 my $key1 聽 聽= shift;
聽 聽 my $key2 聽 聽= shift;
聽 聽 die "Undefined Message Bytes" 聽 聽 unless defined $rx_msg;
聽 聽 # Descramble payload bytes. 聽This is perfomed in a similar way to the
聽 聽 # encoder by calling the CRC routine initially with magic values
聽 聽 # then doing some bit shifts and logic.
聽
聽 聽 my $enc1 = 0; 聽 聽 聽 聽 聽 聽# Defaults to 0
聽 聽 my $rx_clr;
聽 聽 # Take each message byte in turn and descramble:
聽 聽 foreach my $byte (split //,$rx_msg)
聽 聽 {
聽 聽 聽 聽 $byte = ord $byte;
聽 聽 聽 聽 # Starting with the magic init values, use the returned
聽 聽 聽 聽 # CRC16 as the init values for the next round.
聽 聽 聽 聽 $key1 = crc16($key1, 0x1021, 0xFF);
聽 聽 聽 聽 $key2 = crc16($key2, 0x8005, 0xFF);
聽 聽 聽 聽 # Now some bit shifting weirdness:
聽 聽 聽 聽 my $enc2 = ($enc1 >> 3) | ($enc1 << 5);
聽 聽 聽 聽 # And some XORing for good measure:
聽 聽 聽 聽 my $enc3 = ($byte ^ $enc2) & 0xFF;
聽 聽 聽 聽 my $enc4 = ($enc3 ^ $key1) & 0xFF;
聽 聽 聽 聽 my $enc5 = ($enc4 ^ $key2) & 0xFF;
聽 聽 聽 聽 $enc1 聽 聽= ($enc2 ^ $enc5) & 0xFF;
聽 聽 聽 聽 $rx_clr .= chr $enc5;
聽 聽 }
聽 聽 return $rx_clr;
}
# ----------------------------------------------------------------------------
# Local Send Functions
# ----------------------------------------------------------------------------
sub send_sbs
{
聽 聽 my $msg_type 聽 聽 = shift;
聽 聽 my $msg 聽 聽 聽 聽 = shift;
聽 聽 my $key1 聽 聽 聽 聽= shift;
聽 聽 my $key2 聽 聽 聽 聽= shift;
聽 聽 # Scramble payload
聽 聽 #printf "Using key1=0x%04X and key2=0x%04X\n", $key1, $key2 if $args{v};
聽 聽 my $enc_login1 = tx_encode($msg_type, $msg, $key1, $key2);
聽 聽 # 16 bit message checksum works like this:
聽 聽 # CRC16 Poly 0x1021 Init 0x0000 聽 聽- Message Type + Msg Payload aginst
聽 聽 # the cleartext bytes.
聽 聽 my $crc16 = crc16(0x0000, 0x1021, $msg_type);
聽 聽 foreach my $byte (split //,$msg)
聽 聽 {
聽 聽 聽 聽 $crc16 = crc16($crc16, 0x1021, ord $byte);
聽 聽 }
聽 聽 #printf "CRC16 after msg payload = 0x%04X\n", $crc16 if $args{v};
聽 聽 # Add the header and footer bytes and
聽 聽 my $buffer = "\x10\x02".(chr $msg_type)."$enc_login1\x10\x03".
聽 聽 聽 聽 chr($crc16 >> 8).chr($crc16 & 0xFF);
聽 聽 print $remote $buffer;
}
sub tx_encode
{
聽 聽 my $msg_type = shift;
聽 聽 my $msg 聽 聽 聽= shift;
聽 聽 my $key1 聽 聽 = shift;
聽 聽 my $key2 聽 聽 = shift;
聽 聽
聽 聽 die "Undefined Message Type ID" unless defined $msg_type;
聽 聽 die "Undefined Message Bytes" 聽 聽 unless defined $msg;
聽 聽 my $len = length($msg);
聽 聽 # The message payload, but not the Message Type ID, are now scrambled
聽 聽 # by calling the usual CRC routine with various initialisation words and
聽 聽 # by performing a series of bit shifts.
聽 聽 my $enc1 = 0; 聽 聽 聽 聽 聽 聽# Defaults to 0
聽 聽 my $output;
聽 聽 # Take each message byte in turn and scramble:
聽 聽 foreach my $byte (split //,$msg)
聽 聽 {
聽 聽 聽 聽 $byte = ord $byte;
聽 聽 聽 聽 #printf "Scrambling 0x%02X\n", $byte if $args{v};
聽 聽 聽 聽 # Starting with the magic init values, use the returned
聽 聽 聽 聽 # CRC16 as the init values for the next round.
聽 聽 聽 聽 $key1 = crc16($key1, 0x1021, 0xFF);
聽 聽 聽 聽 $key2 = crc16($key2, 0x8005, 0xFF);
聽 聽 聽 聽 # Now some bit shifting weirdness:
聽 聽 聽 聽 my $enc2 = ($enc1 >> 3) | ($enc1 << 5);
聽 聽 聽 聽 # And some XORing for good measure:
聽 聽 聽 聽 $enc1 聽 聽= ($byte ^ $enc2) & 0xFF;
聽 聽 聽 聽 my $enc3 = ($enc1 ^ $key1) & 0xFF;
聽 聽 聽 聽 my $enc4 = ($enc3 ^ $key2) & 0xFF;
# 聽 聽 聽 聽printf "\tScrambled 0x%02X = 0x%02X\n", $byte, $enc4 & 0xFF if $args{v};
聽 聽 聽 聽 $output .= chr $enc4;
聽 聽 }
聽 聽 return $output;
}
# ----------------------------------------------------------------------------
# Helpers
# ----------------------------------------------------------------------------
sub crc16
{
聽 聽 my $init = shift;
聽 聽 my $poly = shift;
聽 聽 my $val 聽= shift;
聽 聽 die "Undefined CRC value"
聽 聽 聽 聽 unless defined $val && defined $poly && defined $init;
聽 聽 my $var;
聽 聽 for (my $i=0; $i<8; $i++)
聽 聽 {
聽 聽 聽 聽 $var = $val << 8;
聽 聽 聽 聽 $var ^= $init;
聽 聽 聽 聽 $init += $init;
聽 聽 聽 聽 $val <<= 1;
聽 聽 聽 聽 if ($var & 0x8000)
聽 聽 聽 聽 {
聽 聽 聽 聽 聽 聽 $init ^= $poly;
聽 聽 聽 聽 }
聽 聽 }
聽 聽 return $init & 0xFFFF;
}
sub Dump
{
聽 聽 my $buffer = shift;
聽 聽 my $header = shift;
聽 聽 die "Undefined buffer" unless defined $buffer;
聽 聽 die "References not supported" unless ref $buffer eq "";
聽 聽 my @vals = unpack("C*", $buffer);
聽 聽 print "$header\n" if defined $header;
聽 聽 my $rowChars = 18;
聽 聽 my $pos = 0;
聽 聽 while ($pos < @vals)
聽 聽 {
聽 聽 聽 聽 #printf "%04X: ", $pos;
聽 聽 聽 聽 for (my $i=0; $i<$rowChars; $i++)
聽 聽 聽 聽 {
聽 聽 聽 聽 聽 聽 (($pos+$i) < @vals) ?
聽 聽 聽 聽 聽 聽 聽 聽 printf "%02X,", $vals[$pos+$i] : print " 聽 ";
聽 聽 聽 聽 } 聽 聽
聽 聽 聽 聽 $pos += $rowChars;
聽 聽 聽 聽 print "\n";
聽 聽 }
}