From c0d145ebbe6f5a60b4e21f4aac761cb0583bc5b8 Mon Sep 17 00:00:00 2001 From: Ruud Schramp Date: Fri, 11 Feb 2022 19:58:06 +0100 Subject: [PATCH 1/5] Support byte-array primitive Crashes reporting: Fields 0: Array - [ - 0x5b fieldName Length - 1 - 0x00 01 Value - b - 0x62 className1 TC_STRING - 0x74 newHandle 0x00 7e 00 09 Length - 2 - 0x00 02 Value - [B - 0x5b42 . . Exception in thread "main" java.lang.RuntimeException: Error: Unexpected array field value type (0x7a at nb.deser.SerializationDumper.readArrayField(SerializationDumper.java:1497) at nb.deser.SerializationDumper.readFieldValue(SerializationDumper.java:989) --- src/nb/deser/SerializationDumper.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nb/deser/SerializationDumper.java b/src/nb/deser/SerializationDumper.java index 17e91f6..47d00dd 100644 --- a/src/nb/deser/SerializationDumper.java +++ b/src/nb/deser/SerializationDumper.java @@ -1492,6 +1492,14 @@ private void readArrayField() { case (byte)0x71: //TC_REFERENCE this.readPrevObject(); break; + + case (byte)0x77: //TC_BLOCKDATA + this.readBlockData(); + break; + + case (byte)0x7a: //TC_BLOCKDATALONG + this.readLongBlockData(); + break; default: //Unknown throw new RuntimeException("Error: Unexpected array field value type (0x" + this.byteToHex(this._data.peek())); From d590b38f1d5c966419675d89d3c538ba67ab3329 Mon Sep 17 00:00:00 2001 From: Nicky Bloor Date: Fri, 21 Jun 2024 23:08:14 +0100 Subject: [PATCH 2/5] Fixed readFloatField() and readDoubleField(). --- src/nb/deser/SerializationDumper.java | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/nb/deser/SerializationDumper.java b/src/nb/deser/SerializationDumper.java index 17e91f6..02562c7 100644 --- a/src/nb/deser/SerializationDumper.java +++ b/src/nb/deser/SerializationDumper.java @@ -1397,15 +1397,16 @@ private void readDoubleField() { byte b1, b2, b3, b4, b5, b6, b7, b8; b1 = this._data.pop(); b2 = this._data.pop(); b3 = this._data.pop(); b4 = this._data.pop(); b5 = this._data.pop(); b6 = this._data.pop(); b7 = this._data.pop(); b8 = this._data.pop(); - this.print("(double)" + (double)(((b1 << 56) & 0xff00000000000000L) + - ((b2 << 48) & 0xff000000000000L) + - ((b3 << 40) & 0xff0000000000L) + - ((b4 << 32) & 0xff00000000L) + - ((b5 << 24) & 0xff000000 ) + - ((b6 << 16) & 0xff0000 ) + - ((b7 << 8) & 0xff00 ) + - ( b8 & 0xff )) + " - 0x" + this.byteToHex(b1) + - " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + " " + this.byteToHex(b4) + " " + this.byteToHex(b5) + " " + this.byteToHex(b6) + " " + + this.print("(double)" + Double.longBitsToDouble((((long)b1 << 56) & 0xff00000000000000L) + + (((long)b2 << 48) & 0xff000000000000L) + + (((long)b3 << 40) & 0xff0000000000L) + + (((long)b4 << 32) & 0xff00000000L) + + (( b5 << 24) & 0xff000000 ) + + (( b6 << 16) & 0xff0000 ) + + (( b7 << 8) & 0xff00 ) + + (( b8 ) & 0xff )) + + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + + " " + this.byteToHex(b4) + " " + this.byteToHex(b5) + " " + this.byteToHex(b6) + " " + this.byteToHex(b7) + " " + this.byteToHex(b8)); } @@ -1415,10 +1416,11 @@ private void readDoubleField() { private void readFloatField() { byte b1, b2, b3, b4; b1 = this._data.pop(); b2 = this._data.pop(); b3 = this._data.pop(); b4 = this._data.pop(); - this.print("(float)" + (float)(((b1 << 24) & 0xff000000) + - ((b2 << 16) & 0xff0000) + - ((b3 << 8) & 0xff00) + - ( b4 & 0xff)) + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + + this.print("(float)" + Float.intBitsToFloat(((b1 << 24) & 0xff000000) + + ((b2 << 16) & 0xff0000) + + ((b3 << 8) & 0xff00) + + ( b4 & 0xff)) + + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + " " + this.byteToHex(b4)); } From 3fe774dfe38bc245bb615adbca9d674d6c4e372c Mon Sep 17 00:00:00 2001 From: Nicky Bloor Date: Fri, 21 Jun 2024 23:09:41 +0100 Subject: [PATCH 3/5] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1c62328..459065c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Download v1.11 built and ready to run from here: [https://github.com/NickstaDB/S \* See the limitations section below for more details. +**Update 21/06/2024:** Fixed bugs in `readFloatField()` and `readDoubleField()`. + **Update 19/12/2018:** SerializationDumper now supports rebuilding serialization streams so you can dump a Java serialization stream to a text file, modify the hex or string values, then convert the text file back into a binary serialization stream. See the section below on [Rebuilding Serialization Streams](#rebuilding-serialization-streams) for an example of this. ## Building From 6d161cdc019cc5746298191ee4f608cd01ae02aa Mon Sep 17 00:00:00 2001 From: Nicky Bloor Date: Fri, 21 Jun 2024 23:15:38 +0100 Subject: [PATCH 4/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 459065c..73d7aee 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The tool does not deserialize the stream (i.e. objects in the stream are not ins This tool was developed to support research into Java deserialization vulnerabilities after spending many hours manually decoding raw serialization streams to debug code! -Download v1.11 built and ready to run from here: [https://github.com/NickstaDB/SerializationDumper/releases/download/1.13/SerializationDumper-v1.13.jar](https://github.com/NickstaDB/SerializationDumper/releases/download/1.13/SerializationDumper-v1.13.jar "SerializationDumper-v1.13.jar") +Download v1.14 built and ready to run from here: [https://github.com/NickstaDB/SerializationDumper/releases/download/v1.14/SerializationDumper-v1.14.jar](https://github.com/NickstaDB/SerializationDumper/releases/download/v1.14/SerializationDumper-v1.14.jar "SerializationDumper-v1.14.jar") \* See the limitations section below for more details. From ae9a8f2825b1d7d3f68fdb47a4278ab2b1ad7015 Mon Sep 17 00:00:00 2001 From: Ruud Schramp Date: Wed, 11 Mar 2026 17:43:33 +0100 Subject: [PATCH 5/5] Dump Byte arrays as hexstring (input for xxd -r -p) --- src/nb/deser/SerializationDumper.java | 36 ++++++++++++++++++--------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/nb/deser/SerializationDumper.java b/src/nb/deser/SerializationDumper.java index 02562c7..b14f07c 100644 --- a/src/nb/deser/SerializationDumper.java +++ b/src/nb/deser/SerializationDumper.java @@ -1042,20 +1042,32 @@ private void readNewArray() { this.print("Array size - " + size + " - 0x" + this.byteToHex(b1) + " " + this.byteToHex(b2) + " " + this.byteToHex(b3) + " " + this.byteToHex(b4)); //Array data - this.print("Values"); - this.increaseIndent(); - for(int i = 0; i < size; ++i) { - //Print element index - this.print("Index " + i + ":"); + if (cd.getClassName().charAt(1)=='B') { + StringBuilder build = new StringBuilder(); + for(int i = 0; i < size; ++i) { + byte b = this._data.pop(); + build.append(this.byteToHex(b)); + }; + this.print("Value " + build.toString()); + + } + else { + this.print("Values"); this.increaseIndent(); - - //Read the field values based on the classDesc read above - this.readFieldValue((byte)cd.getClassName().charAt(1)); - - //Revert indent + for(int i = 0; i < size; ++i) { + //Print element index + this.print("Index " + i + ":"); + this.increaseIndent(); + + //Read the field values based on the classDesc read above + this.readFieldValue((byte)cd.getClassName().charAt(1)); + + //Revert indent + this.decreaseIndent(); + } this.decreaseIndent(); - } - this.decreaseIndent(); + }; + //Revert indent this.decreaseIndent();