📄 ndr.pm
字号:
VALSSTRING => "NULL", FT_TYPE => "FT_NONE", BASE_TYPE => "BASE_HEX" }; } if (ContainsString($e)) { $type = { MASK => 0, VALSSTRING => "NULL", FT_TYPE => "FT_STRING", BASE_TYPE => "BASE_DEC" }; } my $hf = $self->register_hf_field("hf_$ifname\_$pn\_$e->{NAME}", field2name($e->{NAME}), "$ifname.$pn.$e->{NAME}", $type->{FT_TYPE}, $type->{BASE_TYPE}, $type->{VALSSTRING}, $type->{MASK}, ""); $self->{hf_used}->{$hf} = 1; my $eltname = StripPrefixes($pn, $self->{conformance}->{strip_prefixes}) . ".$e->{NAME}"; if (defined($self->{conformance}->{noemit}->{$eltname})) { return $call_code; } my $add = ""; foreach (@{$e->{LEVELS}}) { next if ($_->{TYPE} eq "SWITCH"); $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_);"); $self->pidl_fn_start("$dissectorname$add"); $self->pidl_code("static int"); $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)"); $self->pidl_code("{"); $self->indent; $self->ElementLevel($e,$_,$hf,$dissectorname.$add,$pn,$ifname); $self->pidl_code(""); $self->pidl_code("return offset;"); $self->deindent; $self->pidl_code("}\n"); $self->pidl_fn_end("$dissectorname$add"); $add.="_"; last if ($_->{TYPE} eq "ARRAY" and $_->{IS_ZERO_TERMINATED}); } return $call_code;}sub Function($$$){ my ($self, $fn,$ifname) = @_; my %dissectornames; foreach (@{$fn->{ELEMENTS}}) { $dissectornames{$_->{NAME}} = $self->Element($_, $fn->{NAME}, $ifname) if not defined($dissectornames{$_->{NAME}}); } my $fn_name = $_->{NAME}; $fn_name =~ s/^${ifname}_//; $self->PrintIdl(DumpFunction($fn->{ORIGINAL})); $self->pidl_fn_start("$ifname\_dissect\_$fn_name\_response"); $self->pidl_code("static int"); $self->pidl_code("$ifname\_dissect\_${fn_name}_response(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)"); $self->pidl_code("{"); $self->indent; if ( not defined($fn->{RETURN_TYPE})) { } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS" or $fn->{RETURN_TYPE} eq "WERROR") { $self->pidl_code("guint32 status;\n"); } elsif (my $type = getType($fn->{RETURN_TYPE})) { if ($type->{DATA}->{TYPE} eq "ENUM") { $self->pidl_code("g".Parse::Pidl::Typelist::enum_type_fn($type->{DATA}) . " status;\n"); } elsif ($type->{DATA}->{TYPE} eq "SCALAR") { $self->pidl_code("g$fn->{RETURN_TYPE} status;\n"); } else { error($fn, "return type `$fn->{RETURN_TYPE}' not yet supported"); } } else { error($fn, "unknown return type `$fn->{RETURN_TYPE}'"); } $self->pidl_code("pinfo->dcerpc_procedure_name=\"${fn_name}\";"); foreach (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$_->{DIRECTION}})) { $self->pidl_code("$dissectornames{$_->{NAME}}"); $self->pidl_code("offset = dissect_deferred_pointers(pinfo, tvb, offset, drep);"); $self->pidl_code(""); } } if (not defined($fn->{RETURN_TYPE})) { } elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") { $self->pidl_code("offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep, hf\_$ifname\_status, &status);\n"); $self->pidl_code("if (status != 0 && check_col(pinfo->cinfo, COL_INFO))"); $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str(status, NT_errors, \"Unknown NT status 0x%08x\"));\n"); $return_types{$ifname}->{"status"} = ["NTSTATUS", "NT Error"]; } elsif ($fn->{RETURN_TYPE} eq "WERROR") { $self->pidl_code("offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf\_$ifname\_werror, &status);\n"); $self->pidl_code("if (status != 0 && check_col(pinfo->cinfo, COL_INFO))"); $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str(status, WERR_errors, \"Unknown DOS error 0x%08x\"));\n"); $return_types{$ifname}->{"werror"} = ["WERROR", "Windows Error"]; } elsif (my $type = getType($fn->{RETURN_TYPE})) { if ($type->{DATA}->{TYPE} eq "ENUM") { my $return_type = "g".Parse::Pidl::Typelist::enum_type_fn($type->{DATA}); my $return_dissect = "dissect_ndr_" .Parse::Pidl::Typelist::enum_type_fn($type->{DATA}); $self->pidl_code("offset = $return_dissect(tvb, offset, pinfo, tree, drep, hf\_$ifname\_$fn->{RETURN_TYPE}_status, &status);"); $self->pidl_code("if (status != 0 && check_col(pinfo->cinfo, COL_INFO))"); $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Status: %s\", val_to_str(status, $ifname\_$fn->{RETURN_TYPE}\_vals, \"Unknown " . $fn->{RETURN_TYPE} . " error 0x%08x\"));\n"); $return_types{$ifname}->{$fn->{RETURN_TYPE}."_status"} = [$fn->{RETURN_TYPE}, $fn->{RETURN_TYPE}]; } elsif ($type->{DATA}->{TYPE} eq "SCALAR") { $self->pidl_code("offset = dissect_ndr_$fn->{RETURN_TYPE}(tvb, offset, pinfo, tree, drep, hf\_$ifname\_$fn->{RETURN_TYPE}_status, &status);"); $self->pidl_code("if (status != 0 && check_col(pinfo->cinfo, COL_INFO))"); $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Status: %d\", status);\n"); $return_types{$ifname}->{$fn->{RETURN_TYPE}."_status"} = [$fn->{RETURN_TYPE}, $fn->{RETURN_TYPE}]; } } $self->pidl_code("return offset;"); $self->deindent; $self->pidl_code("}\n"); $self->pidl_fn_end("$ifname\_dissect\_$fn_name\_response"); $self->pidl_fn_start("$ifname\_dissect\_$fn_name\_request"); $self->pidl_code("static int"); $self->pidl_code("$ifname\_dissect\_${fn_name}_request(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)"); $self->pidl_code("{"); $self->indent; $self->pidl_code("pinfo->dcerpc_procedure_name=\"${fn_name}\";"); foreach (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$_->{DIRECTION}})) { $self->pidl_code("$dissectornames{$_->{NAME}}"); $self->pidl_code("offset = dissect_deferred_pointers(pinfo, tvb, offset, drep);"); } } $self->pidl_code("return offset;"); $self->deindent; $self->pidl_code("}\n"); $self->pidl_fn_end("$ifname\_dissect\_$fn_name\_request");}sub Struct($$$$){ my ($self,$e,$name,$ifname) = @_; my $dissectorname = "$ifname\_dissect\_struct\_".StripPrefixes($name, $self->{conformance}->{strip_prefixes}); return if (defined($self->{conformance}->{noemit}->{StripPrefixes($name, $self->{conformance}->{strip_prefixes})})); $self->register_ett("ett_$ifname\_$name"); my $res = ""; ($res.="\t".$self->Element($_, $name, $ifname)."\n\n") foreach (@{$e->{ELEMENTS}}); $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);"); $self->pidl_fn_start($dissectorname); $self->pidl_code("int"); $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)"); $self->pidl_code("{"); $self->indent; $self->pidl_code("proto_item *item = NULL;"); $self->pidl_code("proto_tree *tree = NULL;"); $self->pidl_code("int old_offset;"); $self->pidl_code(""); if ($e->{ALIGN} > 1) { $self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;"); } $self->pidl_code(""); $self->pidl_code("old_offset = offset;"); $self->pidl_code(""); $self->pidl_code("if (parent_tree) {"); $self->indent; $self->pidl_code("item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, TRUE);"); $self->pidl_code("tree = proto_item_add_subtree(item, ett_$ifname\_$name);"); $self->deindent; $self->pidl_code("}"); $self->pidl_code("\n$res"); $self->pidl_code("proto_item_set_len(item, offset-old_offset);\n"); $self->pidl_code("return offset;"); $self->deindent; $self->pidl_code("}\n"); $self->pidl_fn_end($dissectorname); $self->register_type($name, "offset = $dissectorname(tvb,offset,pinfo,tree,drep,\@HF\@,\@PARAM\@);", "FT_NONE", "BASE_NONE", 0, "NULL", 0);}sub Union($$$$){ my ($self,$e,$name,$ifname) = @_; my $dissectorname = "$ifname\_dissect_".StripPrefixes($name, $self->{conformance}->{strip_prefixes}); return if (defined($self->{conformance}->{noemit}->{StripPrefixes($name, $self->{conformance}->{strip_prefixes})})); $self->register_ett("ett_$ifname\_$name"); my $res = ""; foreach (@{$e->{ELEMENTS}}) { $res.="\n\t\t$_->{CASE}:\n"; if ($_->{TYPE} ne "EMPTY") { $res.="\t\t\t".$self->Element($_, $name, $ifname)."\n"; } $res.="\t\tbreak;\n"; } my $switch_type; my $switch_dissect; my $switch_dt = getType($e->{SWITCH_TYPE}); if ($switch_dt->{DATA}->{TYPE} eq "ENUM") { $switch_type = "g".Parse::Pidl::Typelist::enum_type_fn($switch_dt->{DATA}); $switch_dissect = "dissect_ndr_" .Parse::Pidl::Typelist::enum_type_fn($switch_dt->{DATA}); } elsif ($switch_dt->{DATA}->{TYPE} eq "SCALAR") { $switch_type = "g$e->{SWITCH_TYPE}"; $switch_dissect = "dissect_ndr_$e->{SWITCH_TYPE}"; } $self->pidl_fn_start($dissectorname); $self->pidl_code("static int"); $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)"); $self->pidl_code("{"); $self->indent; $self->pidl_code("proto_item *item = NULL;"); $self->pidl_code("proto_tree *tree = NULL;"); $self->pidl_code("int old_offset;"); $self->pidl_code("$switch_type level;"); $self->pidl_code(""); $self->pidl_code("old_offset = offset;"); $self->pidl_code("if (parent_tree) {"); $self->indent; $self->pidl_code("item = proto_tree_add_text(parent_tree, tvb, offset, -1, \"$name\");"); $self->pidl_code("tree = proto_item_add_subtree(item, ett_$ifname\_$name);"); $self->deindent; $self->pidl_code("}"); $self->pidl_code(""); $self->pidl_code("offset = $switch_dissect(tvb, offset, pinfo, tree, drep, hf_index, &level);"); if ($e->{ALIGN} > 1) { $self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;"); $self->pidl_code(""); } $self->pidl_code("switch(level) {$res\t}"); $self->pidl_code("proto_item_set_len(item, offset-old_offset);\n"); $self->pidl_code("return offset;"); $self->deindent; $self->pidl_code("}"); $self->pidl_fn_end($dissectorname); $self->register_type($name, "offset = $dissectorname(tvb, offset, pinfo, tree, drep, \@HF\@, \@PARAM\@);", "FT_NONE", "BASE_NONE", 0, "NULL", 0);}sub Const($$$){ my ($self,$const,$ifname) = @_; if (!defined($const->{ARRAY_LEN}[0])) { $self->pidl_hdr("#define $const->{NAME}\t( $const->{VALUE} )\n"); } else { $self->pidl_hdr("#define $const->{NAME}\t $const->{VALUE}\n"); }}sub Typedef($$$$){ my ($self,$e,$name,$ifname) = @_; $self->Type($e->{DATA}, $name, $ifname);}sub Type($$$$){ my ($self, $e, $name, $ifname) = @_; $self->PrintIdl(DumpType($e->{ORIGINAL})); { ENUM => \&Enum, STRUCT => \&Struct, UNION => \&Union, BITMAP => \&Bitmap, TYPEDEF => \&Typedef }->{$e->{TYPE}}->($self, $e, $name, $ifname);}sub RegisterInterface($$){ my ($self, $x) = @_; $self->pidl_fn_start("proto_register_dcerpc_$x->{NAME}"); $self->pidl_code("void proto_register_dcerpc_$x->{NAME}(void)"); $self->pidl_code("{"); $self->indent; $self->{res}->{code}.=$self->DumpHfList()."\n"; $self->{res}->{code}.="\n".DumpEttList($self->{ett})."\n"; if (defined($x->{UUID})) { # These can be changed to non-pidl_code names if the old dissectors # in epan/dissctors are deleted. my $name = uc($x->{NAME}) . " (pidl)"; my $short_name = uc($x->{NAME}); my $filter_name = $x->{NAME}; if (has_property($x, "helpstring")) { $name = $x->{PROPERTIES}->{helpstring}; } if (defined($self->{conformance}->{protocols}->{$x->{NAME}})) { $short_name = $self->{conformance}->{protocols}->{$x->{NAME}}->{SHORTNAME}; $name = $self->{conformance}->{protocols}->{$x->{NAME}}->{LONGNAME}; $filter_name = $self->{conformance}->{protocols}->{$x->{NAME}}->{FILTERNAME}; } $self->pidl_code("proto_dcerpc_$x->{NAME} = proto_register_protocol(".make_str($name).", ".make_str($short_name).", ".make_str($filter_name).");"); $self->pidl_code("proto_register_field_array(proto_dcerpc_$x->{NAME}, hf, array_length (hf));"); $self->pidl_code("proto_register_subtree_array(ett, array_length(ett));"); } else { $self->pidl_code("proto_dcerpc = proto_get_id_by_filter_name(\"dcerpc\");"); $self->pidl_code("proto_register_field_array(proto_dcerpc, hf, array_length(hf));"); $self->pidl_code("proto_register_subtree_array(ett, array_length(ett));"); } $self->deindent; $self->pidl_code("}\n"); $self->pidl_fn_end("proto_register_dcerpc_$x->{NAME}");}sub RegisterInterfaceHandoff($$){ my ($self,$x) = @_; if (defined($x->{UUID})) { $self->pidl_fn_start("proto_reg_handoff_dcerpc_$x->{NAME}"); $self->pidl_code("void proto_reg_handoff_dcerpc_$x->{NAME}(void)"); $self->pidl_code("{"); $self->indent; $self->pidl_code("dcerpc_init_uuid(proto_dcerpc_$x->{NAME}, ett_dcerpc_$x->{NAME},"); $self->pidl_code("\t&uuid_dcerpc_$x->{NAME}, ver_dcerpc_$x->{NAME},"); $self->pidl_code("\t$x->{NAME}_dissectors, hf_$x->{NAME}_opnum);"); $self->deindent; $self->pidl_code("}"); $self->pidl_fn_end("proto_reg_handoff_dcerpc_$x->{NAME}"); $self->{hf_used}->{"hf_$x->{NAME}_opnum"} = 1; }}sub ProcessInclude{ my $self = shift; my @includes = @_; foreach (@includes) { $self->pidl_hdr("#include \"$_\""); } $self->pidl_hdr("");}sub ProcessImport{ my $self = shift; my @imports = @_; foreach (@imports) { next if($_ eq "security"); s/\.idl\"$//; s/^\"//;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -