📄 ndr.pm
字号:
$self->pidl_hdr("#include \"packet-dcerpc-$_\.h\""); } $self->pidl_hdr("");}sub ProcessInterface($$){ my ($self, $x) = @_; push(@{$self->{conformance}->{strip_prefixes}}, $x->{NAME}); my $define = "__PACKET_DCERPC_" . uc($_->{NAME}) . "_H"; $self->pidl_hdr("#ifndef $define"); $self->pidl_hdr("#define $define"); $self->pidl_hdr(""); $self->pidl_def("static gint proto_dcerpc_$x->{NAME} = -1;"); $self->register_ett("ett_dcerpc_$x->{NAME}"); $self->register_hf_field("hf_$x->{NAME}_opnum", "Operation", "$x->{NAME}.opnum", "FT_UINT16", "BASE_DEC", "NULL", 0, ""); if (defined($x->{UUID})) { my $if_uuid = $x->{UUID}; $self->pidl_def("/* Version information */\n\n"); $self->pidl_def("static e_uuid_t uuid_dcerpc_$x->{NAME} = {"); $self->pidl_def("\t0x" . substr($if_uuid, 1, 8) . ", 0x" . substr($if_uuid, 10, 4) . ", 0x" . substr($if_uuid, 15, 4) . ","); $self->pidl_def("\t{ 0x" . substr($if_uuid, 20, 2) . ", 0x" . substr($if_uuid, 22, 2) . ", 0x" . substr($if_uuid, 25, 2) . ", 0x" . substr($if_uuid, 27, 2) . ", 0x" . substr($if_uuid, 29, 2) . ", 0x" . substr($if_uuid, 31, 2) . ", 0x" . substr($if_uuid, 33, 2) . ", 0x" . substr($if_uuid, 35, 2) . " }"); $self->pidl_def("};"); my $maj = $x->{VERSION}; $maj =~ s/\.(.*)$//g; $self->pidl_def("static guint16 ver_dcerpc_$x->{NAME} = $maj;"); $self->pidl_def(""); } $return_types{$x->{NAME}} = {}; $self->Interface($x); $self->pidl_code("\n".DumpFunctionTable($x)); foreach (keys %{$return_types{$x->{NAME}}}) { my ($type, $desc) = @{$return_types{$x->{NAME}}->{$_}}; my $dt = $self->find_type($type); $dt or die("Unable to find information about return type `$type'"); $self->register_hf_field("hf_$x->{NAME}_$_", $desc, "$x->{NAME}.$_", $dt->{FT_TYPE}, "BASE_HEX", $dt->{VALSSTRING}, 0, ""); $self->{hf_used}->{"hf_$x->{NAME}_$_"} = 1; } $self->RegisterInterface($x); $self->RegisterInterfaceHandoff($x); $self->pidl_hdr("#endif /* $define */");}sub find_type($$){ my ($self, $n) = @_; return $self->{conformance}->{types}->{$n};}sub register_type($$$$$$$$){ my ($self, $type,$call,$ft,$base,$mask,$vals,$length) = @_; return if (defined($self->{conformance}->{types}->{$type})); $self->{conformance}->{types}->{$type} = { NAME => $type, DISSECTOR_NAME => $call, FT_TYPE => $ft, BASE_TYPE => $base, MASK => $mask, VALSSTRING => $vals, ALIGNMENT => $length };}# Loads the default typessub Initialize($$){ my ($self, $cnf_file) = @_; $self->{conformance} = { imports => {}, header_fields=> {} }; ReadConformance($cnf_file, $self->{conformance}) or print STDERR "warning: No conformance file `$cnf_file'\n"; foreach my $bytes (qw(1 2 4 8)) { my $bits = $bytes * 8; $self->register_type("uint$bits", "offset = PIDL_dissect_uint$bits(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);", "FT_UINT$bits", "BASE_DEC", 0, "NULL", $bytes); $self->register_type("int$bits", "offset = PIDL_dissect_uint$bits(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);", "FT_INT$bits", "BASE_DEC", 0, "NULL", $bytes); } $self->register_type("udlong", "offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);", "FT_UINT64", "BASE_DEC", 0, "NULL", 4); $self->register_type("bool8", "offset = PIDL_dissect_uint8(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_INT8", "BASE_DEC", 0, "NULL", 1); $self->register_type("char", "offset = PIDL_dissect_uint8(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_INT8", "BASE_DEC", 0, "NULL", 1); $self->register_type("long", "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_INT32", "BASE_DEC", 0, "NULL", 4); $self->register_type("dlong", "offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);","FT_INT64", "BASE_DEC", 0, "NULL", 8); $self->register_type("GUID", "offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, drep, \@HF\@, NULL);","FT_GUID", "BASE_NONE", 0, "NULL", 4); $self->register_type("policy_handle", "offset = PIDL_dissect_policy_hnd(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_BYTES", "BASE_NONE", 0, "NULL", 4); $self->register_type("NTTIME", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);","FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4); $self->register_type("NTTIME_hyper", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);","FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4); $self->register_type("time_t", "offset = dissect_ndr_time_t(tvb, offset, pinfo,tree, drep, \@HF\@, NULL);","FT_ABSOLUTE_TIME", "BASE_DEC", 0, "NULL", 4); $self->register_type("NTTIME_1sec", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep, \@HF\@);", "FT_ABSOLUTE_TIME", "BASE_NONE", 0, "NULL", 4); $self->register_type("SID", " dcerpc_info *di = (dcerpc_info *)pinfo->private_data; di->hf_index = \@HF\@; offset = dissect_ndr_nt_SID_with_options(tvb, offset, pinfo, tree, drep, param); ","FT_STRING", "BASE_DEC", 0, "NULL", 4); $self->register_type("WERROR", "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_DEC", 0, "VALS(WERR_errors)", 4); $self->register_type("NTSTATUS", "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_DEC", 0, "VALS(NT_errors)", 4);}###################################################################### Generate Wireshark parser and header codesub Parse($$$$$){ my($self,$ndr,$idl_file,$h_filename,$cnf_file) = @_; $self->Initialize($cnf_file); return (undef, undef) if defined($self->{conformance}->{noemit_dissector}); my $notice = "/* DO NOT EDIT This filter was automatically generated from $idl_file and $cnf_file. Pidl is a perl based IDL compiler for DCE/RPC idl files. It is maintained by the Samba team, not the Wireshark team. Instructions on how to download and install Pidl can be found at http://wiki.wireshark.org/Pidl*/"; $self->pidl_hdr($notice); $self->{res}->{headers} = "\n"; $self->{res}->{headers} .= "#ifdef HAVE_CONFIG_H\n"; $self->{res}->{headers} .= "#include \"config.h\"\n"; $self->{res}->{headers} .= "#endif\n\n"; $self->{res}->{headers} .= "#ifdef _MSC_VER\n"; $self->{res}->{headers} .= "#pragma warning(disable:4005)\n"; $self->{res}->{headers} .= "#pragma warning(disable:4013)\n"; $self->{res}->{headers} .= "#pragma warning(disable:4018)\n"; $self->{res}->{headers} .= "#pragma warning(disable:4101)\n"; $self->{res}->{headers} .= "#endif\n\n"; $self->{res}->{headers} .= "#include <glib.h>\n"; $self->{res}->{headers} .= "#include <string.h>\n"; $self->{res}->{headers} .= "#include <epan/packet.h>\n\n"; $self->{res}->{headers} .= "#include \"packet-dcerpc.h\"\n"; $self->{res}->{headers} .= "#include \"packet-dcerpc-nt.h\"\n"; $self->{res}->{headers} .= "#include \"packet-windows-common.h\"\n"; my $h_basename = basename($h_filename); $self->{res}->{headers} .= "#include \"$h_basename\"\n"; $self->pidl_code(""); # Wireshark protocol registration foreach (@$ndr) { $self->ProcessInterface($_) if ($_->{TYPE} eq "INTERFACE"); $self->ProcessImport(@{$_->{PATHS}}) if ($_->{TYPE} eq "IMPORT"); $self->ProcessInclude(@{$_->{PATHS}}) if ($_->{TYPE} eq "INCLUDE"); } $self->{res}->{ett} = DumpEttDeclaration($self->{ett}); $self->{res}->{hf} = $self->DumpHfDeclaration(); my $parser = $notice; $parser.= $self->{res}->{headers}; $parser.=$self->{res}->{ett}; $parser.=$self->{res}->{hf}; $parser.=$self->{res}->{def}; if (exists ($self->{conformance}->{override})) { $parser.=$self->{conformance}->{override}; } $parser.=$self->{res}->{code}; my $header = "/* autogenerated by pidl */\n\n"; $header.=$self->{res}->{hdr}; $self->CheckUsed($self->{conformance}); return ($parser,$header);}################################################################################ ETT###############################################################################sub register_ett($$){ my ($self, $name) = @_; push (@{$self->{ett}}, $name); }sub DumpEttList{ my ($ett) = @_; my $res = "\tstatic gint *ett[] = {\n"; foreach (@$ett) { $res .= "\t\t&$_,\n"; } return "$res\t};\n";}sub DumpEttDeclaration{ my ($ett) = @_; my $res = "\n/* Ett declarations */\n"; foreach (@$ett) { $res .= "static gint $_ = -1;\n"; } return "$res\n";}################################################################################ HF###############################################################################sub register_hf_field($$$$$$$$$) { my ($self,$index,$name,$filter_name,$ft_type,$base_type,$valsstring,$mask,$blurb) = @_; if (defined ($self->{conformance}->{hf_renames}->{$index})) { $self->{conformance}->{hf_renames}->{$index}->{USED} = 1; return $self->{conformance}->{hf_renames}->{$index}->{NEWNAME}; } $self->{conformance}->{header_fields}->{$index} = { INDEX => $index, NAME => $name, FILTER => $filter_name, FT_TYPE => $ft_type, BASE_TYPE => $base_type, VALSSTRING => $valsstring, MASK => $mask, BLURB => $blurb }; if ((not defined($blurb) or $blurb eq "") and defined($self->{conformance}->{fielddescription}->{$index})) { $self->{conformance}->{header_fields}->{$index}->{BLURB} = $self->{conformance}->{fielddescription}->{$index}->{DESCRIPTION}; $self->{conformance}->{fielddescription}->{$index}->{USED} = 1; } return $index;}sub DumpHfDeclaration($){ my ($self) = @_; my $res = ""; $res = "\n/* Header field declarations */\n"; foreach (keys %{$self->{conformance}->{header_fields}}) { $res .= "static gint $_ = -1;\n"; } return "$res\n";}sub DumpHfList($){ my ($self) = @_; my $res = "\tstatic hf_register_info hf[] = {\n"; foreach (values %{$self->{conformance}->{header_fields}}) { $res .= "\t{ &$_->{INDEX}, { ".make_str($_->{NAME}).", ".make_str($_->{FILTER}).", $_->{FT_TYPE}, $_->{BASE_TYPE}, $_->{VALSSTRING}, $_->{MASK}, ".make_str($_->{BLURB}).", HFILL }},"; } return $res."\t};\n";}################################################################################ Function table###############################################################################sub DumpFunctionTable($){ my $if = shift; my $res = "static dcerpc_sub_dissector $if->{NAME}\_dissectors[] = {\n"; foreach (@{$if->{FUNCTIONS}}) { my $fn_name = $_->{NAME}; $fn_name =~ s/^$if->{NAME}_//; $res.= "\t{ $_->{OPNUM}, \"$fn_name\",\n"; $res.= "\t $if->{NAME}_dissect_${fn_name}_request, $if->{NAME}_dissect_${fn_name}_response},\n"; } $res .= "\t{ 0, NULL, NULL, NULL }\n"; return "$res};\n";}sub CheckUsed($$){ my ($self, $conformance) = @_; foreach (values %{$conformance->{header_fields}}) { if (not defined($self->{hf_used}->{$_->{INDEX}})) { warning($_->{POS}, "hf field `$_->{INDEX}' not used"); } } foreach (values %{$conformance->{hf_renames}}) { if (not $_->{USED}) { warning($_->{POS}, "hf field `$_->{OLDNAME}' not used"); } } foreach (values %{$conformance->{dissectorparams}}) { if (not $_->{USED}) { warning($_->{POS}, "dissector param never used"); } } foreach (values %{$conformance->{imports}}) { if (not $_->{USED}) { warning($_->{POS}, "import never used"); } } foreach (values %{$conformance->{types}}) { if (not $_->{USED} and defined($_->{POS})) { warning($_->{POS}, "type never used"); } } foreach (values %{$conformance->{fielddescription}}) { if (not $_->{USED}) { warning($_->{POS}, "description never used"); } } foreach (values %{$conformance->{tfs}}) { if (not $_->{USED}) { warning($_->{POS}, "True/False description never used"); } }}1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -