#Criando diretorios open HEX, "<", "Ragexe.pb.1.exe" or die $!; mkdir 'tables'; mkdir 'tables/bro'; mkdir 'src'; mkdir 'src/Network'; mkdir 'src/Network/Receive'; mkdir 'src/Network/Send'; binmode HEX; while () { # Generates a Hex Dump from target EXE my $tempDump = unpack("H*",$_); # Hex Dump is way too large, so we cut it down to where the packets are, thus decreasing process time: # Beginning of packets if ($tempDump =~ /F08D45EC8BF1508D4DFC518D55DC33DB/i) { $flagWrite = 1 } if ($flagWrite) { $HexDump .= $tempDump; } # Ending of packets # Note: flagWrite must be set to undef AFTER the writing process above, or else it won't write the last packet's block if ($tempDump =~ /0C6A0C683A0A/i) { $flagWrite = undef; } # This extracts bRO's encrypting keys (K, M, A) into an array if ($tempDump =~ m/25FF7F00005DC2040083F801751BC74104(..)(..)(..)(..)C74108(..)(..)(..)(..)C7410C(..)(..)(..)(..)33C05DC20400895104/i) { push(@keys, (uc($4.$3.$2.$1), uc($8.$7.$6.$5), uc($12.$11.$10.$9))); push(@keys01, (map hex, $keys[0])); push(@keys02, (map hex, $keys[1])); push(@keys03, (map hex, $keys[2])); } } close HEX; # Generates recvpackets.txt # This was firstly designed to bRO, so it is likely that only post-renewall EXE's would work with it # First we grab the general packets in the WHILE, then we analyze the kind of packet in the IF's $datestring = localtime(); open RECV, ">recvpackets.txt"; print RECV "# Generated by FullMetal extracting tool $datestring\n"; open Len, "<", "Len.txt" or die $!; my $tempMatch = "$HexDump"; while ($tempMatch =~ m/(C745FC|68)(..)(..)0000(8B|89|C7|B8)/ig) { my $PackID = uc($3.$2); my $line = ; print RECV $PackID, " ", $line; foreach my $Length (@line) { } close(arq); } print RECV "0073 11 11 1 0074 3 3 0 0075 -1 11 1 0076 9 9 1 0077 5 5 1 0078 55 55 1 007A 58 58 1 007B 60 60 1 007C 44 44 1 007F 6 6 1"; close RECV; # Stores new packets into array to be used by bro.pm generator open RECV, "<", "recvpackets.txt" or die $!; $error = 0; $cont = 0; while (my $line = ) { if (substr($line,0,1) !~ /\s|\#/) { $cont++; if ($cont == 1) { # actor_action if ($line =~ /7 7 0/) { # push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 3) { # character_move if ($line =~ /5 5 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 2) { # skill_use if ($line =~ /10 10 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 4) { # sync if ($line =~ /6 6 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 5) { # actor_look_at if ($line =~ /5 5 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 6) { # item_take if ($line =~ /6 6 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 7) { # item_drop if ($line =~ /6 6 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 8) { # storage_item_add if ($line =~ /8 8 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 9) { # storage_item_remove if ($line =~ /8 8 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 10) { # skill_use_location if ($line =~ /10 10 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 12) { # actor_info_request if ($line =~ /6 6 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 13) { # actor_name_request if ($line =~ /6 6 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 23) { # item_list_res if ($line =~ /-1 12 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 24) { # map_login if ($line =~ /19 19 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 25) { # party_join_request_by_name if ($line =~ /26 26 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 28) { # homunculus_command if ($line =~ /5 5 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif ($cont == 29) { # storage_password if ($line =~ /36 36 0/) { push(@newPackets,substr($line,0,4)); } else { $error = 1; } } elsif (($cont > 29) && ($cont < 114)) { if ($line =~ /2 2 0/) { push(@recvPacketslist,substr($line,0,4)); } else { $error = 1; } } elsif (($cont > 113) && ($cont < 198)) { if ($line =~ /2 2 0/) { push(@sendPacketslist,substr($line,0,4)); } else { $error = 1; } } } last if (($error == 1) || ($cont > 196)); } close RECV; $old_name=recvpackets.txt; $new_name="tables\recvpackets.txt"; rename $old_name, $new_name; ## IMPRIME O SEND\bRO.PM if ($error == 1) { print "Ocorreu um erro na linha ", $cont, ". Verifique o recvpackets manualmente."; } else { open (SEND, '>src\Network\Send\bro.pm'); print SEND "############################################################################# # OpenKore - Network subsystem # # This module contains functions for sending messages to the server. # # # # This software is open source, licensed under the GNU General Public # # License, version 2. # # Basically, this means that you're allowed to modify and distribute # # this software. However, if you distribute modified versions, you MUST # # also distribute the source code. # # See http://www.gnu.org/licenses/gpl.html for the full license. # ############################################################################# # bRO (Brazil) package Network::Send::bRO; use strict; use base 'Network::Send::ServerType0'; sub new { my (\$class) = \@_; my \$self = \$class->SUPER::new(\@_); my %packets = ( '$newPackets[0]' => ['actor_action', 'a4 C', [qw(targetID type)]], '$newPackets[1]' => ['skill_use', 'v2 a4', [qw(lv skillID targetID)]], '$newPackets[2]' => ['character_move','a3', [qw(coords)]], '$newPackets[3]' => ['sync', 'V', [qw(time)]], '$newPackets[4]' => ['actor_look_at', 'v C', [qw(head body)]], '$newPackets[5]' => ['item_take', 'a4', [qw(ID)]], '$newPackets[6]' => ['item_drop', 'v2', [qw(index amount)]], '$newPackets[7]' => ['storage_item_add', 'v V', [qw(index amount)]], '$newPackets[8]' => ['storage_item_remove', 'v V', [qw(index amount)]], '$newPackets[9]' => ['skill_use_location', 'v4', [qw(lv skillID x y)]], '$newPackets[10]' => ['actor_info_request', 'a4', [qw(ID)]], '$newPackets[11]' => ['actor_name_request', 'a4', [qw(ID)]], '$newPackets[12]' => ['item_list_res', 'v V2 a*', [qw(len type action itemInfo)]], '$newPackets[13]' => ['map_login', 'a4 a4 a4 V C', [qw(accountID charID sessionID tick sex)]], '$newPackets[14]' => ['party_join_request_by_name', 'Z24', [qw(partyName)]], #f '$newPackets[15]' => ['homunculus_command', 'v C', [qw(commandType, commandID)]], #f '$newPackets[16]' => ['storage_password'], ); \$self->{packet_list}{\$_} = \$packets{\$_} for keys %packets; my %handlers = qw( master_login 02B0 buy_bulk_vender 0801 party_setting 07D7 ); while (my (\$k, \$v) = each %packets) { \$handlers{\$v->[0]} = \$k} \$self->{packet_lut}{\$_} = \$handlers{\$_} for keys %handlers; \$self->cryptKeys(@keys01, @keys03, @keys02); return \$self; } 1;"; close SEND; ## IMPRIME O RECEIVE\bRO.PM open (RECEIVE, '>src/Network/receive/bro.pm'); print RECEIVE "############################################################################# # OpenKore - Network subsystem # # This module contains functions for sending messages to the server. # # # # This software is open source, licensed under the GNU General Public # # License, version 2. # # Basically, this means that you're allowed to modify and distribute # # this software. However, if you distribute modified versions, you MUST # # also distribute the source code. # # See http://www.gnu.org/licenses/gpl.html for the full license. # ############################################################################# # bRO (Brazil) package Network::Receive::bRO; use strict; use Log qw(warning); use base 'Network::Receive::ServerType0'; # Sync_Ex algorithm developed by Fr3DBr sub new { my (\$class) = \@_; my \$self = \$class->SUPER::new(\@_); my %packets = ( '0097' => ['private_message', 'v Z24 V Z*', [qw(len privMsgUser flag privMsg)]], # -1 )"; print RECEIVE "; # Sync Ex Reply Array \$self->{sync_ex_reply} = { "; ####################### generate sync_receive_ex tables for ($var = 0;$var < scalar(@recvPacketslist);$var++) { print RECEIVE " '$recvPacketslist[$var]', '$sendPacketslist[$var]'," }; ####################### end of sync_receive_ex tables print RECEIVE " }; foreach my \$key (keys %{\$self->{sync_ex_reply}}) { \$packets{\$key} = ['sync_request_ex']; } foreach my \$switch (keys %packets) { \$self->{packet_list}{\$switch} = \$packets{\$switch}; } return \$self;" } print ( RECEIVE" } sub items_nonstackable { my (\$self, \$args) = \@_; my \$items = \$self->{nested}->{items_nonstackable}; if(\$args->{switch} eq '00A4' || \$args->{switch} eq '00A6' || \$args->{switch} eq '0122') { return \$items->{type4}; } elsif (\$args->{switch} eq '0295' || \$args->{switch} eq '0296' || \$args->{switch} eq '0297') { return \$items->{type4}; } elsif (\$args->{switch} eq '02D0' || \$args->{switch} eq '02D1' || \$args->{switch} eq '02D2') { return \$items->{type4}; } else { warning(\"items_nonstackable: unsupported packet (\$args->{switch})!\\n\"); } } *parse_quest_update_mission_hunt = *Network::Receive::ServerType0::parse_quest_update_mission_hunt_v2; *reconstruct_quest_update_mission_hunt = *Network::Receive::ServerType0::reconstruct_quest_update_mission_hunt_v2; 1; "); close RECEIVE; use File::Copy; move("recvpackets.txt", "tables/bro/recvpackets.txt") or die "falha na copia: $!";