diff --git a/.idea/artifacts/G_Earth2.xml b/.idea/artifacts/G_Earth2.xml new file mode 100644 index 0000000..9d4fe51 --- /dev/null +++ b/.idea/artifacts/G_Earth2.xml @@ -0,0 +1,20 @@ + + + $PROJECT_DIR$/out/artifacts/G_Earth + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0548357 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..1ebdf36 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..712c2b5 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,1248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Memor + 256 + memory maps + print + send + sendtostream + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + true + + + + DIRECTORY + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1522695209780 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/src/main/protocol/memory/Rc4Obtainer.java + 28 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + G-Earth2 + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 1.8 + + + + + + + + G-Earth2 + + + + + + + + 1.8 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/G-Earth2.iml b/G-Earth2.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/G-Earth2.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/out/artifacts/G_Earth/G_Earth.html b/out/artifacts/G_Earth/G_Earth.html new file mode 100644 index 0000000..83d886b --- /dev/null +++ b/out/artifacts/G_Earth/G_Earth.html @@ -0,0 +1,43 @@ + + + + + + + +

Test page for G-Earth2

+ Webstart: click to launch this app as webstart


+ + +
+ diff --git a/out/artifacts/G_Earth/G_Earth.jar b/out/artifacts/G_Earth/G_Earth.jar new file mode 100644 index 0000000..7416dac Binary files /dev/null and b/out/artifacts/G_Earth/G_Earth.jar differ diff --git a/out/artifacts/G_Earth/G_Earth.jnlp b/out/artifacts/G_Earth/G_Earth.jnlp new file mode 100644 index 0000000..92bd616 --- /dev/null +++ b/out/artifacts/G_Earth/G_Earth.jnlp @@ -0,0 +1,15 @@ + + + + G-Earth + Unknown + G-Earth2 + + + + + + + + + diff --git a/out/production/G-Earth2/main/Main.class b/out/production/G-Earth2/main/Main.class new file mode 100644 index 0000000..5aaa3d0 Binary files /dev/null and b/out/production/G-Earth2/main/Main.class differ diff --git a/out/production/G-Earth2/main/OSValidator.class b/out/production/G-Earth2/main/OSValidator.class new file mode 100644 index 0000000..8975ffe Binary files /dev/null and b/out/production/G-Earth2/main/OSValidator.class differ diff --git a/out/production/G-Earth2/main/irrelevant/Timer.class b/out/production/G-Earth2/main/irrelevant/Timer.class new file mode 100644 index 0000000..7864cd1 Binary files /dev/null and b/out/production/G-Earth2/main/irrelevant/Timer.class differ diff --git a/out/production/G-Earth2/main/protocol/HConnection$State.class b/out/production/G-Earth2/main/protocol/HConnection$State.class new file mode 100644 index 0000000..552be5b Binary files /dev/null and b/out/production/G-Earth2/main/protocol/HConnection$State.class differ diff --git a/out/production/G-Earth2/main/protocol/HConnection.class b/out/production/G-Earth2/main/protocol/HConnection.class new file mode 100644 index 0000000..cf1b3ff Binary files /dev/null and b/out/production/G-Earth2/main/protocol/HConnection.class differ diff --git a/out/production/G-Earth2/main/protocol/HMessage$Side.class b/out/production/G-Earth2/main/protocol/HMessage$Side.class new file mode 100644 index 0000000..a449dcc Binary files /dev/null and b/out/production/G-Earth2/main/protocol/HMessage$Side.class differ diff --git a/out/production/G-Earth2/main/protocol/HMessage.class b/out/production/G-Earth2/main/protocol/HMessage.class new file mode 100644 index 0000000..1048185 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/HMessage.class differ diff --git a/out/production/G-Earth2/main/protocol/HPacket.class b/out/production/G-Earth2/main/protocol/HPacket.class new file mode 100644 index 0000000..8b6fa9f Binary files /dev/null and b/out/production/G-Earth2/main/protocol/HPacket.class differ diff --git a/out/production/G-Earth2/main/protocol/StateChangeListener.class b/out/production/G-Earth2/main/protocol/StateChangeListener.class new file mode 100644 index 0000000..fbb7e8d Binary files /dev/null and b/out/production/G-Earth2/main/protocol/StateChangeListener.class differ diff --git a/out/production/G-Earth2/main/protocol/TrafficListener.class b/out/production/G-Earth2/main/protocol/TrafficListener.class new file mode 100644 index 0000000..efcc262 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/TrafficListener.class differ diff --git a/out/production/G-Earth2/main/protocol/crypto/RC4.class b/out/production/G-Earth2/main/protocol/crypto/RC4.class new file mode 100644 index 0000000..f9e4168 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/crypto/RC4.class differ diff --git a/out/production/G-Earth2/main/protocol/memory/FlashClient.class b/out/production/G-Earth2/main/protocol/memory/FlashClient.class new file mode 100644 index 0000000..00d3474 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/memory/FlashClient.class differ diff --git a/out/production/G-Earth2/main/protocol/memory/MemorySnippet.class b/out/production/G-Earth2/main/protocol/memory/MemorySnippet.class new file mode 100644 index 0000000..46d3eaf Binary files /dev/null and b/out/production/G-Earth2/main/protocol/memory/MemorySnippet.class differ diff --git a/out/production/G-Earth2/main/protocol/memory/MemoryUtils.class b/out/production/G-Earth2/main/protocol/memory/MemoryUtils.class new file mode 100644 index 0000000..fe37b46 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/memory/MemoryUtils.class differ diff --git a/out/production/G-Earth2/main/protocol/memory/Rc4Obtainer.class b/out/production/G-Earth2/main/protocol/memory/Rc4Obtainer.class new file mode 100644 index 0000000..12b2f39 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/memory/Rc4Obtainer.class differ diff --git a/out/production/G-Earth2/main/protocol/packethandler/BufferListener.class b/out/production/G-Earth2/main/protocol/packethandler/BufferListener.class new file mode 100644 index 0000000..9a3d35d Binary files /dev/null and b/out/production/G-Earth2/main/protocol/packethandler/BufferListener.class differ diff --git a/out/production/G-Earth2/main/protocol/packethandler/Handler.class b/out/production/G-Earth2/main/protocol/packethandler/Handler.class new file mode 100644 index 0000000..d162727 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/packethandler/Handler.class differ diff --git a/out/production/G-Earth2/main/protocol/packethandler/IncomingHandler.class b/out/production/G-Earth2/main/protocol/packethandler/IncomingHandler.class new file mode 100644 index 0000000..f7407a7 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/packethandler/IncomingHandler.class differ diff --git a/out/production/G-Earth2/main/protocol/packethandler/OutgoingHandler.class b/out/production/G-Earth2/main/protocol/packethandler/OutgoingHandler.class new file mode 100644 index 0000000..444e331 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/packethandler/OutgoingHandler.class differ diff --git a/out/production/G-Earth2/main/protocol/packethandler/PayloadBuffer.class b/out/production/G-Earth2/main/protocol/packethandler/PayloadBuffer.class new file mode 100644 index 0000000..a564b77 Binary files /dev/null and b/out/production/G-Earth2/main/protocol/packethandler/PayloadBuffer.class differ diff --git a/out/production/G-Earth2/main/ui/G-Earth.fxml b/out/production/G-Earth2/main/ui/G-Earth.fxml new file mode 100644 index 0000000..2dea4ee --- /dev/null +++ b/out/production/G-Earth2/main/ui/G-Earth.fxml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out/production/G-Earth2/main/ui/GEarthController.class b/out/production/G-Earth2/main/ui/GEarthController.class new file mode 100644 index 0000000..a22f2d0 Binary files /dev/null and b/out/production/G-Earth2/main/ui/GEarthController.class differ diff --git a/out/production/G-Earth2/main/ui/SubForm.class b/out/production/G-Earth2/main/ui/SubForm.class new file mode 100644 index 0000000..ec75b78 Binary files /dev/null and b/out/production/G-Earth2/main/ui/SubForm.class differ diff --git a/out/production/G-Earth2/main/ui/bootstrap3.css b/out/production/G-Earth2/main/ui/bootstrap3.css new file mode 100644 index 0000000..a79da42 --- /dev/null +++ b/out/production/G-Earth2/main/ui/bootstrap3.css @@ -0,0 +1,893 @@ +.root { + -fx-body-color : #F5F5F5; + -fx-outer-border : #cecece; +} +.button,.menu-button,.toggle-button,.split-menu-button { + -fx-font-size: 14; + -fx-background-radius: 4; + -fx-border-radius: 4; + -fx-pref-height: 30; + -fx-min-width: 30; +} +.button,.menu-button,.split-menu-button,.toggle-button,.number-button { + -fx-background-insets: 0, 0, -1, 0; +} + +.split-menu-button > .label { + -fx-border-radius: 4 0 0 4; + -fx-background-radius: 3 0 0 3; +} + +.split-menu-button > .arrow-button { + -fx-border-radius: 0 4 4 0; + -fx-background-radius: 0 3 3 0; +} + +.lg { + -fx-min-height: 46; + -fx-max-height: 46; + -fx-font-size: 18; +} + +.sm { + -fx-min-height: 30; + -fx-max-height: 30; +} + +.xs { + -fx-min-height: 22; + -fx-max-height: 22; + -fx-font-size: 10; +} + +.primary .arrow, +.success .arrow, +.info .arrow, +.warning .arrow, +.danger .arrow { + -fx-background-color: transparent, white; +} + +.primary > .label, +.success > .label, +.info > .label, +.warning > .label, +.danger > .label { + -fx-text-fill: white; +} + +.action-btn { + -fx-min-width: 80; +} + +/*positions*/ +/*first*/ +.button.first, .menu-button.first, .toggle-button.first, .text-field.first, .text-area.first { + -fx-border-radius: 4 0 0 4; + -fx-background-radius: 4 0 0 4; +} + +.split-menu-button.first > .arrow-button, .split-menu-button.middle > .arrow-button { + -fx-border-radius: 0; + -fx-background-radius: 0; +} + +VBox > .button.first, +VBox > .menu-button.first, +VBox > .toggle-button.first, +VBox > .split-menu-button.first, +VBox > .text-field.first, +VBox > .text-area.first { + -fx-border-radius: 4 4 0 0; + -fx-background-radius: 4 4 0 0; +} + +VBox > .split-menu-button.first > .label { + -fx-border-radius: 4 0 0 0; + -fx-background-radius: 3 0 0 0; +} +VBox > .split-menu-button.first > .arrow-button { + -fx-border-radius: 0 4 0 0; + -fx-background-radius: 0 3 0 0; +} +/*middle*/ +.middle { + -fx-border-radius: 0; + -fx-background-radius: 0; +} + +/*last*/ +.split-menu-button.middle > .label, .split-menu-button.last > .label { + -fx-border-radius: 0; + -fx-background-radius: 0; +} + +.split-menu-button.last { + -fx-border-radius: 0 4 4 0; + -fx-background-radius: 0 4 4 0; +} + +.button.middle, .text-field.middle, .text-area.middle, .split-menu-button.middle, .toggle-button.middle { + -fx-border-radius: 0; + -fx-background-radius: 0; +} + +.button.last, .text-field.last, .text-area.last, .split-menu-button.last, .toggle-button.last, .menu-button.last { + -fx-border-radius: 0 4 4 0; + -fx-background-radius: 0 4 4 0; +} +VBox > .button.last, +VBox > .menu-button.last, +VBox > .toggle-button.last, +VBox > .split-menu-button.last, +VBox > .text-field.last, +VBox > .text-area.last { + -fx-border-radius: 0 0 4 4; + -fx-background-radius: 0 0 4 4; +} + +VBox > .split-menu-button.last > .label { + -fx-border-radius: 0 0 0 4; + -fx-background-radius: 0 0 0 3; +} +VBox > .split-menu-button.last > .arrow-button { + -fx-border-radius: 0 0 4 0; + -fx-background-radius: 0 0 3 0; +} + +/*button styles*/ + +/*default button settings*/ + +/*bgcolor setting*/ +.color-picker,.date-picker > .arrow-button, +.number-button,.left-arrow-button,.right-arrow-button, +.button,.split-menu-button,.toggle-button,.menu-button, +.font-menu-button, .split-menu-button > .label, .split-menu-button > .arrow-button { + -fx-background-color: white; +} + +.color-picker,.date-picker > .arrow-button, +.button,.menu-button,.toggle-button,.number-button,.left-arrow-button,.right-arrow-button, +.font-menu-button, +.split-menu-button > .label,.split-menu-button > .arrow-button { + -fx-border-color: #cccccc; + -fx-text-fill: #333333; +} +/*just for the special split menu button*/ +.split-menu-button > .label { + -fx-border-width: 1 0 1 1; +} +/*for date picker arrow button*/ +.date-picker > .arrow-button { + -fx-border-radius: 0 4 4 0; +} +.combo-box > .arrow-button, .choice-box > .arrow-button { + -fx-border-width: 0; +} +/*hover state*/ +.color-picker:hover, +.date-picker:hover > .arrow-button, +.combo-box:hover,.choice-box:hover, +.number-button:hover,.left-arrow-button:hover,.right-arrow-button:hover, +.button:hover,.menu-button:hover,.toggle-button:hover, +.font-menu-button:hover, +.split-menu-button > .label:hover, .split-menu-button > .arrow-button:hover { + -fx-background-color: #e6e6e6; + -fx-border-color: #acacac; +} +/*pressed selected*/ +.color-picker:pressed,.color-picker:selected, +.number-button:pressed,.number-button:selected, +.date-picker:pressed > .arrow-button, +.combo-box:pressed > .arrow-button,.combo-box:selected > .arrow-button, +.choice-box:pressed > .arrow-button,.choice-box:selected > .arrow-button, +.font-menu-button:pressed,.font-menu-button:selected, +.left-arrow-button:pressed,.left-arrow-button:selected, +.right-arrow-button:pressed,.right-arrow-button:selected, +.button:pressed, .button:selected,.menu-button:pressed,.menu-button:selected +,.toggle-button:pressed,.toggle-button:selected, +.split-menu-button:pressed > .label, .split-menu-button > .arrow-button:pressed { + -fx-background-color: #e6e6e6; + -fx-border-color: #acacac; + -fx-effect: innershadow(gaussian, #adadad, 10, 0, 0, 3); +} + +/*primary*/ + +.button.primary,.split-menu-button.primary,.toggle-button.primary,.menu-button.primary, +.split-menu-button.primary > .label, .split-menu-button.primary > .arrow-button { + -fx-background-color: #337ab7; +} + +.button.primary,.menu-button.primary,.toggle-button.primary, +.split-menu-button.primary > .label,.split-menu-button.primary > .arrow-button { + -fx-border-color: #2e6da4; + -fx-text-fill: white; +} +/*hover state*/ +.button.primary:hover,.menu-button.primary:hover,.toggle-button.primary:hover, +.split-menu-button.primary > .label:hover, .split-menu-button.primary > .arrow-button:hover { + -fx-border-color: #204d74; + -fx-background-color: #286090; +} +/*pressed selected*/ +.button.primary:pressed, .button.primary:selected, +.menu-button.primary:pressed,.menu-button.primary:selected +,.toggle-button.primary:pressed,.toggle-button.primary:selected, +.split-menu-button.primary:pressed > .label, .split-menu-button.primary > .arrow-button:pressed { + -fx-background-color: #286090; + -fx-border-color: #204d74; + -fx-effect: innershadow(gaussian, #204d74, 10, 0, 0, 3); +} + +/*success*/ + +.button.success,.split-menu-button.success,.toggle-button.success,.menu-button.success, +.split-menu-button.success > .label, .split-menu-button.success > .arrow-button { + -fx-background-color: #5cb85c; +} + +.button.success,.menu-button.success,.toggle-button.success, +.split-menu-button.success > .label,.split-menu-button.success > .arrow-button { + -fx-border-color: #4cae4c; + -fx-text-fill: white; +} +/*hover state*/ +.button.success:hover,.menu-button.success:hover,.toggle-button.success:hover, +.split-menu-button.success > .label:hover, .split-menu-button.success > .arrow-button:hover { + -fx-border-color: #398439; + -fx-background-color: #449d44; +} +/*pressed selected*/ +.button.success:pressed, .button.success:selected, +.menu-button.success:pressed,.menu-button.success:selected +,.toggle-button.success:pressed,.toggle-button.success:selected, +.split-menu-button.success:pressed > .label, .split-menu-button.success > .arrow-button:pressed { + -fx-background-color: #449d44; + -fx-border-color: #398439; + -fx-effect: innershadow(gaussian, #398439, 10, 0, 0, 3); +} + +/*info*/ + +.button.info,.split-menu-button.info,.toggle-button.info,.menu-button.info, +.split-menu-button.info > .label, .split-menu-button.info > .arrow-button { + -fx-background-color: #5bc0de; +} + +.button.info,.menu-button.info,.toggle-button.info, +.split-menu-button.info > .label,.split-menu-button.info > .arrow-button { + -fx-border-color: #46b8da; + -fx-text-fill: white; +} +/*hover state*/ +.button.info:hover,.menu-button.info:hover,.toggle-button.info:hover, +.split-menu-button.info > .label:hover, .split-menu-button.info > .arrow-button:hover { + -fx-border-color: #269abc; + -fx-background-color: #31b0d5; +} +/*pressed selected*/ +.button.info:pressed, .button.info:selected, +.menu-button.info:pressed,.menu-button.info:selected +,.toggle-button.info:pressed,.toggle-button.info:selected, +.split-menu-button.info:pressed > .label, .split-menu-button.info > .arrow-button:pressed { + -fx-background-color: #31b0d5; + -fx-border-color: #269abc; + -fx-effect: innershadow(gaussian, #269abc, 10, 0, 0, 3); +} + +/*warning*/ + +.button.warning,.split-menu-button.warning,.toggle-button.warning,.menu-button.warning, +.split-menu-button.warning > .label, .split-menu-button.warning > .arrow-button { + -fx-background-color: #f0ad4e; +} + +.button.warning,.menu-button.warning,.toggle-button.warning, +.split-menu-button.warning > .label,.split-menu-button.warning > .arrow-button { + -fx-border-color: #eea236; + -fx-text-fill: white; +} +/*hover state*/ +.button.warning:hover,.menu-button.warning:hover,.toggle-button.warning:hover, +.split-menu-button.warning > .label:hover, .split-menu-button.warning > .arrow-button:hover { + -fx-border-color: #d58512; + -fx-background-color: #ec971f; +} +/*pressed selected*/ +.button.warning:pressed, .button.warning:selected, +.menu-button.warning:pressed,.menu-button.warning:selected +,.toggle-button.warning:pressed,.toggle-button.warning:selected, +.split-menu-button.warning:pressed > .label, .split-menu-button.warning > .arrow-button:pressed { + -fx-background-color: #ec971f; + -fx-border-color: #d58512; + -fx-effect: innershadow(gaussian, #d58512, 10, 0, 0, 3); +} + +/*danger*/ + +.button.danger,.split-menu-button.danger,.toggle-button.danger,.menu-button.danger, +.split-menu-button.danger > .label, .split-menu-button.danger > .arrow-button { + -fx-background-color: #d9534f; +} + +.button.danger,.menu-button.danger,.toggle-button.danger, +.split-menu-button.danger > .label,.split-menu-button.danger > .arrow-button { + -fx-border-color: #d43f3a; + -fx-text-fill: white; +} +/*hover state*/ +.button.danger:hover,.menu-button.danger:hover,.toggle-button.danger:hover, +.split-menu-button.danger > .label:hover, .split-menu-button.danger > .arrow-button:hover { + -fx-border-color: #ac2925; + -fx-background-color: #c9302c; +} +/*pressed selected*/ +.button.danger:pressed, .button.danger:selected, +.menu-button.danger:pressed,.menu-button.danger:selected +,.toggle-button.danger:pressed,.toggle-button.danger:selected, +.split-menu-button.danger:pressed > .label, .split-menu-button.danger > .arrow-button:pressed { + -fx-border-color: #ac2925; + -fx-background-color: #c9302c; + -fx-effect: innershadow(gaussian, #ac2925, 10, 0, 0, 3); +} + +.menu-item { + -fx-min-width: 200; +} + +.menu-item:focused { + -fx-background-color: #f5f5f5; +} + +.menu-item:focused > * { + -fx-text-fill: #262626; +} +.menu-item:focused .arrow { + -fx-background-color: #333333; +} + +.check-menu-item:checked:hover > .left-container > .check, +.check-menu-item:checked:focused > .left-container > .check, +.radio-menu-item:checked:hover > .left-container > .radio, +.radio-menu-item:checked:focused > .left-container > .radio { + -fx-background-color: #333333; +} + +.context-menu { + -fx-border-radius: 4; + -fx-background-radius: 4; + -fx-border-color: #bebec0; +} + +.context-menu > * { + -fx-padding: 5 0 5 0; +} + +.separator { + -fx-padding: 5 0 5 0; +} + +.text-field { + -fx-pref-height: 30; +} + +.combo-box, .choice-box { + -fx-background-insets: 0; + -fx-border-color: #cecece; + -fx-padding: -1; + -fx-border-width: 1; +} +.combo-box, .choice-box, .color-picker, .date-picker { + -fx-border-radius: 4; + -fx-background-radius: 4; + -fx-pref-height: 30; +} + +.combo-box:editable > .arrow-button { + -fx-background-color: white; +} + +.combo-box:editable > .arrow-button:hover { + -fx-background-color: #e6e6e6; +} + +.combo-box:editable > .arrow-button:pressed { + -fx-effect: innershadow(gaussian, #adadad, 10, 0, 0, 3); +} + +.combo-box > .text-input, .date-picker > .text-input { + -fx-background-radius: 4 0 0 4; + -fx-border-width: 0; +} + +.text-field, .text-area { + -fx-border-color: #cccccc; + -fx-background-color: white; + -fx-border-radius: 4; + -fx-background-radius: 4; + -fx-effect: innershadow(gaussian, transparent, 0, 0, 0, 0); +} + +.text-field:focused, .text-area:focused { + -fx-border-color: #66afe9; + -fx-effect: dropshadow(gaussian, #66afe9, 10, 0, 0, 0); +} + +.text-area .scroll-pane, .text-area .scroll-pane .content { + -fx-background-color: white; + -fx-background-radius: 4; +} + +.tab-pane .tab-header-background { + -fx-background-color: #f4f4f4; +} +.tab-pane.plain .tab-header-background { + -fx-background-color: transparent; +} + +.tab-pane .tab-header-area .tab { + -fx-border-radius: 4 4 0 0; + -fx-background-radius: 5 5 0 0; + -fx-background-color: transparent; + -fx-border-color: transparent; + -fx-padding: 3 10 5 10; + -fx-background-insets: 0; +} + +.tab-pane .tab-header-area .tab .tab-label { + -fx-text-fill: #337ab7; +} + +.tab-pane .tab-header-area .tab:hover { + -fx-background-color: #eeeeee; +} + +.tab-pane .tab-header-area .tab:selected { + -fx-focus-color: transparent; + -fx-border-color: #dddddd #dddddd white #dddddd; + -fx-background-color: white; +} +.tab-pane .tab-header-area .tab:selected .tab-label { + -fx-text-fill: #333333; +} +.tab-pane > .tab-content-area { + -fx-background-color: white; +} + +.tab-pane .tab-header-area .tab .tab-label { + -fx-focus-color: transparent; +} + +.tab-pane:focused > .tab-header-area > .headers-region > .tab:selected .focus-indicator { + -fx-border-color: transparent; +} + +.tab-pane > .tab-header-area > .headers-region > .tab > .tab-container > .tab-close-button { + -fx-background-color: #337ab7; +} +.tab-pane > .tab-header-area > .headers-region > .tab:selected > .tab-container > .tab-close-button { + -fx-background-color: #333333; +} +.tab-pane > .tab-header-area > .headers-region > .tab > .tab-container > .tab-close-button:hover { + -fx-background-color: red; + -fx-cursor: hand; +} + +.scroll-bar { + -fx-background-color: transparent; + -fx-background-radius: 0; + -fx-block-increment: 50; +} + +.corner { + -fx-background-color: transparent; +} + +.scroll-bar .decrement-button, .scroll-bar .decrement-arrow { + visibility: hidden; + -fx-pref-height: 1; + -fx-pref-width: 1; +} + +.scroll-bar .increment-button, .scroll-bar .increment-arrow { + visibility: hidden; + -fx-pref-height: 1; + -fx-pref-width: 1; +} + +.scroll-bar:vertical { + -fx-pref-width: 10; +} + +.scroll-bar:horizontal { + -fx-pref-height: 10; +} + +.scroll-bar:horizontal .track, +.scroll-bar:vertical .track { + -fx-background-color: transparent; + -fx-border-color: transparent; + -fx-background-radius: 5; +} + +.scroll-bar:vertical .track-background, +.scroll-bar:horizontal .track-background { + -fx-background-color: transparent; + -fx-background-insets: 0; + -fx-background-radius: 5; +} + +.scroll-bar:horizontal .thumb { + -fx-background-color: #c9c9c9; + -fx-background-insets: 2 0 2 0; + -fx-background-radius: 5; +} + +.scroll-bar:vertical .thumb { + -fx-background-color: #c9c9c9; + -fx-background-insets: 0 2 0 2; + -fx-background-radius: 5; +} + +.scroll-bar:horizontal .thumb:hover, +.scroll-bar:vertical .thumb:hover { + -fx-background-color: #b5b5b5; +} + +.scroll-bar:horizontal .thumb:pressed, +.scroll-bar:vertical .thumb:pressed { + -fx-background-color: #a0a0a0; +} + +.scroll-bar:vertical .increment-button, .scroll-bar:vertical .decrement-button { + -fx-background-color: transparent; + -fx-background-radius: 5; + -fx-padding: 5; +} + +.scroll-bar:horizontal .increment-button, .scroll-bar:horizontal .decrement-button { + -fx-background-color: transparent; + -fx-background-radius: 5; + -fx-padding: 5; +} + +.scroll-bar:vertical:focused, +.scroll-bar:horizontal:focused { + -fx-background-color: transparent, rgb(96, 96, 96), rgb(96, 96, 96); +} + +.menu-bar { + -fx-background-color: white; +} +.menu-bar > .container > .menu-button { + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-border-width: 0; + -fx-border-radius: 0; +} +.menu-bar > .container > .menu-button:hover, +.menu-bar > .container > .menu-button:showing { + -fx-background-color: #56c0e0; +} + +.color-palette { + -fx-background-color: white; +} + +.pagination > .pagination-control > .control-box { + -fx-spacing: -1; +} +.pagination > .pagination-control > .control-box > .left-arrow-button { + -fx-border-radius: 3 0 0 3; + -fx-border-insets: 0 0 0 7; + -fx-background-insets: 0 0 0 7, 0 0 0 5, 1 1 1 6, 2 2 2 7; +} +.pagination > .pagination-control > .control-box > .right-arrow-button { + -fx-border-radius: 0 3 3 0; + -fx-border-insets: 0 7 0 0; + -fx-background-insets: 0 7 -1 0, 0 5 0 0, 1 6 1 1, 2 7 2 2; +} +.pagination > .pagination-control > .control-box > .number-button { + -fx-background-radius: 0; + -fx-border-radius: 0; +} + +.progress-bar > .track { + -fx-pref-height: 10; + -fx-background-radius: 3; + -fx-effect: innershadow(gaussian, #e4e4e4, 4, 0, 0, 1); + -fx-background-color: #f5f5f5; +} + +.progress-bar > .bar { + -fx-background-insets: 0; + -fx-background-color: #337ab7; +} + +.progress-bar.success > .bar { + -fx-background-insets: 0; + -fx-background-color: #5cb85c; +} + +.progress-bar.info > .bar { + -fx-background-insets: 0; + -fx-background-color: #5bc0de; +} + +.progress-bar.warning > .bar { + -fx-background-insets: 0; + -fx-background-color: #f0ad4e +} + +.progress-bar.danger > .bar { + -fx-background-insets: 0; + -fx-background-color: #d9534f; +} + +.tooltip { + -fx-background: white; + -fx-text-fill: #333333; + -fx-background-color: white; + -fx-background-radius: 4px; + -fx-border-radius: 4px; + -fx-border-color: #C0C0C0; + -fx-background-insets: 0; + -fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */ + -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.5), 10, 0.0, 0, 3); + -fx-font-size: 0.85em; +} + +.tooltip.success { + -fx-background: #dff0d8; + -fx-background-color: #dff0d8; + -fx-text-fill: #99bb96; + -fx-border-color: #d6e9c6; +} + +.tooltip.info { + -fx-background: #d8ecf6; + -fx-background-color: #d8ecf6; + -fx-text-fill: #31708f; + -fx-border-color: #bce8f1; +} + +.tooltip.warning { + -fx-background: #fcf8e3; + -fx-background-color: #fcf8e3; + -fx-text-fill: #8a6e3c; + -fx-border-color: #faebcc; +} + +.tooltip.danger { + -fx-background: #f2dede; + -fx-background-color: #f2dede; + -fx-text-fill: #a94442; + -fx-border-color: #ebccd1; +} + +.titled-pane > .title { + -fx-background-color: #f5f5f5; + -fx-border-color: #dddddd; + /*-fx-background-insets: 5, 1, 5;*/ + -fx-background-radius: 3 3 0 0, 2 2 0 0, 1 1 0 0; + -fx-border-radius: 3 3 0 0, 2 2 0 0, 1 1 0 0; + -fx-padding: 11 +} + +.titled-pane > .content { + -fx-background-color: white; + -fx-background-radius: 0 0 4 4; + -fx-border-radius: 0 0 4 4; + -fx-border-color: #dddddd; + /*-fx-padding: -11;*/ +} + +.titled-pane.primary { + -fx-text-fill: white; +} + +.titled-pane.primary > .title { + -fx-background-color: #337ab7; + -fx-border-color: #337ab7; +} + +.titled-pane.primary > .content { + -fx-border-color: #337ab7; +} + +.titled-pane.success .arrow, +.titled-pane.info .arrow, +.titled-pane.warning .arrow, +.titled-pane.danger .arrow { + -fx-background-color: -fx-mark-highlight-color, -fx-mark-color; +} + +.titled-pane.success { + -fx-text-fill: #3c763d; +} + +.titled-pane.success > .title { + -fx-background-color: #dff0d8; + -fx-border-color: #d6e9c6; +} + +.titled-pane.success > .content { + -fx-border-color: #d6e9c6; +} + +.titled-pane.info { + -fx-text-fill: #31708f; +} + +.titled-pane.info > .title { + -fx-background-color: #d9edf7; + -fx-border-color: #bce8f1; +} + +.titled-pane.info > .content { + -fx-border-color: #bce8f1; +} + +.titled-pane.warning { + -fx-text-fill: #8a6d3b; +} + +.titled-pane.warning > .title { + -fx-background-color: #fcf8e3; + -fx-border-color: #faebcc; +} + +.titled-pane.warning > .content { + -fx-border-color: #faebcc; +} + +.titled-pane.danger { + -fx-text-fill: #a94442; +} + +.titled-pane.danger > .title { + -fx-background-color: #f2dede; + -fx-border-color: #eacbd0; +} + +.titled-pane.danger > .content { + -fx-border-color: #eacbd0; +} + +.accordion > .titled-pane > .title, +.accordion > .titled-pane > .content { + -fx-background-radius: 0; + -fx-border-radius: 0; +} + +.tool-bar:vertical { /* left */ + -fx-border-color: transparent #dddddd transparent transparent; +} + +.tool-bar { /* top */ + -fx-background-color: white; + -fx-border-color: transparent transparent #dddddd transparent; +} + +.tool-bar:vertical { + -fx-background-insets: 0, 0 1 0 0; +} + +/*table view columns*/ +.filler,.column-header,.show-hide-columns-button { + -fx-background-color: #dddddd, white, white; +} +.show-hide-columns-button { + -fx-border-width: 0; + -fx-background-insets: 0 0 1 1; +} +.column-header:hover,.show-hide-columns-button:hover { + -fx-background-color: #dddddd, white, #f8f8f8; +} +.column-header-background > .filler { + -fx-border-color: transparent #dddddd transparent transparent; + -fx-border-insets: 0 1 0 0; +} +.column-drag-header { + -fx-background-color: #2fb254; +} + +/*split pane*/ +.split-pane > .split-pane-divider { + -fx-background-color: white; + -fx-border-color: #eeeeee; + -fx-pref-width: 8; +} +.split-pane:horizontal > .split-pane-divider { + -fx-background-insets: 0, 0 1 0 1; + -fx-border-width: 0 1 0 1; +} +/* vertical the two nodes are placed on top of each other. */ +.split-pane:vertical > .split-pane-divider { + -fx-background-insets: 0, 1 0 1 0; + -fx-border-width: 1 0 1 0; +} +.split-pane > .split-pane-divider:hover { + -fx-background-color: #E0E0E0; +} + +/******************************************************************************* + * * + * CheckBox * + * * + ******************************************************************************/ +.check-box > .box { + -fx-background-radius: 3; + /*-fx-padding: 0.166667em 0.166667em 0.25em 0.25em; !* 2 2 3 3 *!*/ + -fx-padding:0; + -fx-border-color: #56c0e0; + -fx-border-radius: 3; + -fx-background-color: white; +} +.check-box > .box > .mark { + -fx-background-color: null; + -fx-padding: 0.416667em 0.416667em 0.5em 0.5em; /* 5 5 6 6 */ + -fx-shape: "M927.936 272.992l-68.288-68.288c-12.608-12.576-32.96-12.576-45.536 0l-409.44 409.44-194.752-196.16c-12.576-12.576-32.928-12.576-45.536 0l-68.288 68.288c-12.576 12.608-12.576 32.96 0 45.536l285.568 287.488c12.576 12.576 32.96 12.576 45.536 0l500.736-500.768c12.576-12.544 12.576-32.96 0-45.536z"; + -fx-background-insets: -3 -3 1 0; +} +.check-box { + -fx-label-padding: 0.2em 0.0em 0.3em 0.416667em; /* 0 0 0 5 */ + -fx-text-fill: -fx-text-background-color; + -fx-padding: 0 0 2 0; +} +.check-box:indeterminate > .box { + -fx-padding: 0; +} +.check-box:selected > .box > .mark { + -fx-background-color: linear-gradient(to bottom, #56c0e0, #40b8dc); +} + +/******************************************************************************* + * * + * RadioButton * + * * + ******************************************************************************/ + +.radio-button { + -fx-label-padding: 0.0em 0.0em 0.1em 0.416667em; /* 0 0 0 5 */ + -fx-text-fill: -fx-text-background-color; + -fx-padding: 0 0 .5 0; +} +.radio-button > .radio, +.radio-button:focused > .radio { + -fx-border-color: #56c0e0; + -fx-border-radius: 1em; + -fx-background-radius: 1.0em; /* large value to make sure this remains circular */ + -fx-padding: 1 2 3 2; + -fx-background-color: white; +} +.radio-button > .radio > .dot { + -fx-background-color: transparent; + -fx-background-radius: 1.0em; /* large value to make sure this remains circular */ + -fx-padding: 0.333333em; /* 4 -- radius of the inner black dot when selected */ + -fx-background-insets: 3 2 1 2; +} +.radio-button:selected > .radio,.radio-button:hover > .radio { + -fx-fill-color: #56c0e0; +} +.radio-button:pressed > .radio { + -fx-background-color: #50c0e2; +} +.radio-button:selected > .radio > .dot { + -fx-background-color: #56c0e0; +} + +/*common things*/ +.check-box:hover > .box, +.check-box:selected > .box, +.radio-button:hover > .radio, +.radio-button:selected > .radio { + -fx-background-color: linear-gradient(to bottom, white, #efefef); +} + +.check-box:pressed > .box, +.radio-button:pressed > .radio { + -fx-background-color: #50c0e2; +} \ No newline at end of file diff --git a/out/production/G-Earth2/main/ui/connection/Connection.fxml b/out/production/G-Earth2/main/ui/connection/Connection.fxml new file mode 100644 index 0000000..d4590b8 --- /dev/null +++ b/out/production/G-Earth2/main/ui/connection/Connection.fxml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out/production/G-Earth2/main/ui/connection/ConnectionForm.class b/out/production/G-Earth2/main/ui/connection/ConnectionForm.class new file mode 100644 index 0000000..588bd51 Binary files /dev/null and b/out/production/G-Earth2/main/ui/connection/ConnectionForm.class differ diff --git a/out/production/G-Earth2/main/ui/injection/Injection.fxml b/out/production/G-Earth2/main/ui/injection/Injection.fxml new file mode 100644 index 0000000..fda9bd9 --- /dev/null +++ b/out/production/G-Earth2/main/ui/injection/Injection.fxml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out/production/G-Earth2/main/ui/injection/InjectionForm.class b/out/production/G-Earth2/main/ui/injection/InjectionForm.class new file mode 100644 index 0000000..5279aef Binary files /dev/null and b/out/production/G-Earth2/main/ui/injection/InjectionForm.class differ diff --git a/out/production/G-Earth2/main/ui/logger/Logger.fxml b/out/production/G-Earth2/main/ui/logger/Logger.fxml new file mode 100644 index 0000000..d96cbcc --- /dev/null +++ b/out/production/G-Earth2/main/ui/logger/Logger.fxml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out/production/G-Earth2/main/ui/logger/LoggerForm.class b/out/production/G-Earth2/main/ui/logger/LoggerForm.class new file mode 100644 index 0000000..d13b757 Binary files /dev/null and b/out/production/G-Earth2/main/ui/logger/LoggerForm.class differ diff --git a/out/production/G-Earth2/main/ui/tools/Tools.fxml b/out/production/G-Earth2/main/ui/tools/Tools.fxml new file mode 100644 index 0000000..362b480 --- /dev/null +++ b/out/production/G-Earth2/main/ui/tools/Tools.fxml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out/production/G-Earth2/main/ui/tools/ToolsForm.class b/out/production/G-Earth2/main/ui/tools/ToolsForm.class new file mode 100644 index 0000000..c2c80ed Binary files /dev/null and b/out/production/G-Earth2/main/ui/tools/ToolsForm.class differ diff --git a/src/main/protocol/HConnection.java b/src/main/protocol/HConnection.java index a5b3319..6ce083c 100644 --- a/src/main/protocol/HConnection.java +++ b/src/main/protocol/HConnection.java @@ -1,6 +1,7 @@ package main.protocol; import main.OSValidator; +import main.protocol.memory.Rc4Obtainer; import main.protocol.packethandler.Handler; import main.protocol.packethandler.IncomingHandler; import main.protocol.packethandler.OutgoingHandler; @@ -126,10 +127,13 @@ public class HConnection { final boolean[] aborted = new boolean[1]; + Rc4Obtainer rc4Obtainer = new Rc4Obtainer(); + // wachten op data van client new Thread(() -> { try { OutgoingHandler handler = new OutgoingHandler(habbo_server_out); + rc4Obtainer.setOutgoingHandler(handler); while (!client.isClosed() && (state == State.WAITING_FOR_CLIENT || state == State.CONNECTED)) { byte[] buffer; @@ -179,6 +183,7 @@ public class HConnection { new Thread(() -> { try { IncomingHandler handler = new IncomingHandler(client_out); + rc4Obtainer.setIncomingHandler(handler); while (!habbo_server.isClosed() && (state == State.CONNECTED || state == State.WAITING_FOR_CLIENT)) { byte[] buffer; diff --git a/src/main/protocol/HPacket.java b/src/main/protocol/HPacket.java index a47dcdd..ade4ca2 100644 --- a/src/main/protocol/HPacket.java +++ b/src/main/protocol/HPacket.java @@ -21,12 +21,14 @@ public class HPacket { packetInBytes = fromStringToBytes(fromExpressionToString(packet)); } public HPacket(int header) { - packetInBytes = new byte[]{0,0,0,4,0,0}; + packetInBytes = new byte[]{0,0,0,2,0,0}; replaceUShort(4, header); + isEdited = false; } public HPacket(int header, byte[] bytes) { - packetInBytes = new byte[4]; + this(header); appendBytes(bytes); + isEdited = false; } public String toString() { diff --git a/src/main/protocol/crypto/RC4.java b/src/main/protocol/crypto/RC4.java index 1c67547..e062291 100644 --- a/src/main/protocol/crypto/RC4.java +++ b/src/main/protocol/crypto/RC4.java @@ -35,6 +35,10 @@ package main.protocol.crypto; import main.protocol.HPacket; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** * This is a simple implementation of the RC4 (tm) encryption algorithm. The * author implemented this class for some simple applications @@ -111,6 +115,17 @@ public class RC4 { } + public RC4(byte[] state, int x, int y) { + this.x = x; + this.y = y; + this.state = state; + } + + //copyconstructor + public RC4 deepCopy() { + return new RC4(Arrays.copyOf(state, 256), x, y); + } + /** * RC4 encryption/decryption. * @@ -169,36 +184,100 @@ public class RC4 { return result; } + public void undoRc4(byte[] buf) { + + byte tmp; + + for (int i = buf.length - 1; i >= 0; i--) { + + tmp = state[x]; + state[x] = state[y]; + state[y] = tmp; + + y = (y - (state[x] & 0xff)) & 0xff; + x = (x - 1) & 0xff; + } + + } + public void printKey() { System.out.println(new HPacket(state).toString()); } + + private static void printState(byte[] booleans) { + StringBuilder builder = new StringBuilder("state: "); + for (byte bool : booleans) { + builder.append(bool); + builder.append(","); + } + System.out.println(builder); + } + public static void main(String[] args) { + byte[] sharedKey = new byte[27]; - + List allbytesEncrypted = new ArrayList<>(); RC4 p1 = new RC4(sharedKey); - RC4 p2 = new RC4(sharedKey); - p1.printKey(); - p2.printKey(); - byte[] enc = p1.rc4("hallo".getBytes()); - System.out.println(new String(p2.rc4(enc))); + System.out.println("original:"); + printState(p1.state); + System.out.println("x: " + p1.x + ", y: " + p1.y); - p1.printKey(); - p2.printKey(); + byte[] enc1 = p1.rc4("hallo dit istoch wel redelijk veel tekst ofzo denk k".getBytes()); + for (int i = 0; i < enc1.length; i++) { + allbytesEncrypted.add(enc1[i]); + } - enc = p1.rc4("hallo".getBytes()); - System.out.println(new String(p2.rc4(enc))); + byte[] enc2 = p1.rc4("dit is ook redelijk wa tekst maar mag nog veel meer zijn eigelijk in principe hoor".getBytes()); + for (int i = 0; i < enc2.length; i++) { + allbytesEncrypted.add(enc2[i]); + } - p1.printKey(); - p2.printKey(); + System.out.println("-----------"); + System.out.println("after being sent:"); + printState(p1.state); + System.out.println("x: " + p1.x + ", y: " + p1.y); - enc = p1.rc4("meneeeer dit zijn echt veel meer dan 27 characters dus latne we dit even proberen".getBytes()); - System.out.println(new String(p2.rc4(enc))); - p1.printKey(); - p2.printKey(); + byte[] allencrypted = new byte[allbytesEncrypted.size()]; + for (int i = 0; i < allbytesEncrypted.size(); i++) { + allencrypted[i] = allbytesEncrypted.get(i); + } + + p1.undoRc4(allencrypted); + + System.out.println("-----------"); + System.out.println("after undo:"); + printState(p1.state); + System.out.println("x: " + p1.x + ", y: " + p1.y); + + +// byte[] sharedKey = new byte[27]; +// +// RC4 p1 = new RC4(sharedKey); +// RC4 p2 = new RC4(sharedKey); +// +// p1.printKey(); +// p2.printKey(); +// byte[] enc = p1.rc4("hallo".getBytes()); +// System.out.println(new String(p2.rc4(enc))); +// +// p1.printKey(); +// p2.printKey(); +// +// enc = p1.rc4("hallo".getBytes()); +// System.out.println(new String(p2.rc4(enc))); +// +// p1.printKey(); +// p2.printKey(); +// +// enc = p1.rc4("meneeeer dit zijn echt veel meer dan 27 characters dus latne we dit even proberen".getBytes()); +// System.out.println(new String(p2.rc4(enc))); +// +// p1.printKey(); +// p2.printKey(); } // public static void main(String[] args) { diff --git a/src/main/protocol/memory/FlashClient.java b/src/main/protocol/memory/FlashClient.java index fb06315..0276472 100644 --- a/src/main/protocol/memory/FlashClient.java +++ b/src/main/protocol/memory/FlashClient.java @@ -4,34 +4,15 @@ import main.irrelevant.Timer; import java.io.*; import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; public class FlashClient { - - public class MemorySnippet { - long offset; - byte[] data; - - public MemorySnippet(long offset, byte[] data) { - this.offset = offset; - this.data = data; - } - - public byte[] getData() { - return data; - } - - public long getOffset() { - return offset; - } - } - private int PID; private List maps; + private static final boolean DEBUG = false; + public static FlashClient create() { File folder = new File("/proc"); FlashClient client = null; @@ -52,7 +33,7 @@ public class FlashClient { } while (client == null); - System.out.println("* Found flashclient process: " + client.PID); + if (DEBUG) System.out.println("* Found flashclient process: " + client.PID); return client; } public void refreshMemoryMaps() { @@ -85,7 +66,7 @@ public class FlashClient { e.printStackTrace(); } - System.out.println("* Found memory maps (amount: " + maps.size() + ")"); + if (DEBUG) System.out.println("* Found memory maps (amount: " + maps.size() + ")"); } public List createMemorySnippetList () { @@ -102,254 +83,74 @@ public class FlashClient { return result; } public void fetchMemory(List snippets) { - String memoryPath = "/proc/" + PID + "/mem"; for (MemorySnippet snippet : snippets) { - long begin = snippet.offset; - try { - RandomAccessFile raf = new RandomAccessFile(memoryPath, "r"); - raf.seek(begin); - raf.read(snippet.getData()); - raf.close(); - } - catch (Exception e) { - e.printStackTrace(); - } + fetchMemory(snippet); } } - - /** - * can remove & add & edit maps of memorysnipperlist - */ - public void updateMapLocationsSnippetList(List snippets) { - refreshMemoryMaps(); - - List list2 = new ArrayList<>(); - List not_added = new ArrayList<>(); - - // readd all maps that stayed the same - for (long[] map : maps) { - //if was in snippetlist: - boolean found = false; - for (MemorySnippet snippet : snippets) { - if (snippet.offset == map[0] && snippet.offset + snippet.getData().length == map[1]) { - list2.add(snippet); - snippets.remove(snippet); - found = true; - break; - } - } - if (!found) { - not_added.add(map); - } - + public void fetchMemory(MemorySnippet snippet) { + String memoryPath = "/proc/" + PID + "/mem"; + long begin = snippet.offset; + try { + RandomAccessFile raf = new RandomAccessFile(memoryPath, "r"); + raf.seek(begin); + raf.read(snippet.getData()); + raf.close(); } - - for (int i = 0; i < not_added.size(); i++) { - long[] map = not_added.get(i); - //find potential overlap snippet - MemorySnippet snippet = new MemorySnippet(map[0], new byte[(int)(map[1] - map[0])]); - byte[] data = snippet.getData(); - - for (MemorySnippet potential : snippets) { - //if there is overlap - if ((potential.offset >= map[0] && potential.offset < map[1]) || - (potential.offset + potential.getData().length >= map[0] && potential.offset + potential.getData().length< map[1]) || - (potential.offset < map[0] && potential.offset + potential.getData().length >= map[1]) ) { - - int start = Math.max((int)(potential.offset - map[0]), 0); - int offset2 = -(int)(potential.offset - map[0]); - - for (int j = start; j < Math.min(map[1] - map[0], potential.getData().length - offset2); j++) { - data[j] = potential.getData()[j+offset2]; - } - } - } - list2.add(snippet); + catch (Exception e) { + e.printStackTrace(); } - - snippets.clear(); - for (MemorySnippet snippet : list2) { - snippets.add(snippet); - } - } - /** - * creates a new memorysnippet list of data that changed (or not) from the original list with a given left&right buffer - */ - public List differentiate(List original, boolean isChanged, int leftRightbytebuffer) { - //fill a new memorysnippet list with live data + public List differentiate2(List original, int minChangedBytes, int maxChangedBytes, int range) { List upToDate = new ArrayList<>(); for (MemorySnippet memorySnippet : original) { upToDate.add(new MemorySnippet(memorySnippet.getOffset(), new byte[memorySnippet.getData().length])); } fetchMemory(upToDate); - List result = new ArrayList<>(); - - long totalBytes = 0; - + Queue wachter = new LinkedList<>(); for (int i = 0; i < original.size(); i++) { - long offset = original.get(i).getOffset(); - byte[] old = original.get(i).getData(); - byte[] curr = upToDate.get(i).getData(); + wachter.clear(); + int wachtersize = 0; - if (!isChanged) { - // find all non-changed stuff and put in result - long pre = offset; - for (int j = 0; j < old.length; j++) { - if (old[j] != curr[j]) { - //calculate previous block length - int len = j - ((int)(pre - offset)); - if (len >= leftRightbytebuffer && len > 0) { - result.add(new MemorySnippet(pre, new byte[len])); - totalBytes += len; - } - pre = offset + j + 1; - } + MemorySnippet org = original.get(i); + byte[] orgdata = org.getData(); + MemorySnippet upd = upToDate.get(i); + byte[] upddata = upd.getData(); + + int curstartoffset = -1; + int lastendbuffer = -1; + + for (int p = 0; p < org.getData().length; p++) { + if (wachtersize > 0 && p == wachter.peek()) { + wachter.poll(); + wachtersize--; } - int len = old.length - ((int)(pre - offset)); - if (len >= leftRightbytebuffer && len > 0) { - result.add(new MemorySnippet(pre, new byte[len])); - totalBytes += len; + if (orgdata[p] != upddata[p]) { + wachter.add(p + range); + wachtersize++; + } + + if (p >= range - 1 && wachtersize >= minChangedBytes && wachtersize <= maxChangedBytes) { + if (curstartoffset == -1) { + curstartoffset = p - range + 1; + } + else if (lastendbuffer < p - range) { + MemorySnippet snippet = new MemorySnippet(curstartoffset + org.getOffset(), new byte[lastendbuffer - curstartoffset + 1]); + result.add(snippet); + curstartoffset = p - range + 1; + } + lastendbuffer = p; } } - else { - //find all changed stuff and put result - long pre = offset; - int downCount = -1; //if downCount reaches zero, buffer should be written out - for (int j = 0; j < old.length; j++) { - if (old[j] != curr[j]) { - if (downCount <= 0) { - pre = Math.max(offset, offset + j - leftRightbytebuffer); - } - downCount = leftRightbytebuffer; - } - else { downCount -= 1; } - if (downCount == 0) { - int len = j - ((int)(pre - offset)); - result.add(new MemorySnippet(pre, new byte[len])); - totalBytes += len; - } - } - int len = old.length - ((int)(pre - offset)); - if (downCount > 0 && len >= leftRightbytebuffer) { - result.add(new MemorySnippet(pre, new byte[len])); - totalBytes += len; - } + if (curstartoffset != -1) { + MemorySnippet snippet = new MemorySnippet(curstartoffset + org.getOffset(), new byte[lastendbuffer - curstartoffset + 1]); + result.add(snippet); } } fetchMemory(result); - - System.out.println("totalbytes after diff: " + totalBytes); - return result; } - //currently not being used functions: - List searchOffsetForByteArray(byte[] toFind) { - if (toFind.length == 0) return null; - - System.out.println("*** Start searching for: " + new String(toFind)); - String memoryPath = "/proc/" + PID + "/mem"; - List results = new ArrayList<>(); - - Timer t = new Timer(); - t.start(); - - for (long[] map : maps) { - long begin = map[0]; - long end = map[1]; - try { - RandomAccessFile raf = new RandomAccessFile(memoryPath, "r"); - byte[] wholeBuffer = new byte[(int)(end - begin)]; - raf.seek(begin); - raf.read(wholeBuffer); - raf.close(); - - for (int i = 0; i < wholeBuffer.length; i++) { - - int subIndex = 0; - while (subIndex < toFind.length && wholeBuffer[i + subIndex] == toFind[subIndex]) subIndex++; - - if (subIndex == toFind.length) { - long result = (long)i + begin; - results.add(result); - System.out.println("* Found match for " + new String(toFind) + " at address: " + result); - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - System.out.println("*** End searching for: " + new String(toFind) + " in " + t.delta() + "ms"); - return results; - } - List searchOffsetForString(String keyString) { - return searchOffsetForByteArray(keyString.getBytes()); - } - - public List findSharedKey (List snippets){ - - byte[] bounds = "09afAF".getBytes(); - - List results = new ArrayList<>(); - - int size = 54; - - for (MemorySnippet snippet : snippets) { - int count = 0; - byte[] data = snippet.getData(); - if (data.length >= size) { - for (int i = 0; i < data.length; i++) { - byte b = data[i]; - if ((b >= bounds[0] && b <= bounds[1]) || - (b >= bounds[2] && b <= bounds[3]) || - (b >= bounds[4] && b <= bounds[5])) { - count++; - } - else { - count = 0; - } - if (count == size && (i + 1 == data.length || !((data[i+1] >= bounds[0] && data[i+1] <= bounds[1]) || - (data[i+1] >= bounds[2] && data[i+1] <= bounds[3]) || - (data[i+1] >= bounds[4] && data[i+1] <= bounds[5]))) ) { - results.add(new String(Arrays.copyOfRange(data, i - size + 1, i + 1)) + " on location: " + (snippet.getOffset() + i)); - } - } - } - - } - return results; - } - - public List findSharedKey2() { - List memorySnippets = new ArrayList<>(); - - int buff = 15000000; - - long verystart = maps.get(0)[0]; - long veryend = maps.get(0)[1]; - - for (int i = 1; i < maps.size(); i++) { - long[] map = maps.get(i); - if (map[1] - veryend <= buff) { - veryend = map[1]; - } - else { - memorySnippets.add(new MemorySnippet(verystart, new byte[(int)(veryend - verystart + buff)])); - verystart = maps.get(i)[0]; - veryend = maps.get(i)[1]; - } - } - memorySnippets.add(new MemorySnippet(verystart, new byte[(int)(veryend - verystart + buff)])); - - fetchMemory(memorySnippets); - return findSharedKey(memorySnippets); - } - - @SuppressWarnings("Duplicates") public void pauseProcess() { String[] args = new String[] {"kill", "-STOP", PID+""}; @@ -401,10 +202,8 @@ public class FlashClient { // client.updateMapLocationsSnippetList(l); - List res = client.findSharedKey2(); - System.out.println(res); - System.out.println("test"); } + } diff --git a/src/main/protocol/memory/MemorySnippet.java b/src/main/protocol/memory/MemorySnippet.java new file mode 100644 index 0000000..aca539a --- /dev/null +++ b/src/main/protocol/memory/MemorySnippet.java @@ -0,0 +1,19 @@ +package main.protocol.memory; + +public class MemorySnippet { + long offset; + byte[] data; + + public MemorySnippet(long offset, byte[] data) { + this.offset = offset; + this.data = data; + } + + public byte[] getData() { + return data; + } + + public long getOffset() { + return offset; + } +} diff --git a/src/main/protocol/memory/Rc4Obtainer.java b/src/main/protocol/memory/Rc4Obtainer.java index 6e734e3..5358119 100644 --- a/src/main/protocol/memory/Rc4Obtainer.java +++ b/src/main/protocol/memory/Rc4Obtainer.java @@ -2,33 +2,34 @@ package main.protocol.memory; import javafx.application.Platform; import main.protocol.HPacket; +import main.protocol.crypto.RC4; import main.protocol.packethandler.BufferListener; import main.protocol.packethandler.IncomingHandler; import main.protocol.packethandler.OutgoingHandler; import main.protocol.memory.FlashClient; +import java.util.Arrays; import java.util.List; +import java.util.Random; public class Rc4Obtainer { - public static Rc4Obtainer rc4Obtainer = null; - public static void initialize() { - rc4Obtainer = new Rc4Obtainer(); - rc4Obtainer.client = FlashClient.create(); - } + public static final boolean DEBUG = false; FlashClient client = null; OutgoingHandler outgoingHandler = null; IncomingHandler incomingHandler = null; - private Rc4Obtainer() { - + public Rc4Obtainer() { + client = FlashClient.create(); } + + private boolean hashappened1 = false; public void setOutgoingHandler(OutgoingHandler handler) { outgoingHandler = handler; - handler.addBufferListener(() -> { - if (handler.getCurrentIndex() >= 3) hasChangedFromLastCheck = true; + handler.addBufferListener((int addedbytes) -> { + if (handler.getCurrentIndex() >= 3) this.addedBytes += addedbytes; if (!hashappened1 && handler.getCurrentIndex() == 3) { hashappened1 = true; onSendFirstEncryptedMessage(); @@ -38,91 +39,182 @@ public class Rc4Obtainer { public void setIncomingHandler(IncomingHandler handler) { incomingHandler = handler; - handler.addBufferListener(() -> { - if (!hashappened2 && handler.getCurrentIndex() == 1) { - hashappened2 = true; - onReceivePubKey(); - } - }); } - private List fullmemorybeforekey = null; - private boolean hasChangedFromLastCheck = false; - - private boolean hashappened2 = false; - private void onReceivePubKey() { - incomingHandler.block(); - new Thread(() -> { - - System.out.println("[+] receive pubkey"); - client.pauseProcess(); - - fullmemorybeforekey = client.createMemorySnippetList(); - client.fetchMemory(fullmemorybeforekey); - - System.out.println("[-] receive pubkey"); - - client.resumeProcess(); - incomingHandler.unblock(); - }).start(); - } - - - private boolean hashappened1 = false; + private volatile int addedBytes = 0; private void onSendFirstEncryptedMessage() { incomingHandler.block(); outgoingHandler.block(); new Thread(() -> { - System.out.println("[+] send encrypted"); - client.pauseProcess(); - client.updateMapLocationsSnippetList(fullmemorybeforekey); - client.resumeProcess(); + if (DEBUG) System.out.println("[+] send encrypted"); + sleep(20); - List diff = searchForPossibleRC4Tables(fullmemorybeforekey); - System.out.println("size: " + getTotalBytesLengthOfDiff(diff)); - for (int i = 0; i < 20; i++) { -// if (i % 2 == 1) { -// incomingHandler.sendToStream(new HPacket(3631).toBytes()); -// } - sleep(200); - boolean rem = hasChangedFromLastCheck; - diff = searchForPossibleRC4Tables(diff); - System.out.println("size: " + getTotalBytesLengthOfDiff(diff) + " and was changed: " + rem); + List diff = null; + + + // STEP ONE: filtering to obtain one area containing the rc4 data field + int foundbuffersize = 0; + while (foundbuffersize == 0) { + client.pauseProcess(); + diff = client.createMemorySnippetList(); + client.fetchMemory(diff); + client.resumeProcess(); + this.addedBytes = 0; + + Random rand = new Random(); + + if (DEBUG) System.out.println("size: " + getTotalBytesLengthOfDiff(diff)); + int i = 0; + while (getTotalBytesLengthOfDiff(diff) > 2000) { + int am = 0; + if (i % 2 == 1) { + am = rand.nextInt(30) + 1; + for (int j = 0; j < am; j++) { + incomingHandler.sendToStream(new HPacket(3794).toBytes()); + outgoingHandler.fakePongAlert(); + sleep(20); + } + } + sleep(50); + int rem = addedBytes; + diff = searchForPossibleRC4Tables(diff); + if (DEBUG) System.out.println("size: " + getTotalBytesLengthOfDiff(diff) + " with changed bytes: " + rem + " should be: " + am * 6); + i++; + } + + foundbuffersize = (int)getTotalBytesLengthOfDiff(diff); } - System.out.println("[-] send encrypted"); + + + + //diff should only have one element now + // STEP TWO: obtain the exactly the 256 needed bytes + //research shows that this equals the first occurence of a number followed by 3 zeros is the start + //if that number accidentally is zero it won't work so fuck that - cry - + MemorySnippet snippet = diff.get(0); + byte[] wannabeRC4data = snippet.getData(); + int result_start_index = -1; + for (int i = 0; i < snippet.getData().length - 3; i++) { + if (wannabeRC4data[i] != 0 && wannabeRC4data[i+1] == 0 && wannabeRC4data[i+2] == 0 && wannabeRC4data[i+3] == 0) { + result_start_index = i; + if (DEBUG) System.out.println(result_start_index); + break; + } + } + + byte[] data = new byte[256]; // dis is the friggin key + for (int i = 0; i < 256; i++) data[i] = wannabeRC4data[i*4 + result_start_index]; + + if (DEBUG) printByteArray(data); + + + + + + // STEP 3: find the i & j values (in our RC4 class called x & y) + // this goes together with the verification of this actually being the right RC4 table + + MemorySnippet snippet1 = new MemorySnippet(snippet.getOffset(), new byte[snippet.getData().length]); + client.fetchMemory(snippet1); + incomingHandler.sendToStream(new HPacket(3794).toBytes()); + outgoingHandler.fakePongAlert(); + sleep(70); + + byte[] data1 = new byte[256]; + for (int i = 0; i < 256; i++) data1[i] = snippet1.getData()[i*4 + result_start_index]; + + byte[] lastPongPacket = new byte[6]; + List encodedbytelistraw = outgoingHandler.getEncryptedBuffer(); + for (int i = 0; i < 6; i++) { + lastPongPacket[i] = encodedbytelistraw.get(encodedbytelistraw.size() - 6 + i); + } + + RC4 result = null; + + //dont panic this runs extremely fast xo + outerloop: + for (int x = 0; x < 256; x++) { + for (int y = 0; y < 256; y++) { + byte[] copy = new byte[256]; + for (int i = 0; i < 256; i++) { + copy[i] = data1[i]; + } + RC4 rc4Tryout = new RC4(copy, x, y); + + HPacket tryout = new HPacket(rc4Tryout.rc4(lastPongPacket)); + if (!tryout.isCorrupted()) { + result = rc4Tryout; + break outerloop; + } + } + } + + + + // STEP FOUR: undo all sent packets in the rc4 stream + List enbuf = outgoingHandler.getEncryptedBuffer(); + byte[] encrbuffer = new byte[enbuf.size()]; + for (int i = 0; i < enbuf.size(); i++) { + encrbuffer[i] = enbuf.get(i); + } + + result.undoRc4(encrbuffer); + + + // STEP FIVE: set the rc4 stream + + if (result != null) { + outgoingHandler.setRc4(result); + } + else { + System.err.println("Did not find RC4 stream"); + } + + if (DEBUG) System.out.println("[-] send encrypted"); outgoingHandler.unblock(); incomingHandler.unblock(); }).start(); - - } - private List searchForPossibleRC4Tables(List snippets) { - List result; + + + + + private List searchForPossibleRC4Tables(List snippets) { + List result; client.pauseProcess(); - if (hasChangedFromLastCheck) { - result = client.differentiate(snippets, true, 255); - hasChangedFromLastCheck = false; - } - else { - result = client.differentiate(snippets, false, 4); - } + result = client.differentiate2(snippets, ((addedBytes * 2) / 3), addedBytes * 2, 1028); + addedBytes = 0; client.resumeProcess(); return result; } - private long getTotalBytesLengthOfDiff(List snippets) { + private void printBooleanArray(boolean[] booleans) { + StringBuilder builder = new StringBuilder(); + for (boolean bool : booleans) { + builder.append(bool ? "1" : "0"); + } + System.out.println(builder); + } + private void printByteArray(byte[] booleans) { + StringBuilder builder = new StringBuilder(); + for (byte bool : booleans) { + builder.append(bool); + builder.append(","); + } + System.out.println(builder); + } + private long getTotalBytesLengthOfDiff(List snippets) { long tot = 0; - for (FlashClient.MemorySnippet snippet : snippets) { + for (MemorySnippet snippet : snippets) { tot += (snippet.getData().length); } return tot; } - private void sleep(int ms) { try { Thread.sleep(ms); diff --git a/src/main/protocol/packethandler/BufferListener.java b/src/main/protocol/packethandler/BufferListener.java index 1a459fb..8e346f6 100644 --- a/src/main/protocol/packethandler/BufferListener.java +++ b/src/main/protocol/packethandler/BufferListener.java @@ -3,6 +3,6 @@ package main.protocol.packethandler; public interface BufferListener { - void act(); + void act(int addedbytes); } diff --git a/src/main/protocol/packethandler/Handler.java b/src/main/protocol/packethandler/Handler.java index 054368e..638eb21 100644 --- a/src/main/protocol/packethandler/Handler.java +++ b/src/main/protocol/packethandler/Handler.java @@ -12,8 +12,8 @@ public abstract class Handler { volatile PayloadBuffer payloadBuffer = new PayloadBuffer(); volatile OutputStream out; - private volatile Object[] listeners = null; //get notified on packet send - private volatile boolean isTempBlocked = false; + volatile Object[] listeners = null; //get notified on packet send + volatile boolean isTempBlocked = false; volatile boolean isDataStream = false; volatile int currentIndex = 0; @@ -32,16 +32,11 @@ public abstract class Handler { if (isDataStream) { payloadBuffer.push(buffer); - notifyBufferListeners(); + notifyBufferListeners(buffer.length); if (!isTempBlocked) { flush(); } - else { - if (this instanceof OutgoingHandler) { - System.out.println("blocked outgoing bytes with size: "+ buffer.length); - } - } } else { out.write(buffer); @@ -88,9 +83,9 @@ public abstract class Handler { public void removeBufferListener(BufferListener listener) { bufferListeners.remove(listener); } - private void notifyBufferListeners() { + void notifyBufferListeners(int addedbytes) { for (int i = bufferListeners.size() - 1; i >= 0; i -= 1) { - bufferListeners.get(i).act(); + bufferListeners.get(i).act(addedbytes); } } diff --git a/src/main/protocol/packethandler/IncomingHandler.java b/src/main/protocol/packethandler/IncomingHandler.java index b830469..ae17a1c 100644 --- a/src/main/protocol/packethandler/IncomingHandler.java +++ b/src/main/protocol/packethandler/IncomingHandler.java @@ -13,34 +13,35 @@ public class IncomingHandler extends Handler { super(outputStream); } - @Override - public void setAsDataStream() { - super.setAsDataStream(); - Rc4Obtainer.rc4Obtainer.setIncomingHandler(this); - } + private final Object lock = new Object(); @Override public void sendToStream(byte[] buffer) { - try { - out.write(buffer); - out.flush(); - } catch (IOException e) { - e.printStackTrace(); + synchronized (lock) { + try { + out.write(buffer); + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + } } } @Override public void flush() throws IOException { - HPacket[] hpackets = payloadBuffer.receive(); + synchronized (lock) { + HPacket[] hpackets = payloadBuffer.receive(); - for (HPacket hpacket : hpackets){ - HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOCLIENT, currentIndex); - notifyListeners(hMessage); + for (HPacket hpacket : hpackets){ + HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOCLIENT, currentIndex); + notifyListeners(hMessage); - if (!hMessage.isBlocked()) { - out.write(hMessage.getPacket().toBytes()); + if (!hMessage.isBlocked()) { + out.write(hMessage.getPacket().toBytes()); + } + currentIndex++; } - currentIndex++; } + } } diff --git a/src/main/protocol/packethandler/OutgoingHandler.java b/src/main/protocol/packethandler/OutgoingHandler.java index ba83af8..a5938d0 100644 --- a/src/main/protocol/packethandler/OutgoingHandler.java +++ b/src/main/protocol/packethandler/OutgoingHandler.java @@ -2,14 +2,23 @@ package main.protocol.packethandler; import main.protocol.HMessage; import main.protocol.HPacket; +import main.protocol.crypto.RC4; import main.protocol.memory.Rc4Obtainer; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; public class OutgoingHandler extends Handler { + private final Object lock = new Object(); + + private final static int encryptOffset = 3; //all packets with index < 3 aren't encrypted + private RC4 clientcipher = null; + private RC4 servercipher = null; + private List tempEncryptedBuffer = new ArrayList<>(); public OutgoingHandler(OutputStream outputStream) { super(outputStream); @@ -19,49 +28,101 @@ public class OutgoingHandler extends Handler { if (!isDataStream) { HPacket hpacket = new HPacket(buffer); isDataStream = (hpacket.getBytesLength() > 6 && hpacket.headerId() == 4000 && hpacket.headerId() == 4000); - if (isDataStream) { - Rc4Obtainer.initialize(); - Rc4Obtainer.rc4Obtainer.setOutgoingHandler(this); - } } } @Override public void act(byte[] buffer, Object[] listeners) throws IOException { dataStreamCheck(buffer); - super.act(buffer, listeners); + this.listeners = listeners; + + if (isDataStream) { + + if (currentIndex < encryptOffset) { + payloadBuffer.push(buffer); + } + else if (clientcipher == null) { + for (int i = 0; i < buffer.length; i++) { + tempEncryptedBuffer.add(buffer[i]); + } + } + else { + payloadBuffer.push(clientcipher.rc4(buffer)); + } + + notifyBufferListeners(buffer.length); + + if (!isTempBlocked) { + flush(); + } + } + else { + out.write(buffer); + } } @Override public void sendToStream(byte[] buffer) { + synchronized (lock) { + try { + out.write(servercipher.rc4(buffer)); + out.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } } + public void setRc4(RC4 rc4) { + this.clientcipher = rc4; + this.servercipher = rc4.deepCopy(); + + byte[] encrbuffer = new byte[tempEncryptedBuffer.size()]; + for (int i = 0; i < tempEncryptedBuffer.size(); i++) { + encrbuffer[i] = tempEncryptedBuffer.get(i); + } + + try { + act(encrbuffer, this.listeners); + } catch (IOException e) { + e.printStackTrace(); + } + tempEncryptedBuffer = null; + } + public List getEncryptedBuffer() { + return tempEncryptedBuffer; + } + + + //as pings & pongs are used in order to find the RC4 table, we really don't want it to be displayed + //or even be sent to the server, we can fix that by calling this method everytime we fakesend a ping + private int skipPongAmount = 0; + public void fakePongAlert() { + skipPongAmount ++; + } + @Override public void flush() throws IOException { - - if (currentIndex < encryptOffset) { + synchronized (lock) { HPacket[] hpackets = payloadBuffer.receive(); for (HPacket hpacket : hpackets){ + if (skipPongAmount > 0 && hpacket.length() == 2) { + skipPongAmount --; + continue; + } + HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOSERVER, currentIndex); notifyListeners(hMessage); if (!hMessage.isBlocked()) { - out.write(hMessage.getPacket().toBytes()); + out.write( + currentIndex < encryptOffset ? hMessage.getPacket().toBytes() : + servercipher.rc4(hMessage.getPacket().toBytes()) + ); } currentIndex ++; } } - if (currentIndex >= encryptOffset) { - if (payloadBuffer.peak().length > 0) { - HPacket packet = new HPacket(payloadBuffer.forceClear()); - HMessage hMessage = new HMessage(packet, HMessage.Side.TOSERVER, currentIndex); - - notifyListeners(hMessage); - out.write(packet.toBytes()); - currentIndex++; - } - - } } }