Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ 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.

**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
Expand Down
72 changes: 47 additions & 25 deletions src/nb/deser/SerializationDumper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -1397,15 +1409,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));
}

Expand All @@ -1415,10 +1428,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));
}

Expand Down Expand Up @@ -1492,6 +1506,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()));
Expand Down