逆向工程java序列化

时间:2012-09-06 22:18:27

标签: java serialization deserialization

首先让我解释一下我们的项目。

我们有一个客户端服务器系统。客户端和服务器都是用java实现的。我们在C中重新实现客户端,保持接口相同并使服务器保持在java中。

客户端和服务器通过java动态代理进行通信的方式是remoteid是网络连接。现在,客户端调用在服务器上调用的方法。显然序列化和反序列化正在进行中。我想实现服务器在C中所期望的相同格式。作为一名C黑客我通过wireshark打开数据包并开始在java代码中映射实际字节,这对我没什么帮助。我无法在代码中映射的字节很少(显然我没有查看正确的代码)。

我还没有完全理解java动态代理是否使用其库自动序列化,或者您是否需要在类中实现某些函数,以便可以将内容写入线路。

有人能建议我采用更人性化的方法解决这个问题吗?

PS:我对java编程不是很了解。

5 个答案:

答案 0 :(得分:1)

我是Google Protocol Buffers的粉丝,用于维护跨语言兼容的序列化界面。您以相当简单的格式编写消息格式,protoc生成您希望用于消息对象的任何语言的代码并兼容地序列化它们。 (它也非常擅长确保您可以在不破坏所有内容的情况下添加更多字段,这对于轻松维护事物非常重要。)

默认情况下它只处理Java,C ++和Python,但是C plugins exist

答案 1 :(得分:1)

  

我想实现服务器在C中所期望的相同格式。

忘了它。这基本上是不可能的,除非你手头有一个JVM为你做。任何Java类都可以定义自己的序列化格式,JDK中的许多都可以这样做。

考虑另一个协议,或忘记在C中重新实现客户端。无论如何,目的是什么?一般是逆行步骤。

答案 2 :(得分:0)

我建议使用像Thrift这样的东西。通过在C中重新实现Java序列化,您可以轻松实现,如果它可以在您的测试环境中运行 - 它可能会在现实世界中的真实数据上失败。

答案 3 :(得分:0)

正如其中一条评论建议的那样 - 我建议你切换协议。
java.lang.reflect.Proxy本身只是一个调用的拦截器。我想InvocationHandler是执行实际通信的那个。
当使用例如REST框架时,许多实现让客户端决定它想要哪种格式的响应--JSON,XML或其他。
在服务器端,有些类负责根据请求的格式“呈现”结果。
我建议你实现一个区分C客户端和java客户端的机制,并且基于客户端类型将使用正确的“请求解析器”和“响应编写器”
这样,您还可以实现与现有Java客户端的向后兼容性

另一种选择当然是使用相同的协议,并决定更改现有的Java客户端,
在此选项中,您可以使用DataInputStream和DataOutputStream从Stream读取和写入数据,该数据不仅仅是字节数组或单个字节。
我认为通过使用wireshark的一些实验,您将了解正确的字节对齐,例如写入Long值的情况。
我过去使用过已经成功实现了协议读写器 DataInputStream和DataOutputStream,其中客户端不仅仅是Java(例如 - 我们有一个iOS / objective-C客户端)。

答案 4 :(得分:0)

任何实现Serializable接口的Java类都使用指定的序列化协议(带有BNF语法):https://docs.oracle.com/javase/8/docs/platform/serialization/spec/protocol.html

如果您习惯编写解析器,您绝对可以在C中实现此语法,并使用它来反序列化和重新序列化Java对象。