{"id":20445808,"url":"https://github.com/rapid7/smbj-rpc","last_synced_at":"2025-07-07T04:10:15.902Z","repository":{"id":22472602,"uuid":"95162017","full_name":"rapid7/smbj-rpc","owner":"rapid7","description":"Created by Paul Miseiko via the GitHub Connector","archived":false,"fork":false,"pushed_at":"2025-06-04T12:34:30.000Z","size":1368,"stargazers_count":57,"open_issues_count":25,"forks_count":29,"subscribers_count":74,"default_branch":"master","last_synced_at":"2025-07-04T18:11:22.605Z","etag":null,"topics":["cifs","java","smb"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rapid7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-22T22:32:33.000Z","updated_at":"2025-06-28T18:24:21.000Z","dependencies_parsed_at":"2024-04-17T09:38:52.499Z","dependency_job_id":"760039a8-5745-4e37-af8d-1c156fa96a4b","html_url":"https://github.com/rapid7/smbj-rpc","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/rapid7/smbj-rpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fsmbj-rpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fsmbj-rpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fsmbj-rpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fsmbj-rpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rapid7","download_url":"https://codeload.github.com/rapid7/smbj-rpc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fsmbj-rpc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263620918,"owners_count":23489796,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cifs","java","smb"],"created_at":"2024-11-15T10:14:19.336Z","updated_at":"2025-07-07T04:10:15.884Z","avatar_url":"https://github.com/rapid7.png","language":"Java","funding_links":[],"categories":["开发框架"],"sub_categories":["RPC框架"],"readme":"# SMBJ-RPC\n\n [![Build Status](https://github.com/rapid7/smbj-rpc/actions/workflows/CI.yml/badge.svg)](https://github.com/rapid7/smbj-rpc/actions) [![Maven Central](https://img.shields.io/maven-central/v/com.rapid7.client/dcerpc.svg)](https://search.maven.org/artifact/com.rapid7.client/dcerpc) [![Javadocs](https://www.javadoc.io/badge/com.rapid7.client/dcerpc.svg)](https://www.javadoc.io/doc/com.rapid7.client/dcerpc)\n\nDCE-RPC implementation capable of using SMBv2 via SMBJ to invoke remote procedure calls (RPC) over the IPC$ named pipe.\n\nPartial support for the Windows Remote Registry Protocol (MS-RRP) specification (https://msdn.microsoft.com/en-us/library/cc244877.aspx).\n\nSpecial thank you to Jeroen van Erp for SMBJ (https://github.com/hierynomus/smbj).\n\nTable of contents\n=================\n* [Usage Examples](#usage-examples)\n* [NDR Types](#ndr-types)\n  * [Structure](#structure)\n  * [Pointers](#pointers)\n  * [Arrays](#arrays)\n* [NDR Marshalling](#ndr-marshalling)\n  * [Primitive Marshalling](#primitive-marshalling)\n  * [Construct Marshalling](#construct-marshalling)\n* [NDR Alignment](#ndr-alignment)\n  * [Primitive Alignment](#primitive-alignment)\n  * [Array Alignment](#array-alignment)\n  * [Structure Alignment](#structure-alignment)\n  * [Union Alignment](#union-alignment)\n* [Marshalling Example](#marshalling-example)\n\n# Usage Examples\n\nAdd to your pom.xml:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.rapid7.client\u003c/groupId\u003e\n  \u003cartifactId\u003edcerpc\u003c/artifactId\u003e\n  \u003cversion\u003e0.11.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### [MS-RRP]: Windows Remote Registry Protocol (https://msdn.microsoft.com/en-us/library/cc244877.aspx)\n\n```java\nfinal SMBClient smbClient = new SMBClient();\ntry (final Connection smbConnection = smbClient.connect(\"aaa.bbb.ccc.ddd\")) {\n    final AuthenticationContext smbAuthenticationContext = new AuthenticationContext(\"username\", \"password\".toCharArray(), \"\");\n    final Session session = smbConnection.authenticate(smbAuthenticationContext);\n\n    final RPCTransport transport = SMBTransportFactories.WINREG.getTransport(session);\n    final RegistryService registryService = new RegistryService(transport);\n\n    // Read sub keys from the HKLM hive.\n    for (final RegistryKey key : registryService.getSubKeys(\"HKLM\", \"\")) {\n        System.out.println(key.getName());\n    }\n\n    // Read values located in the HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion key.\n    for (final RegistryValue value : registryService.getValues(\"HKLM\", \"Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\")) {\n        System.out.println(value.getName() + \" is \" + value.getType() + \" = \" + value.toString());\n    }\n\n    // Does key exist?  Does value exist?\n    System.out.println(registryService.doesKeyExist(\"HKLM\", \"\"));\n    System.out.println(registryService.doesKeyExist(\"HKLM\", \"bad\"));\n    System.out.println(registryService.doesKeyExist(\"HKLM\", \"Software\"));\n    System.out.println(registryService.doesKeyExist(\"HKLM\", \"Software\\\\bad\"));\n    System.out.println(registryService.doesValueExist(\"HKLM\", \"bad\", \"bad\"));\n    System.out.println(registryService.doesValueExist(\"HKLM\", \"\", \"bad\"));\n    System.out.println(registryService.doesValueExist(\"HKLM\", \"Software\", \"bad\"));\n\n    // Read registry values.\n    System.out.println(registryService.getValue(\"HKLM\", \"SYSTEM\\\\ControlSet001\\\\Control\\\\Session Manager\\\\Environment\", \"Path\").toString());\n    System.out.println(registryService.getValue(\"HKLM\", \"SYSTEM\\\\ControlSet001\\\\Control\\\\Lsa\", \"Authentication Packages\").toString());\n}\n```\n\n#### [MS-SRVS]: Server Service Remote Protocol (https://msdn.microsoft.com/en-us/library/cc247080.aspx)\n\n```java\nfinal SMBClient smbClient = new SMBClient();\ntry (final Connection smbConnection = smbClient.connect(\"aaa.bbb.ccc.ddd\")) {\n    final AuthenticationContext smbAuthenticationContext = new AuthenticationContext(\"username\", \"password\".toCharArray(), \"\");\n    final Session session = smbConnection.authenticate(smbAuthenticationContext);\n\n    final RPCTransport transport = SMBTransportFactories.SRVSVC.getTransport(session);\n    final ServerService serverService = new ServerService(transport);\n    // Get shares at information level 0\n    final List\u003cNetShareInfo0\u003e shares = serverService.getShares0();\n    for (final NetShareInfo0 share : shares) {\n        System.out.println(share);\n    }\n}\n```\n\n# NDR Types\n\nAll objects are assigned to a type hierarchy:\n* Primitive\n  * `boolean`\n  * `character` (ASCII)\n  * Signed/Unsigned Integers:\n    * `small`\n    * `short`\n    * `long`\n    * `hyper`\n  * Signed/Unsigned Floating Points:\n    * `single`\n    * `double`\n* NDR Construct\n  * `Struct`\n  * `Union`\n  * Arrays\n    * `Fixed Array`\n    * `Varying Array`\n    * `Conformant Array`\n    * `Conformant Varying Array`\n  * `Pointer`\n\n# Structure\n\nStructures have 0 or more fields of NDR objects, and have special marshalling and alignment considerations.\n\n# Pointers\n\nAll pointers are represented with a `ReferentID` as an `unsigned long` (NDR20) or `unsigned hyper` (NDR64). While these IDs don't need to be unique, a value of `0` indicates a NULL pointer, and the subsequent referent is considered null and should be ignored.\n\n# Arrays\n\n## Size Representation\n\n* **Fixed**: Size information is not represented as is expected to be known ahead of time. This can either be from another hint (i.e. struct field), or hardcoded to be of constant size.\n\n* **Conformant**: Conformant arrays must contain a `MaximumSize`, which is the size of the entire array. For ND20, this values is an `unsigned long` (4 bytes). For ND64, it is an `unsigned hyper` (8 byte).\n\n* **Varying**: Varying arrays must contain the `Offset` and `ActualSize`, which represents the subset of the complete array to consider. For ND20, these values are an `unsigned long` (4 bytes). For ND64, they are an `unsigned hyper` (8 byte).\n\n## Element Storage\n\nWhen embedded within a struct, element storage has special rules:\n\n* **Conformant**: Stored at the *end* of the embedded structure. This is not the same as deferred references as they are stored at the end of the top level construct.\n\n* **Fixed**/**Varying**: If the array is not conformant, data is stored inline, immediately after size representation (if any).\n\n# NDR Marshalling\n\n## Primitive Marshalling\n\nEach primitive is provided its own unique marshalling strategy, and does not require special consideration.\n\n## Construct Marshalling\n\nMarshalling of constructs consists of three stages:\n* Preamble\n* Entity\n* Deferrals\n\nThe approach to marshalling any NDR data type is:\n```\nmarshal(DataType obj) {\n\tobj.marshalPreamble(Stream)\n\tobj.marshalEntity(Stream)\n\tobj.marshalDeferrals(Stream)\n}\n```\n\nStandard rules for marshalling any NDR construct are as follows:\n\n| | Fixed Array | Varying Array | Conformant Array | Pointer  | Struct |\n| --- | --- | ---| --- | --- | --- |\n| Premable | | | marshal(MaximumLength) | | for f in fields:\u003cbr/\u003ef.marshalPreamble(Stream) |\n| Entity   | for e in entries:\u003cbr/\u003emarshal(e) | marshal(Offset)\u003cbr/\u003emarshal(ActualSize)\u003cbr/\u003emarshal(Entries) | | marshal(ReferentID) | for f in fields:\u003cbr/\u003ef.marshalEntity(Stream) |\n| Deferrals | |  | for e in entries:\u003cbr/\u003emarshal(e) | marshal(reference.referent) | for f in fields:\u003cbr/\u003ef.marshalDeferrals(Stream) |\n\n# NDR Alignment\n\nAll NDR objects must be prefixed aligned a fixed number of bytes N, where N is one of the following: {1, 2, 4, 8}.\n\n*Objects should always align themselves before writing their representation.*\nWhile this can lead to inefficient behavior if the caller knows that the object is already aligned, it results in a simpler framework design.\nBy following this pattern, you can be assured that you can safely call marshall/unmarshall on any `DataType` and it will be aligned automatically.\n\n## Primitive Alignment\n\nAll primitive types are aligned by the following fixed sizes:\n* 1: boolean, char, small\n* 2: short, enums\n* 4: long, float, array size information (NDR20), pointer (NDR20)\n* 8: hyper, double, array size information (NDR64), pointer (NDR64)\n\n## Array Alignment\n\nArray alignment is the largest between the size representation (fixed arrays have none), and the entity alignment.\n\nExamples:\n\nSince the alignment of a short is 2, the alignment of this array is 4 when using NDR20:\n```\n[size_of(range(1,200))] short someArray;\n```\n\nSince the alignment of a hyper is 8, the alignment of this array is 8:\n```\n[size_of(range(1,200))] hyper someArray;\n```\n\nHowever, you must also take care to align at each stage of the marshalling process.\nThe subsequent marshalling code for a conformant array above should look like this if you are part of an embedding struct:\n```java\npublic void marshalPreamble(PacketOutput out) throws IOException {\n    // MaximumCount\n    out.align(Alignment.FOUR);\n    out.writeInt(this.array.length);\n}\npublic void marshalEntity(PacketOutput out) throws IOException {\n    // \u003cNDR conformant array\u003e [size_of(range(1,200))] hyper someArray;\n    out.align(Alignment.EIGHT);\n    for (long hyper : this.array) {\n        // Alignment: 8 - Already aligned\n        out.writeLong(hyper);\n    }\n}\n```\n\n## Structure Alignment\n\nA structure itself must be aligned to the largest alignment for all of its fields (regardless of their type).\nThis alignment is performed at the beginning of `marshalEntity`.\n\nFor example the alignment of this struct is 4:\n```\ntypedef struct {\n    boolean field1;\n    unsigned long field2;\n} MyStruct\n```\n\nThe subsequent marshalling code should look like this:\n```java\npublic void marshalEntity(PacketOutput out) throws IOException {\n    // Our Structure Alignment: 4\n    out.align(Alignment.FOUR);\n    // \u003cNDR: boolean\u003e unsigned boolean field1;\n    // Alignment: 1 - Already aligned\n    out.writeBoolean(field1);\n    // \u003cNDR: unsigned long\u003e unsigned long field2;\n    // Alignment: 4 - We pad 3 bytes as we wrote exactly 1 since the known 4 byte alignment\n    out.pad(3);\n    out.writeEntity(field2);\n}\n```\n\n## Union Alignment\n\nUnions are aligned by the largest alignment of the union discriminator and all of the union arms.\n\nFor example, the alignment of the following union is 8:\n```\ntypedef \n [switch_type(short)] \n union _MyUnion {\n   [case(1)] \n     short MyShort;\n   [case(2)] \n     hyper MyHyper;\n } MyUnion;\n```\n\n# Marshalling Example\n\nSignature:\n```\ntypedef struct {\n    boolean field1;\n    [size_of(range(1,200))] hyper field2;\n    unsigned long* field3;\n} MyStruct\n```\n\nJava Implementation:\n```java\npublic class MyStruct implements Marshallable {\n    private boolean field1;\n    private long[] field2;\n    private Long field3;\n    \n    @Override\n    public void marshalPreamble(PacketOutput out) throws IOException {\n        // \u003cNDR unsigned long\u003e MaximumCount - [size_of(range(1,200))] hyper field2;\n        out.align(Alignment.FOUR);\n        out.write(this.field2.length);\n    }\n    \n    @Override\n    public void marshalEntity(PacketOutput out) throws IOException {\n        // Structure Alignment: 8\n        out.align(Alignment.EIGHT);\n        // \u003cNDR boolean\u003e boolean field1;\n        // Alignment: 1 - Already aligned\n        out.writeBoolean(this.field1);\n        // field2 entires are deferred to end of struct\n        // \u003cNDR pointer\u003e unsigned long field3;\n        out.pad(3); // Alignment: 4 - We wrote exactly 1 byte above since an eight byte alignment\n        if (this.field3 != null)\n            out.writeReferenceID();\n        // \u003cNDR unsigned long\u003e MaximumCount - [size_of(range(1,200))] hyper field2;\n        // Alignment: 8 - Already aligned. We wrote 8 bytes above since an eight byte alignment\n        for (long entry : this.field2) {\n            out.writeLong(entry);\n        }\n    }\n    \n    @Override\n    public void marshalDeferrals(PacketOutput out) throws IOException {\n        if (this.field3 != null) {\n            // \u003cNDR: unsigned long\u003e unsigned long* field3;\n            out.align(Alignment.FOUR);\n            out.writeInt(this.field3);\n        }\n    }\n}\n```\n\nSignature:\n```\ntypedef struct {\n    MyStruct field1;\n    unsigned long field2;\n} OuterStruct\n```\n\nJava Implementation:\n```java\npublic class OuterStruct implements Marshallable {\n    private MyStruct field1;\n    private long field2;\n    \n    @Override\n    public void marshalPreamble(PacketOutput out) throws IOException {\n        // MyStruct will align itself\n        field1.marshalPremable(out);\n    }\n    \n    @Override\n    public void marshalEntity(PacketOutput out) throws IOException {\n        // Structure Alignment: 8\n        out.align(Alignment.EIGHT);\n        // \u003cNDR: struct\u003e MyStruct field1;\n        // Alignment: Will align itself\n        field1.marshalEntity(out);\n        // \u003cNDR: unsigned long\u003e unsigned long field2;\n        out.align(Alignment.FOUR);\n        out.writeInt(this.field2);\n    }\n    \n    @Override\n    public void marshalDeferrals(PacketOutput out) throws IOException {\n        // No pointer deferrals\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Fsmbj-rpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frapid7%2Fsmbj-rpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Fsmbj-rpc/lists"}