cyberchef 9.39.2 → 9.39.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/config/OperationConfig.json +19 -3
- package/src/core/lib/FileSignatures.mjs +25 -1
- package/src/core/operations/Fork.mjs +11 -2
- package/src/core/operations/FromBase45.mjs +14 -2
- package/src/core/operations/FromBase85.mjs +13 -1
- package/src/core/operations/Merge.mjs +8 -2
- package/src/core/operations/Subsection.mjs +10 -1
- package/tests/lib/TestRegister.mjs +11 -1
- package/tests/operations/index.mjs +2 -0
- package/tests/operations/tests/Base85.mjs +48 -0
- package/tests/operations/tests/Fork.mjs +14 -3
- package/tests/operations/tests/Subsection.mjs +102 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "9.39.
|
|
3
|
+
"version": "9.39.5",
|
|
4
4
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
|
5
5
|
"author": "n1474335 <n1474335@gmail.com>",
|
|
6
6
|
"homepage": "https://gchq.github.io/CyberChef",
|
|
@@ -5044,7 +5044,7 @@
|
|
|
5044
5044
|
},
|
|
5045
5045
|
"Extract Files": {
|
|
5046
5046
|
"module": "Default",
|
|
5047
|
-
"description": "Performs file carving to attempt to extract files from the input.<br><br>This operation is currently capable of carving out the following formats:\n <ul>\n <li>\n JPG,JPEG,JPE,THM,MPO</li><li>GIF</li><li>PNG</li><li>BMP</li><li>ICO</li><li>TGA</li><li>FLV</li><li>WAV</li><li>MP3</li><li>PDF</li><li>RTF</li><li>DOCX,XLSX,PPTX</li><li>EPUB</li><li>EXE,DLL,DRV,VXD,SYS,OCX,VBX,COM,FON,SCR</li><li>ELF,BIN,AXF,O,PRX,SO</li><li>DYLIB</li><li>ZIP</li><li>TAR</li><li>GZ</li><li>BZ2</li><li>ZLIB</li><li>XZ</li><li>JAR</li><li>LZOP,LZO</li><li>DEB</li><li>SQLITE</li><li>EVT</li><li>EVTX</li><li>DMP</li><li>PF</li><li>PLIST</li><li>KEYCHAIN</li><li>LNK\n </li>\n </ul>Minimum File Size can be used to prune small false positives.",
|
|
5047
|
+
"description": "Performs file carving to attempt to extract files from the input.<br><br>This operation is currently capable of carving out the following formats:\n <ul>\n <li>\n JPG,JPEG,JPE,THM,MPO</li><li>GIF</li><li>PNG</li><li>WEBP</li><li>BMP</li><li>ICO</li><li>TGA</li><li>FLV</li><li>WAV</li><li>MP3</li><li>PDF</li><li>RTF</li><li>DOCX,XLSX,PPTX</li><li>EPUB</li><li>EXE,DLL,DRV,VXD,SYS,OCX,VBX,COM,FON,SCR</li><li>ELF,BIN,AXF,O,PRX,SO</li><li>DYLIB</li><li>ZIP</li><li>TAR</li><li>GZ</li><li>BZ2</li><li>ZLIB</li><li>XZ</li><li>JAR</li><li>LZOP,LZO</li><li>DEB</li><li>SQLITE</li><li>EVT</li><li>EVTX</li><li>DMP</li><li>PF</li><li>PLIST</li><li>KEYCHAIN</li><li>LNK\n </li>\n </ul>Minimum File Size can be used to prune small false positives.",
|
|
5048
5048
|
"infoURL": "https://forensicswiki.xyz/wiki/index.php?title=File_Carving",
|
|
5049
5049
|
"inputType": "ArrayBuffer",
|
|
5050
5050
|
"outputType": "html",
|
|
@@ -5652,6 +5652,11 @@
|
|
|
5652
5652
|
"name": "Alphabet",
|
|
5653
5653
|
"type": "string",
|
|
5654
5654
|
"value": "0-9A-Z $%*+\\-./:"
|
|
5655
|
+
},
|
|
5656
|
+
{
|
|
5657
|
+
"name": "Remove non-alphabet chars",
|
|
5658
|
+
"type": "boolean",
|
|
5659
|
+
"value": true
|
|
5655
5660
|
}
|
|
5656
5661
|
]
|
|
5657
5662
|
},
|
|
@@ -5995,6 +6000,11 @@
|
|
|
5995
6000
|
"value": "0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"
|
|
5996
6001
|
}
|
|
5997
6002
|
]
|
|
6003
|
+
},
|
|
6004
|
+
{
|
|
6005
|
+
"name": "Remove non-alphabet chars",
|
|
6006
|
+
"type": "boolean",
|
|
6007
|
+
"value": true
|
|
5998
6008
|
}
|
|
5999
6009
|
]
|
|
6000
6010
|
},
|
|
@@ -8340,13 +8350,19 @@
|
|
|
8340
8350
|
},
|
|
8341
8351
|
"Merge": {
|
|
8342
8352
|
"module": "Default",
|
|
8343
|
-
"description": "Consolidate all branches back into a single trunk. The opposite of Fork.",
|
|
8353
|
+
"description": "Consolidate all branches back into a single trunk. The opposite of Fork. Unticking the Merge All checkbox will only consolidate all branches up to the nearest Fork/Subsection.",
|
|
8344
8354
|
"infoURL": null,
|
|
8345
8355
|
"inputType": "string",
|
|
8346
8356
|
"outputType": "string",
|
|
8347
8357
|
"flowControl": true,
|
|
8348
8358
|
"manualBake": false,
|
|
8349
|
-
"args": [
|
|
8359
|
+
"args": [
|
|
8360
|
+
{
|
|
8361
|
+
"name": "Merge All",
|
|
8362
|
+
"type": "boolean",
|
|
8363
|
+
"value": true
|
|
8364
|
+
}
|
|
8365
|
+
]
|
|
8350
8366
|
},
|
|
8351
8367
|
"Microsoft Script Decoder": {
|
|
8352
8368
|
"module": "Default",
|
|
@@ -70,7 +70,7 @@ export const FILE_SIGNATURES = {
|
|
|
70
70
|
10: 0x42,
|
|
71
71
|
11: 0x50
|
|
72
72
|
},
|
|
73
|
-
extractor:
|
|
73
|
+
extractor: extractWEBP
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
name: "Camera Image File Format",
|
|
@@ -3032,6 +3032,30 @@ export function extractPNG(bytes, offset) {
|
|
|
3032
3032
|
}
|
|
3033
3033
|
|
|
3034
3034
|
|
|
3035
|
+
/**
|
|
3036
|
+
* WEBP extractor.
|
|
3037
|
+
*
|
|
3038
|
+
* @param {Uint8Array} bytes
|
|
3039
|
+
* @param {number} offset
|
|
3040
|
+
* @returns {Uint8Array}
|
|
3041
|
+
*/
|
|
3042
|
+
export function extractWEBP(bytes, offset) {
|
|
3043
|
+
const stream = new Stream(bytes.slice(offset));
|
|
3044
|
+
|
|
3045
|
+
// Move to file size offset.
|
|
3046
|
+
stream.moveForwardsBy(4);
|
|
3047
|
+
|
|
3048
|
+
// Read file size field.
|
|
3049
|
+
const fileSize = stream.readInt(4, "le");
|
|
3050
|
+
|
|
3051
|
+
// Move to end of file.
|
|
3052
|
+
// There is no need to minus 8 from the size as the size factors in the offset.
|
|
3053
|
+
stream.moveForwardsBy(fileSize);
|
|
3054
|
+
|
|
3055
|
+
return stream.carve();
|
|
3056
|
+
}
|
|
3057
|
+
|
|
3058
|
+
|
|
3035
3059
|
/**
|
|
3036
3060
|
* BMP extractor.
|
|
3037
3061
|
*
|
|
@@ -65,12 +65,21 @@ class Fork extends Operation {
|
|
|
65
65
|
if (input)
|
|
66
66
|
inputs = input.split(splitDelim);
|
|
67
67
|
|
|
68
|
+
// Set to 1 as if we are here, then there is one, the current one.
|
|
69
|
+
let numOp = 1;
|
|
68
70
|
// Create subOpList for each tranche to operate on
|
|
69
|
-
//
|
|
71
|
+
// all remaining operations unless we encounter a Merge
|
|
70
72
|
for (i = state.progress + 1; i < opList.length; i++) {
|
|
71
73
|
if (opList[i].name === "Merge" && !opList[i].disabled) {
|
|
72
|
-
|
|
74
|
+
numOp--;
|
|
75
|
+
if (numOp === 0 || opList[i].ingValues[0])
|
|
76
|
+
break;
|
|
77
|
+
else
|
|
78
|
+
// Not this Fork's Merge.
|
|
79
|
+
subOpList.push(opList[i]);
|
|
73
80
|
} else {
|
|
81
|
+
if (opList[i].name === "Fork" || opList[i].name === "Subsection")
|
|
82
|
+
numOp++;
|
|
74
83
|
subOpList.push(opList[i]);
|
|
75
84
|
}
|
|
76
85
|
}
|
|
@@ -32,7 +32,12 @@ class FromBase45 extends Operation {
|
|
|
32
32
|
name: "Alphabet",
|
|
33
33
|
type: "string",
|
|
34
34
|
value: ALPHABET
|
|
35
|
-
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Remove non-alphabet chars",
|
|
38
|
+
type: "boolean",
|
|
39
|
+
value: true
|
|
40
|
+
},
|
|
36
41
|
];
|
|
37
42
|
|
|
38
43
|
this.highlight = highlightFromBase45;
|
|
@@ -46,10 +51,17 @@ class FromBase45 extends Operation {
|
|
|
46
51
|
*/
|
|
47
52
|
run(input, args) {
|
|
48
53
|
if (!input) return [];
|
|
49
|
-
const alphabet = Utils.expandAlphRange(args[0]);
|
|
54
|
+
const alphabet = Utils.expandAlphRange(args[0]).join("");
|
|
55
|
+
const removeNonAlphChars = args[1];
|
|
50
56
|
|
|
51
57
|
const res = [];
|
|
52
58
|
|
|
59
|
+
// Remove non-alphabet characters
|
|
60
|
+
if (removeNonAlphChars) {
|
|
61
|
+
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
|
62
|
+
input = input.replace(re, "");
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
for (const triple of Utils.chunked(input, 3)) {
|
|
54
66
|
triple.reverse();
|
|
55
67
|
let b = 0;
|
|
@@ -32,6 +32,11 @@ class FromBase85 extends Operation {
|
|
|
32
32
|
type: "editableOption",
|
|
33
33
|
value: ALPHABET_OPTIONS
|
|
34
34
|
},
|
|
35
|
+
{
|
|
36
|
+
name: "Remove non-alphabet chars",
|
|
37
|
+
type: "boolean",
|
|
38
|
+
value: true
|
|
39
|
+
},
|
|
35
40
|
];
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -43,6 +48,7 @@ class FromBase85 extends Operation {
|
|
|
43
48
|
run(input, args) {
|
|
44
49
|
const alphabet = Utils.expandAlphRange(args[0]).join(""),
|
|
45
50
|
encoding = alphabetName(alphabet),
|
|
51
|
+
removeNonAlphChars = args[1],
|
|
46
52
|
result = [];
|
|
47
53
|
|
|
48
54
|
if (alphabet.length !== 85 ||
|
|
@@ -50,6 +56,12 @@ class FromBase85 extends Operation {
|
|
|
50
56
|
throw new OperationError("Alphabet must be of length 85");
|
|
51
57
|
}
|
|
52
58
|
|
|
59
|
+
// Remove non-alphabet characters
|
|
60
|
+
if (removeNonAlphChars) {
|
|
61
|
+
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
|
62
|
+
input = input.replace(re, "");
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
if (input.length === 0) return [];
|
|
54
66
|
|
|
55
67
|
const matches = input.match(/<~(.+?)~>/);
|
|
@@ -69,7 +81,7 @@ class FromBase85 extends Operation {
|
|
|
69
81
|
.map((chr, idx) => {
|
|
70
82
|
const digit = alphabet.indexOf(chr);
|
|
71
83
|
if (digit < 0 || digit > 84) {
|
|
72
|
-
throw `Invalid character '${chr}' at index ${idx}`;
|
|
84
|
+
throw `Invalid character '${chr}' at index ${i + idx}`;
|
|
73
85
|
}
|
|
74
86
|
return digit;
|
|
75
87
|
});
|
|
@@ -20,10 +20,16 @@ class Merge extends Operation {
|
|
|
20
20
|
this.name = "Merge";
|
|
21
21
|
this.flowControl = true;
|
|
22
22
|
this.module = "Default";
|
|
23
|
-
this.description = "Consolidate all branches back into a single trunk. The opposite of Fork.";
|
|
23
|
+
this.description = "Consolidate all branches back into a single trunk. The opposite of Fork. Unticking the Merge All checkbox will only consolidate all branches up to the nearest Fork/Subsection.";
|
|
24
24
|
this.inputType = "string";
|
|
25
25
|
this.outputType = "string";
|
|
26
|
-
this.args = [
|
|
26
|
+
this.args = [
|
|
27
|
+
{
|
|
28
|
+
name: "Merge All",
|
|
29
|
+
type: "boolean",
|
|
30
|
+
value: true,
|
|
31
|
+
}
|
|
32
|
+
];
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
/**
|
|
@@ -67,12 +67,21 @@ class Subsection extends Operation {
|
|
|
67
67
|
subOpList = [];
|
|
68
68
|
|
|
69
69
|
if (input && section !== "") {
|
|
70
|
+
// Set to 1 as if we are here, then there is one, the current one.
|
|
71
|
+
let numOp = 1;
|
|
70
72
|
// Create subOpList for each tranche to operate on
|
|
71
73
|
// all remaining operations unless we encounter a Merge
|
|
72
74
|
for (let i = state.progress + 1; i < opList.length; i++) {
|
|
73
75
|
if (opList[i].name === "Merge" && !opList[i].disabled) {
|
|
74
|
-
|
|
76
|
+
numOp--;
|
|
77
|
+
if (numOp === 0 || opList[i].ingValues[0])
|
|
78
|
+
break;
|
|
79
|
+
else
|
|
80
|
+
// Not this subsection's Merge.
|
|
81
|
+
subOpList.push(opList[i]);
|
|
75
82
|
} else {
|
|
83
|
+
if (opList[i].name === "Fork" || opList[i].name === "Subsection")
|
|
84
|
+
numOp++;
|
|
76
85
|
subOpList.push(opList[i]);
|
|
77
86
|
}
|
|
78
87
|
}
|
|
@@ -84,7 +84,17 @@ class TestRegister {
|
|
|
84
84
|
|
|
85
85
|
if (result.error) {
|
|
86
86
|
if (test.expectedError) {
|
|
87
|
-
|
|
87
|
+
if (result.error.displayStr === test.expectedOutput) {
|
|
88
|
+
ret.status = "passing";
|
|
89
|
+
} else {
|
|
90
|
+
ret.status = "failing";
|
|
91
|
+
ret.output = [
|
|
92
|
+
"Expected",
|
|
93
|
+
"\t" + test.expectedOutput.replace(/\n/g, "\n\t"),
|
|
94
|
+
"Received",
|
|
95
|
+
"\t" + result.error.displayStr.replace(/\n/g, "\n\t"),
|
|
96
|
+
].join("\n");
|
|
97
|
+
}
|
|
88
98
|
} else {
|
|
89
99
|
ret.status = "erroring";
|
|
90
100
|
ret.output = result.error.displayStr;
|
|
@@ -24,6 +24,7 @@ import "./tests/Base45.mjs";
|
|
|
24
24
|
import "./tests/Base58.mjs";
|
|
25
25
|
import "./tests/Base64.mjs";
|
|
26
26
|
import "./tests/Base62.mjs";
|
|
27
|
+
import "./tests/Base85.mjs";
|
|
27
28
|
import "./tests/BitwiseOp.mjs";
|
|
28
29
|
import "./tests/ByteRepr.mjs";
|
|
29
30
|
import "./tests/CartesianProduct.mjs";
|
|
@@ -114,6 +115,7 @@ import "./tests/HASSH.mjs";
|
|
|
114
115
|
import "./tests/GetAllCasings.mjs";
|
|
115
116
|
import "./tests/SIGABA.mjs";
|
|
116
117
|
import "./tests/ELFInfo.mjs";
|
|
118
|
+
import "./tests/Subsection.mjs";
|
|
117
119
|
|
|
118
120
|
|
|
119
121
|
// Cannot test operations that use the File type yet
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base85 tests
|
|
3
|
+
*
|
|
4
|
+
* @author john19696
|
|
5
|
+
* @copyright Crown Copyright 2019
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
|
+
|
|
10
|
+
// Example from Wikipedia
|
|
11
|
+
const wpExample = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
|
|
12
|
+
// Escape newline, quote & backslash
|
|
13
|
+
const wpOutput = "9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,O<\
|
|
14
|
+
DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF\"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKYi(\
|
|
15
|
+
DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIal(\
|
|
16
|
+
DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G>u\
|
|
17
|
+
D.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c";
|
|
18
|
+
|
|
19
|
+
TestRegister.addTests([
|
|
20
|
+
{
|
|
21
|
+
name: "To Base85",
|
|
22
|
+
input: wpExample,
|
|
23
|
+
expectedOutput: wpOutput,
|
|
24
|
+
recipeConfig: [
|
|
25
|
+
{ "op": "To Base85",
|
|
26
|
+
"args": ["!-u"] }
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "From Base85",
|
|
31
|
+
input: wpOutput + "\n",
|
|
32
|
+
expectedOutput: wpExample,
|
|
33
|
+
recipeConfig: [
|
|
34
|
+
{ "op": "From Base85",
|
|
35
|
+
"args": ["!-u", true] }
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "From Base85",
|
|
40
|
+
input: wpOutput + "v",
|
|
41
|
+
expectedError: true,
|
|
42
|
+
expectedOutput: "From Base85 - Invalid character 'v' at index 337",
|
|
43
|
+
recipeConfig: [
|
|
44
|
+
{ "op": "From Base85",
|
|
45
|
+
"args": ["!-u", false] }
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
@@ -31,7 +31,7 @@ TestRegister.addTests([
|
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
op: "Merge",
|
|
34
|
-
args: [],
|
|
34
|
+
args: [true],
|
|
35
35
|
},
|
|
36
36
|
],
|
|
37
37
|
},
|
|
@@ -50,7 +50,7 @@ TestRegister.addTests([
|
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
op: "Merge",
|
|
53
|
-
args: [],
|
|
53
|
+
args: [true],
|
|
54
54
|
},
|
|
55
55
|
],
|
|
56
56
|
},
|
|
@@ -66,5 +66,16 @@ TestRegister.addTests([
|
|
|
66
66
|
{"op": "Label", "args": ["skipReturn"]},
|
|
67
67
|
{"op": "To Base64", "args": ["A-Za-z0-9+/="]}
|
|
68
68
|
]
|
|
69
|
-
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "Fork, Partial Merge",
|
|
72
|
+
input: "Hello World",
|
|
73
|
+
expectedOutput: "48656c6c6f 576f726c64",
|
|
74
|
+
recipeConfig: [
|
|
75
|
+
{ "op": "Fork", "args": [" ", " ", false] },
|
|
76
|
+
{ "op": "Fork", "args": ["l", "l", false] },
|
|
77
|
+
{ "op": "Merge", "args": [false] },
|
|
78
|
+
{ "op": "To Hex", "args": ["None", 0] },
|
|
79
|
+
]
|
|
80
|
+
},
|
|
70
81
|
]);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subsection Tests.
|
|
3
|
+
*
|
|
4
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
5
|
+
* @copyright Crown Copyright 2022
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
|
+
|
|
10
|
+
TestRegister.addTests([
|
|
11
|
+
{
|
|
12
|
+
name: "Subsection: nothing",
|
|
13
|
+
input: "",
|
|
14
|
+
expectedOutput: "",
|
|
15
|
+
recipeConfig: [
|
|
16
|
+
{
|
|
17
|
+
"op": "Subsection",
|
|
18
|
+
"args": ["", true, true, false],
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "Subsection, Full Merge: nothing",
|
|
24
|
+
input: "",
|
|
25
|
+
expectedOutput: "",
|
|
26
|
+
recipeConfig: [
|
|
27
|
+
{
|
|
28
|
+
"op": "Subsection",
|
|
29
|
+
"args": ["", true, true, false],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"op": "Merge",
|
|
33
|
+
"args": [true],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "Subsection, Partial Merge: nothing",
|
|
39
|
+
input: "",
|
|
40
|
+
expectedOutput: "",
|
|
41
|
+
recipeConfig: [
|
|
42
|
+
{
|
|
43
|
+
"op": "Subsection",
|
|
44
|
+
"args": ["", true, true, false],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"op": "Merge",
|
|
48
|
+
"args": [false],
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Subsection, Full Merge: Base64 with Hex",
|
|
54
|
+
input: "SGVsbG38675629ybGQ=",
|
|
55
|
+
expectedOutput: "Hello World",
|
|
56
|
+
recipeConfig: [
|
|
57
|
+
{
|
|
58
|
+
"op": "Subsection",
|
|
59
|
+
"args": ["386756", true, true, false],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"op": "From Hex",
|
|
63
|
+
"args": ["Auto"],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"op": "Merge",
|
|
67
|
+
"args": [true],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"op": "From Base64",
|
|
71
|
+
"args": ["A-Za-z0-9+/=", true, false],
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "Subsection, Partial Merge: Base64 with Hex surrounded by binary data.",
|
|
77
|
+
input: "000000000SGVsbG38675629ybGQ=0000000000",
|
|
78
|
+
expectedOutput: "000000000Hello World0000000000",
|
|
79
|
+
recipeConfig: [
|
|
80
|
+
{
|
|
81
|
+
"op": "Subsection",
|
|
82
|
+
"args": ["SGVsbG38675629ybGQ=", true, true, false],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"op": "Subsection",
|
|
86
|
+
"args": ["386756", true, true, false],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"op": "From Hex",
|
|
90
|
+
"args": ["Auto"],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"op": "Merge",
|
|
94
|
+
"args": [false],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"op": "From Base64",
|
|
98
|
+
"args": ["A-Za-z0-9+/=", true, false],
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
]);
|