cyberchef 10.22.1 → 10.24.0
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/CHANGELOG.md +182 -0
- package/CONTRIBUTING.md +40 -0
- package/Dockerfile +2 -0
- package/Gruntfile.js +2 -28
- package/README.md +1 -1
- package/babel.config.js +0 -6
- package/package.json +64 -63
- package/src/core/Chef.mjs +8 -1
- package/src/core/Ingredient.mjs +5 -2
- package/src/core/Operation.mjs +6 -1
- package/src/core/Recipe.mjs +10 -5
- package/src/core/config/Categories.json +20 -4
- package/src/core/config/OperationConfig.json +550 -26
- package/src/core/config/modules/Ciphers.mjs +6 -0
- package/src/core/config/modules/Crypto.mjs +6 -0
- package/src/core/config/modules/Default.mjs +8 -0
- package/src/core/config/modules/Shellcode.mjs +2 -0
- package/src/core/config/scripts/fixCryptoApiImports.mjs +54 -0
- package/src/core/config/scripts/fixSnackBarMarkup.mjs +28 -0
- package/src/core/lib/AudioBytes.mjs +103 -0
- package/src/core/lib/AudioMetaSchema.mjs +82 -0
- package/src/core/lib/AudioParsers.mjs +630 -0
- package/src/core/lib/BigIntUtils.mjs +73 -0
- package/src/core/lib/Extract.mjs +5 -0
- package/src/core/lib/Modhex.mjs +2 -0
- package/src/core/lib/ParityBit.mjs +50 -0
- package/src/core/lib/QRCode.mjs +30 -10
- package/src/core/lib/RC6.mjs +625 -0
- package/src/core/operations/A1Z26CipherDecode.mjs +1 -1
- package/src/core/operations/AddTextToImage.mjs +116 -64
- package/src/core/operations/AnalyseUUID.mjs +109 -6
- package/src/core/operations/BlurImage.mjs +10 -12
- package/src/core/operations/ContainImage.mjs +50 -40
- package/src/core/operations/ConvertImageFormat.mjs +33 -39
- package/src/core/operations/CoverImage.mjs +39 -37
- package/src/core/operations/CropImage.mjs +35 -21
- package/src/core/operations/DisassembleARM.mjs +193 -0
- package/src/core/operations/DitherImage.mjs +8 -8
- package/src/core/operations/EscapeUnicodeCharacters.mjs +0 -17
- package/src/core/operations/ExtractAudioMetadata.mjs +175 -0
- package/src/core/operations/ExtractEmailAddresses.mjs +2 -3
- package/src/core/operations/ExtractLSB.mjs +17 -11
- package/src/core/operations/ExtractRGBA.mjs +12 -10
- package/src/core/operations/FlaskSessionDecode.mjs +80 -0
- package/src/core/operations/FlaskSessionSign.mjs +89 -0
- package/src/core/operations/FlaskSessionVerify.mjs +136 -0
- package/src/core/operations/FlipImage.mjs +14 -10
- package/src/core/operations/GenerateImage.mjs +39 -32
- package/src/core/operations/ImageBrightnessContrast.mjs +10 -10
- package/src/core/operations/ImageFilter.mjs +14 -13
- package/src/core/operations/ImageHueSaturationLightness.mjs +22 -20
- package/src/core/operations/ImageOpacity.mjs +6 -8
- package/src/core/operations/InvertImage.mjs +4 -6
- package/src/core/operations/Jq.mjs +12 -4
- package/src/core/operations/NormaliseImage.mjs +5 -7
- package/src/core/operations/OffsetChecker.mjs +1 -1
- package/src/core/operations/ParityBit.mjs +128 -0
- package/src/core/operations/ParseEthernetFrame.mjs +112 -0
- package/src/core/operations/ParseIPv4Header.mjs +23 -6
- package/src/core/operations/ParseQRCode.mjs +13 -13
- package/src/core/operations/PseudoRandomIntegerGenerator.mjs +164 -0
- package/src/core/operations/RC6Decrypt.mjs +119 -0
- package/src/core/operations/RC6Encrypt.mjs +119 -0
- package/src/core/operations/RandomizeColourPalette.mjs +11 -11
- package/src/core/operations/RegularExpression.mjs +2 -1
- package/src/core/operations/RenderMarkdown.mjs +35 -4
- package/src/core/operations/ResizeImage.mjs +30 -23
- package/src/core/operations/RotateImage.mjs +8 -9
- package/src/core/operations/SQLBeautify.mjs +21 -3
- package/src/core/operations/SharpenImage.mjs +94 -62
- package/src/core/operations/SplitColourChannels.mjs +47 -21
- package/src/core/operations/TextIntegerConverter.mjs +123 -0
- package/src/core/operations/UnescapeUnicodeCharacters.mjs +17 -0
- package/src/core/operations/ViewBitPlane.mjs +16 -20
- package/src/core/operations/index.mjs +22 -0
- package/src/node/index.mjs +55 -0
- package/src/web/HTMLIngredient.mjs +24 -43
- package/src/web/HTMLOperation.mjs +8 -2
- package/src/web/Manager.mjs +1 -0
- package/src/web/html/index.html +6 -6
- package/src/web/static/fonts/bmfonts/Roboto72White.fnt +491 -485
- package/src/web/static/fonts/bmfonts/RobotoBlack72White.fnt +494 -488
- package/src/web/static/fonts/bmfonts/RobotoMono72White.fnt +110 -103
- package/src/web/static/fonts/bmfonts/RobotoSlab72White.fnt +498 -492
- package/src/web/stylesheets/layout/_banner.css +30 -0
- package/src/web/stylesheets/layout/_modals.css +5 -0
- package/src/web/stylesheets/utils/_overrides.css +7 -0
- package/src/web/waiters/ControlsWaiter.mjs +82 -0
- package/src/web/waiters/InputWaiter.mjs +12 -6
- package/src/web/waiters/OperationsWaiter.mjs +30 -13
- package/src/web/waiters/RecipeWaiter.mjs +2 -2
- package/tests/browser/02_ops.js +23 -3
- package/tests/node/index.mjs +1 -0
- package/tests/node/tests/lib/BigIntUtils.mjs +150 -0
- package/tests/node/tests/operations.mjs +11 -10
- package/tests/operations/index.mjs +13 -0
- package/tests/operations/tests/A1Z26CipherDecode.mjs +33 -0
- package/tests/operations/tests/AnalyseUUID.mjs +66 -0
- package/tests/operations/tests/DisassembleARM.mjs +377 -0
- package/tests/operations/tests/ExtractAudioMetadata.mjs +287 -0
- package/tests/operations/tests/ExtractEmailAddresses.mjs +38 -12
- package/tests/operations/tests/Fernet.mjs +18 -3
- package/tests/operations/tests/FlaskSession.mjs +246 -0
- package/tests/operations/tests/GenerateQRCode.mjs +67 -0
- package/tests/operations/tests/JWTSign.mjs +83 -8
- package/tests/operations/tests/Jq.mjs +32 -0
- package/tests/operations/tests/Modhex.mjs +20 -0
- package/tests/operations/tests/ParityBit.mjs +147 -0
- package/tests/operations/tests/ParseEthernetFrame.mjs +45 -0
- package/tests/operations/tests/RC6.mjs +487 -0
- package/tests/operations/tests/RegularExpression.mjs +75 -0
- package/tests/operations/tests/RenderMarkdown.mjs +110 -0
- package/tests/operations/tests/SQLBeautify.mjs +54 -0
- package/tests/operations/tests/TextIntegerConverter.mjs +199 -0
- package/tests/samples/Audio.mjs +73 -0
- package/tests/samples/Images.mjs +0 -12
- package/webpack.config.js +10 -7
- package/src/core/lib/ImageManipulation.mjs +0 -251
|
@@ -9,13 +9,12 @@ import OperationError from "../errors/OperationError.mjs";
|
|
|
9
9
|
import { isImage } from "../lib/FileType.mjs";
|
|
10
10
|
import { toBase64 } from "../lib/Base64.mjs";
|
|
11
11
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
|
12
|
-
import Jimp from "jimp
|
|
12
|
+
import { Jimp, JimpMime } from "jimp";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Image Opacity operation
|
|
16
16
|
*/
|
|
17
17
|
class ImageOpacity extends Operation {
|
|
18
|
-
|
|
19
18
|
/**
|
|
20
19
|
* ImageOpacity constructor
|
|
21
20
|
*/
|
|
@@ -35,8 +34,8 @@ class ImageOpacity extends Operation {
|
|
|
35
34
|
type: "number",
|
|
36
35
|
value: 100,
|
|
37
36
|
min: 0,
|
|
38
|
-
max: 100
|
|
39
|
-
}
|
|
37
|
+
max: 100,
|
|
38
|
+
},
|
|
40
39
|
];
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -63,10 +62,10 @@ class ImageOpacity extends Operation {
|
|
|
63
62
|
image.opacity(opacity / 100);
|
|
64
63
|
|
|
65
64
|
let imageBuffer;
|
|
66
|
-
if (image.
|
|
67
|
-
imageBuffer = await image.
|
|
65
|
+
if (image.mime === "image/gif") {
|
|
66
|
+
imageBuffer = await image.getBuffer(JimpMime.png);
|
|
68
67
|
} else {
|
|
69
|
-
imageBuffer = await image.
|
|
68
|
+
imageBuffer = await image.getBuffer(image.mime);
|
|
70
69
|
}
|
|
71
70
|
return imageBuffer.buffer;
|
|
72
71
|
} catch (err) {
|
|
@@ -90,7 +89,6 @@ class ImageOpacity extends Operation {
|
|
|
90
89
|
|
|
91
90
|
return `<img src="data:${type};base64,${toBase64(dataArray)}">`;
|
|
92
91
|
}
|
|
93
|
-
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
export default ImageOpacity;
|
|
@@ -9,13 +9,12 @@ import OperationError from "../errors/OperationError.mjs";
|
|
|
9
9
|
import { isImage } from "../lib/FileType.mjs";
|
|
10
10
|
import { toBase64 } from "../lib/Base64.mjs";
|
|
11
11
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
|
12
|
-
import Jimp from "jimp
|
|
12
|
+
import { Jimp, JimpMime } from "jimp";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Invert Image operation
|
|
16
16
|
*/
|
|
17
17
|
class InvertImage extends Operation {
|
|
18
|
-
|
|
19
18
|
/**
|
|
20
19
|
* InvertImage constructor
|
|
21
20
|
*/
|
|
@@ -54,10 +53,10 @@ class InvertImage extends Operation {
|
|
|
54
53
|
image.invert();
|
|
55
54
|
|
|
56
55
|
let imageBuffer;
|
|
57
|
-
if (image.
|
|
58
|
-
imageBuffer = await image.
|
|
56
|
+
if (image.mime === "image/gif") {
|
|
57
|
+
imageBuffer = await image.getBuffer(JimpMime.png);
|
|
59
58
|
} else {
|
|
60
|
-
imageBuffer = await image.
|
|
59
|
+
imageBuffer = await image.getBuffer(image.mime);
|
|
61
60
|
}
|
|
62
61
|
return imageBuffer.buffer;
|
|
63
62
|
} catch (err) {
|
|
@@ -81,7 +80,6 @@ class InvertImage extends Operation {
|
|
|
81
80
|
|
|
82
81
|
return `<img src="data:${type};base64,${toBase64(dataArray)}">`;
|
|
83
82
|
}
|
|
84
|
-
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
export default InvertImage;
|
|
@@ -30,7 +30,12 @@ class Jq extends Operation {
|
|
|
30
30
|
name: "Query",
|
|
31
31
|
type: "string",
|
|
32
32
|
value: ""
|
|
33
|
-
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "Raw",
|
|
36
|
+
type: "boolean",
|
|
37
|
+
value: false
|
|
38
|
+
},
|
|
34
39
|
];
|
|
35
40
|
}
|
|
36
41
|
|
|
@@ -40,7 +45,7 @@ class Jq extends Operation {
|
|
|
40
45
|
* @returns {string}
|
|
41
46
|
*/
|
|
42
47
|
run(input, args) {
|
|
43
|
-
const [query] = args;
|
|
48
|
+
const [query, raw] = args;
|
|
44
49
|
let result;
|
|
45
50
|
|
|
46
51
|
try {
|
|
@@ -48,8 +53,11 @@ class Jq extends Operation {
|
|
|
48
53
|
} catch (err) {
|
|
49
54
|
throw new OperationError(`Invalid jq expression: ${err.message}`);
|
|
50
55
|
}
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
if (raw && typeof result === "string") {
|
|
57
|
+
return result;
|
|
58
|
+
} else {
|
|
59
|
+
return JSON.stringify(result);
|
|
60
|
+
}
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
}
|
|
@@ -8,13 +8,12 @@ import Operation from "../Operation.mjs";
|
|
|
8
8
|
import OperationError from "../errors/OperationError.mjs";
|
|
9
9
|
import { isImage } from "../lib/FileType.mjs";
|
|
10
10
|
import { toBase64 } from "../lib/Base64.mjs";
|
|
11
|
-
import Jimp from "jimp
|
|
11
|
+
import { Jimp, JimpMime } from "jimp";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Normalise Image operation
|
|
15
15
|
*/
|
|
16
16
|
class NormaliseImage extends Operation {
|
|
17
|
-
|
|
18
17
|
/**
|
|
19
18
|
* NormaliseImage constructor
|
|
20
19
|
*/
|
|
@@ -27,7 +26,7 @@ class NormaliseImage extends Operation {
|
|
|
27
26
|
this.infoURL = "";
|
|
28
27
|
this.inputType = "ArrayBuffer";
|
|
29
28
|
this.outputType = "ArrayBuffer";
|
|
30
|
-
this.presentType=
|
|
29
|
+
this.presentType = "html";
|
|
31
30
|
this.args = [];
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -52,10 +51,10 @@ class NormaliseImage extends Operation {
|
|
|
52
51
|
image.normalize();
|
|
53
52
|
|
|
54
53
|
let imageBuffer;
|
|
55
|
-
if (image.
|
|
56
|
-
imageBuffer = await image.
|
|
54
|
+
if (image.mime === "image/gif") {
|
|
55
|
+
imageBuffer = await image.getBuffer(JimpMime.png);
|
|
57
56
|
} else {
|
|
58
|
-
imageBuffer = await image.
|
|
57
|
+
imageBuffer = await image.getBuffer(image.mime);
|
|
59
58
|
}
|
|
60
59
|
return imageBuffer.buffer;
|
|
61
60
|
} catch (err) {
|
|
@@ -79,7 +78,6 @@ class NormaliseImage extends Operation {
|
|
|
79
78
|
|
|
80
79
|
return `<img src="data:${type};base64,${toBase64(dataArray)}">`;
|
|
81
80
|
}
|
|
82
|
-
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
export default NormaliseImage;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author j83305 [awz22@protonmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import { calculateParityBit, decodeParityBit } from "../lib/ParityBit.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parity Bit operation
|
|
12
|
+
*/
|
|
13
|
+
class ParityBit extends Operation {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ParityBit constructor
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this.name = "Parity Bit";
|
|
22
|
+
this.module = "Default";
|
|
23
|
+
this.description = "A parity bit, or check bit, is the simplest form of error detection. It is a bit which is added to a string of bits and represents if the number of 1's in the binary string is an even number or odd number.<br><br>If a delimiter is specified, the parity bit calculation will be performed on each 'block' of the input data, where the blocks are created by slicing the input at each occurence of the delimiter character";
|
|
24
|
+
this.infoURL = "https://wikipedia.org/wiki/Parity_bit";
|
|
25
|
+
this.inputType = "string";
|
|
26
|
+
this.outputType = "string";
|
|
27
|
+
this.args = [
|
|
28
|
+
{
|
|
29
|
+
name: "Mode",
|
|
30
|
+
type: "option",
|
|
31
|
+
value: [
|
|
32
|
+
"Even Parity",
|
|
33
|
+
"Odd Parity"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Postion",
|
|
38
|
+
type: "option",
|
|
39
|
+
value: [
|
|
40
|
+
"Start",
|
|
41
|
+
"End"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "Encode or Decode",
|
|
46
|
+
type: "option",
|
|
47
|
+
value: [
|
|
48
|
+
"Encode",
|
|
49
|
+
"Decode"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Delimiter",
|
|
54
|
+
type: "shortString",
|
|
55
|
+
value: ""
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {string} input
|
|
62
|
+
* @param {Object[]} args
|
|
63
|
+
* @returns {string}
|
|
64
|
+
*/
|
|
65
|
+
run(input, args) {
|
|
66
|
+
if (input.length === 0) {
|
|
67
|
+
return input;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* determines weather to use the encode or decode method based off args[2]
|
|
71
|
+
* @param input input to be encoded or decoded
|
|
72
|
+
* @param args array
|
|
73
|
+
*/
|
|
74
|
+
const method = (input, args) => args[2] === "Encode" ? calculateParityBit(input, args) : decodeParityBit(input, args);
|
|
75
|
+
if (args[3].length > 0) {
|
|
76
|
+
const byteStrings = input.split(args[3]);
|
|
77
|
+
for (let byteStringsArrayIndex = 0; byteStringsArrayIndex < byteStrings.length; byteStringsArrayIndex++) {
|
|
78
|
+
byteStrings[byteStringsArrayIndex] = method(byteStrings[byteStringsArrayIndex], args);
|
|
79
|
+
}
|
|
80
|
+
return byteStrings.join(args[3]);
|
|
81
|
+
}
|
|
82
|
+
return method(input, args);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Highlight Parity Bit
|
|
87
|
+
*
|
|
88
|
+
* @param {Object[]} pos
|
|
89
|
+
* @param {number} pos[].start
|
|
90
|
+
* @param {number} pos[].end
|
|
91
|
+
* @param {Object[]} args
|
|
92
|
+
* @returns {Object[]} pos
|
|
93
|
+
*/
|
|
94
|
+
highlight(pos, args) {
|
|
95
|
+
if (args[3].length === 0) {
|
|
96
|
+
if (args[1] === "Prepend") {
|
|
97
|
+
pos[0].start += 1;
|
|
98
|
+
pos[0].end += 1;
|
|
99
|
+
}
|
|
100
|
+
return pos;
|
|
101
|
+
}
|
|
102
|
+
// need to be able to read input to do the highlighting when there is a delimiter
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Highlight Parity Bit in reverse
|
|
107
|
+
*
|
|
108
|
+
* @param {Object[]} pos
|
|
109
|
+
* @param {number} pos[].start
|
|
110
|
+
* @param {number} pos[].end
|
|
111
|
+
* @param {Object[]} args
|
|
112
|
+
* @returns {Object[]} pos
|
|
113
|
+
*/
|
|
114
|
+
highlightReverse(pos, args) {
|
|
115
|
+
if (args[3].length === 0) {
|
|
116
|
+
if (args[1] === "Prepend") {
|
|
117
|
+
if (pos[0].start > 0) {
|
|
118
|
+
pos[0].start -= 1;
|
|
119
|
+
}
|
|
120
|
+
pos[0].end -= 1;
|
|
121
|
+
}
|
|
122
|
+
return pos;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default ParityBit;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author tedk [tedk@ted.do]
|
|
3
|
+
* @copyright Crown Copyright 2024
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import OperationError from "../errors/OperationError.mjs";
|
|
9
|
+
import Utils from "../Utils.mjs";
|
|
10
|
+
import {fromHex, toHex} from "../lib/Hex.mjs";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Parse Ethernet frame operation
|
|
14
|
+
*/
|
|
15
|
+
class ParseEthernetFrame extends Operation {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* ParseEthernetFrame constructor
|
|
19
|
+
*/
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
|
|
23
|
+
this.name = "Parse Ethernet frame";
|
|
24
|
+
this.module = "Default";
|
|
25
|
+
this.description = "Parses an Ethernet frame and either shows the deduced values (Source and destination MAC, VLANs) or returns the packet data.<br /><br />Good for use in conjunction with the Parse IPv4, and Parse TCP/UDP recipes.";
|
|
26
|
+
this.infoURL = "https://en.wikipedia.org/wiki/Ethernet_frame#Frame_%E2%80%93_data_link_layer";
|
|
27
|
+
this.inputType = "string";
|
|
28
|
+
this.outputType = "html";
|
|
29
|
+
this.args = [
|
|
30
|
+
{
|
|
31
|
+
name: "Input type",
|
|
32
|
+
type: "option",
|
|
33
|
+
value: [
|
|
34
|
+
"Raw", "Hex"
|
|
35
|
+
],
|
|
36
|
+
defaultIndex: 0,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Return type",
|
|
40
|
+
type: "option",
|
|
41
|
+
value: [
|
|
42
|
+
"Text output", "Packet data", "Packet data (hex)",
|
|
43
|
+
],
|
|
44
|
+
defaultIndex: 0,
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {string} input
|
|
52
|
+
* @param {Object[]} args
|
|
53
|
+
* @returns {html}
|
|
54
|
+
*/
|
|
55
|
+
run(input, args) {
|
|
56
|
+
const format = args[0];
|
|
57
|
+
const outputFormat = args[1];
|
|
58
|
+
|
|
59
|
+
if (format === "Hex") {
|
|
60
|
+
input = fromHex(input);
|
|
61
|
+
} else if (format === "Raw") {
|
|
62
|
+
input = new Uint8Array(Utils.strToArrayBuffer(input));
|
|
63
|
+
} else {
|
|
64
|
+
throw new OperationError("Invalid input format selected.");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const destinationMac = input.slice(0, 6);
|
|
68
|
+
const sourceMac = input.slice(6, 12);
|
|
69
|
+
|
|
70
|
+
let offset = 12;
|
|
71
|
+
const vlans = [];
|
|
72
|
+
|
|
73
|
+
while (offset < input.length) {
|
|
74
|
+
const ethType = Utils.byteArrayToChars(input.slice(offset, offset+2));
|
|
75
|
+
offset += 2;
|
|
76
|
+
|
|
77
|
+
if (ethType === "\x81\x00" || ethType === "\x88\xA8") {
|
|
78
|
+
// Parse the VLAN tag:
|
|
79
|
+
// [0000] 0000 0000 0000
|
|
80
|
+
// ^^^ PRIO - Ignored
|
|
81
|
+
// ^ DEI - Ignored
|
|
82
|
+
// ^^^^ ^^^^ ^^^^ VLAN ID
|
|
83
|
+
const vlanTag = input.slice(offset, offset+2);
|
|
84
|
+
vlans.push(((vlanTag[0] & 0b00001111) << 8) | vlanTag[1]);
|
|
85
|
+
|
|
86
|
+
offset += 2;
|
|
87
|
+
} else {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const packetData = input.slice(offset);
|
|
93
|
+
|
|
94
|
+
if (outputFormat === "Packet data") {
|
|
95
|
+
return Utils.byteArrayToChars(packetData);
|
|
96
|
+
} else if (outputFormat === "Packet data (hex)") {
|
|
97
|
+
return toHex(packetData);
|
|
98
|
+
} else if (outputFormat === "Text output") {
|
|
99
|
+
let retval = `Source MAC: ${toHex(sourceMac, ":")}\nDestination MAC: ${toHex(destinationMac, ":")}\n`;
|
|
100
|
+
if (vlans.length > 0) {
|
|
101
|
+
retval += `VLAN: ${vlans.join(", ")}\n`;
|
|
102
|
+
}
|
|
103
|
+
retval += `Data:\n${toHex(packetData)}`;
|
|
104
|
+
return retval;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export default ParseEthernetFrame;
|
|
@@ -33,6 +33,12 @@ class ParseIPv4Header extends Operation {
|
|
|
33
33
|
"name": "Input format",
|
|
34
34
|
"type": "option",
|
|
35
35
|
"value": ["Hex", "Raw"]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "Output format",
|
|
39
|
+
"type": "option",
|
|
40
|
+
"value": ["Table", "Data (hex)", "Data (raw)"],
|
|
41
|
+
defaultIndex: 0,
|
|
36
42
|
}
|
|
37
43
|
];
|
|
38
44
|
}
|
|
@@ -44,6 +50,8 @@ class ParseIPv4Header extends Operation {
|
|
|
44
50
|
*/
|
|
45
51
|
run(input, args) {
|
|
46
52
|
const format = args[0];
|
|
53
|
+
const outputFormat = args[1];
|
|
54
|
+
|
|
47
55
|
let output;
|
|
48
56
|
|
|
49
57
|
if (format === "Hex") {
|
|
@@ -98,7 +106,10 @@ class ParseIPv4Header extends Operation {
|
|
|
98
106
|
checksumResult = givenChecksum + " (incorrect, should be " + correctChecksum + ")";
|
|
99
107
|
}
|
|
100
108
|
|
|
101
|
-
|
|
109
|
+
const data = input.slice(ihl * 4);
|
|
110
|
+
|
|
111
|
+
if (outputFormat === "Table") {
|
|
112
|
+
output = `<table class='table table-hover table-sm table-bordered table-nonfluid'><tr><th>Field</th><th>Value</th></tr>
|
|
102
113
|
<tr><td>Version</td><td>${version}</td></tr>
|
|
103
114
|
<tr><td>Internet Header Length (IHL)</td><td>${ihl} (${ihl * 4} bytes)</td></tr>
|
|
104
115
|
<tr><td>Differentiated Services Code Point (DSCP)</td><td>${dscp}</td></tr>
|
|
@@ -116,13 +127,19 @@ class ParseIPv4Header extends Operation {
|
|
|
116
127
|
<tr><td>Protocol</td><td>${protocol}, ${protocolInfo.protocol} (${protocolInfo.keyword})</td></tr>
|
|
117
128
|
<tr><td>Header checksum</td><td>${checksumResult}</td></tr>
|
|
118
129
|
<tr><td>Source IP address</td><td>${ipv4ToStr(srcIP)}</td></tr>
|
|
119
|
-
<tr><td>Destination IP address</td><td>${ipv4ToStr(dstIP)}</td></tr
|
|
130
|
+
<tr><td>Destination IP address</td><td>${ipv4ToStr(dstIP)}</td></tr>
|
|
131
|
+
<tr><td>Data (hex)</td><td>${toHex(data)}</td></tr>`;
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
133
|
+
if (ihl > 5) {
|
|
134
|
+
output += `<tr><td>Options</td><td>${toHex(options)}</td></tr>`;
|
|
135
|
+
}
|
|
124
136
|
|
|
125
|
-
|
|
137
|
+
return output + "</table>";
|
|
138
|
+
} else if (outputFormat === "Data (hex)") {
|
|
139
|
+
return toHex(data);
|
|
140
|
+
} else if (outputFormat === "Data (raw)") {
|
|
141
|
+
return Utils.byteArrayToChars(data);
|
|
142
|
+
}
|
|
126
143
|
}
|
|
127
144
|
|
|
128
145
|
}
|
|
@@ -13,7 +13,6 @@ import { parseQrCode } from "../lib/QRCode.mjs";
|
|
|
13
13
|
* Parse QR Code operation
|
|
14
14
|
*/
|
|
15
15
|
class ParseQRCode extends Operation {
|
|
16
|
-
|
|
17
16
|
/**
|
|
18
17
|
* ParseQRCode constructor
|
|
19
18
|
*/
|
|
@@ -22,24 +21,26 @@ class ParseQRCode extends Operation {
|
|
|
22
21
|
|
|
23
22
|
this.name = "Parse QR Code";
|
|
24
23
|
this.module = "Image";
|
|
25
|
-
this.description =
|
|
24
|
+
this.description =
|
|
25
|
+
"Reads an image file and attempts to detect and read a Quick Response (QR) code from the image.<br><br><u>Normalise Image</u><br>Attempts to normalise the image before parsing it to improve detection of a QR code.";
|
|
26
26
|
this.infoURL = "https://wikipedia.org/wiki/QR_code";
|
|
27
27
|
this.inputType = "ArrayBuffer";
|
|
28
28
|
this.outputType = "string";
|
|
29
29
|
this.args = [
|
|
30
30
|
{
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
31
|
+
name: "Normalise image",
|
|
32
|
+
type: "boolean",
|
|
33
|
+
value: false,
|
|
34
|
+
},
|
|
35
35
|
];
|
|
36
36
|
this.checks = [
|
|
37
37
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
pattern:
|
|
39
|
+
"^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
|
|
40
|
+
flags: "",
|
|
41
|
+
args: [false],
|
|
42
|
+
useful: true,
|
|
43
|
+
},
|
|
43
44
|
];
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -54,9 +55,8 @@ class ParseQRCode extends Operation {
|
|
|
54
55
|
if (!isImage(input)) {
|
|
55
56
|
throw new OperationError("Invalid file type.");
|
|
56
57
|
}
|
|
57
|
-
return
|
|
58
|
+
return parseQrCode(input, normalise);
|
|
58
59
|
}
|
|
59
|
-
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export default ParseQRCode;
|