This commit is contained in:
Oliver Rahner 2024-05-03 11:01:08 +01:00 committed by GitHub
commit fab73d577a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 108 additions and 0 deletions

View File

@ -242,6 +242,7 @@
"URL Decode",
"Protobuf Decode",
"Protobuf Encode",
"Protobuf Stream Decode",
"VarInt Encode",
"VarInt Decode",
"JA3 Fingerprint",

View File

@ -116,6 +116,30 @@ class Protobuf {
return this.mergeDecodes(input);
}
/**
* Parse Protobuf stream data
* @param {byteArray} input
* @param {any[]} args
* @returns {any[]}
*/
static decodeStream(input, args) {
this.updateProtoRoot(args[0]);
this.showUnknownFields = args[1];
this.showTypes = args[2];
const streams = new Protobuf(input);
const output = [];
let objLength = streams._varInt();
while (!isNaN(objLength) && objLength > 0) {
const subData = streams.data.slice(streams.offset, streams.offset + objLength);
output.push(this.mergeDecodes(subData));
streams.offset += objLength;
objLength = streams._varInt();
}
return output;
}
/**
* Update the parsedProto, throw parsing errors
*

View File

@ -0,0 +1,54 @@
/**
* @author GCHQ Contributor [3]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import Protobuf from "../lib/Protobuf.mjs";
/**
* Protobuf Stream Decode operation
*/
class ProtobufStreamDecode extends Operation {
/**
* ProtobufStreamDecode constructor
*/
constructor() {
super();
this.name = "Protobuf Stream Decode";
this.module = "Protobuf";
this.description = "Decodes Protobuf encoded data from streams to a JSON array representation of the data using the field number as the field key.<br><br>If a .proto schema is defined, the encoded data will be decoded with reference to the schema. Only one message instance will be decoded. <br><br><u>Show Unknown Fields</u><br>When a schema is used, this option shows fields that are present in the input data but not defined in the schema.<br><br><u>Show Types</u><br>Show the type of a field next to its name. For undefined fields, the wiretype and example types are shown instead.";
this.infoURL = "https://developers.google.com/protocol-buffers/docs/techniques#streaming";
this.inputType = "ArrayBuffer";
this.outputType = "JSON";
this.args = [
{
name: "Show Types",
type: "boolean",
value: false
}
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {JSON}
*/
run(input, args) {
input = new Uint8Array(input);
try {
// provide standard values for currently removed arguments
return Protobuf.decodeStream(input, ["", false, ...args]);
} catch (err) {
throw new OperationError(err);
}
}
}
export default ProtobufStreamDecode;

View File

@ -303,4 +303,33 @@ TestRegister.addTests([
}
]
},
{
name: "Protobuf Stream Decode: no schema",
input: "0d081c1203596f751a024d65202b0c0a0a0a066162633132331200",
expectedOutput: JSON.stringify([
{
"1": 28,
"2": "You",
"3": "Me",
"4": 43
},
{
"1": {
"1": "abc123",
"2": {}
}
}
], null, 4),
recipeConfig: [
{
"op": "From Hex",
"args": ["Auto"]
},
{
"op": "Protobuf Stream Decode",
"args": [false]
}
]
},
]);