【问题标题】:Aligning lists of structs for patch analysis对齐结构列表以进行补丁分析
【发布时间】:2021-10-31 03:22:57
【问题描述】:

我目前正在对定期更新的多人游戏进行逆向工程。网络协议使用自定义序列化框架,我现在能够恢复有关正在交换的消息的大量信息。对于每条消息,我可以检索所述消息的完整结构和该消息的类型(例如,身份验证、聊天、移动......)。但是,我遇到的一个问题是消息和消息类型会定期添加和删除,并且消息可能会添加或删除字段。 消息和消息类型的整体顺序保持不变

我现在正在寻找一种如何最好地利用我必须将更新的消息结构与我已经确定了一些消息和字段的含义的旧消息结构相匹配的信息的方法。也就是说,给定如下两组消息,我如何传输已经逆向工程的信息(新消息中的 cmets)?

旧消息:

Authentication:
 message Login:
  opcode: 1
  fields:
  - string mail
  - string password

 message LoginResponse:
  opcode: 2
  fields:
  - string token

Chat:
 message ChatSend:
  opcode: 3
  fields:
  - string channel
  - string message
 message ChatReceive:
  opcode: 4
  fields:
  - string channel
  - string user
  - string message

新消息:

Type1: # Authentication
 message Unk1: # Login
  opcode: 1
  fields:
  - string unk1 # mail
  - string unk2 # password
  _ string unk3 # new field
  
 message Unk2: # LoginResponse
  opcode: 2
  fields:
  - string unk1 # token

Type2: # new Type
  message Unk3:
   opcode: 3
   fields:
   - Vec3 unk1
   - float unk2

Type3: # Chat
 message Unk4: # ChatSend
  opcode: 4
  fields:
  - string unk1 # channel
  - string unk2 # message
 message Unk5: # new message
  opcode: 5
  fields:
  - string unk1
  - string unk2
 message Unk6: # ChatReceive
  opcode: 6
  fields:
  - string unk1 # channel
  - string unk2 # user
  - string unk3 # message

一些附加信息:大约有 60 种不同类型的消息,每种消息类型最多有大约 100 条消息。我也欢迎使用伪代码或 python 的解决方案。

【问题讨论】:

标签: python reverse-engineering sequence-alignment


【解决方案1】:

更好、更可持续的解决方案是重新设计生成消息的系统,使其与名称和格式保持一致。这将使其更具可扩展性。

如果这真的不是一个选项,这里有一个可能的算法,您可能想通过使用诸如Levenshtein 之类的库计算字符串差异来探索。在这里,让我们关注最外层的数据(类型)。只需对内部数据(消息和字段)执行相同的概念。

假设这些是旧消息和新消息中的类型之间的匹配:

Old Messages New Messages Remarks
O1 N1
N2 new
N3 new
O2 N4
O3 N5
O4 deleted
O5 deleted
N6 new
O6 N7
N8 new

地点:

  • 旧消息的示例,例如O1:
Authentication:
 message Login:
  opcode: 1
  fields:
  - string mail
  - string password
  • 新消息的示例,例如N1:
Type1:
 message Unk1:
  opcode: 1
  fields:
  - string unk1
  - string unk2
  - string unk3

对于每条旧消息,计算到每条新消息的 Levenshtein 距离并选择最小的距离。最小的距离表示它是最接近的等效字符串。假设下面的数字是每个 Ox 的计算距离:Ny

O# N1 N2 N3 N4 N5 N6 N7 N8 Smallest Distance
O1 3 10 7 11 14 8 5 12 N1
O2 8 9 6 2 9 7 8 17 N4
O3 9 7 7 9 3 13 7 6 N5
O4 7 9 8 15 16 6 3 10 N7
O5 5 7 9 8 11 4 10 5 N6
O6 9 6 7 8 8 14 1 11 N7

但是由于消息的顺序保持不变,O4 映射到 N7O5 映射到更早的 N6 是错误的。 O6 也是错误的,因为它映射到相同的 N7。现在我们必须在选择最小距离之前执行额外的步骤

  • 检查较早的O 是否映射到等于或晚于当前选择的NN,例如这是O5 映射到N6,而早期的O4 映射到后来的N7
    • 如果有,请检查之前的O 中的所有 是否比当前N 更接近映射的N
      • 如果所有早期的O 都更接近他们的N,那么我们无法更改它,因为它的相似性比当前的更接近。相反,我们会尝试选择到当前O 的第二小距离并重复相同的步骤。
      • 但是,如果当前O 比之前的任何O 映射到它们各自的N 更接近当前选择的N,那么我们将为当前N 选择当前选择的@987654354 @。然后我们会将所有使用相同或更高N 的早期O 标记为已删除。

通过这些额外的步骤,更新后的表格将是:

O# N1 N2 N3 N4 N5 N6 N7 N8 Smallest Distance
O1 3 10 7 11 14 8 5 12 N1
O2 8 9 6 2 9 7 8 17 N4
O3 9 7 7 9 3 13 7 6 N5
O4 7 9 8 15 16 6 3 10 N7 Deleted
O5 5 7 9 8 11 4 10 5 N6 N8 Deleted
O6 9 6 7 8 8 14 1 11 N7

如您所见,O5 已从 N6(距离为 4)重新映射到 N8(距离为 5),因为O4 使用了后来的N7。但是随后两者都被标记为已删除,因为O6 被映射到N7,它更接近(距离为1)更早的O,它使用等于或晚于N7N(即O4O5)。

现在,我们知道了:

  • O1N1
  • O2N4
  • O3N5
  • O4 已删除
  • O5 已删除
  • O6N7
  • 虽然所有未选择的N都是新添加的,即N2N3N6N8

【讨论】:

  • 嗯,是的,这也接近我的想法。使消息更加一致是什么意思?整个问题是我无法控制消息的结构并且名称不可用。但是,我可以将结构转储为您认为可能更容易使用的任何格式。我只是为了可读性选择了 yaml。
  • “重新设计产生消息的系统,使其与名称和格式保持一致”这是为了进行逆向工程,当然它不会被格式化 :D 很抱歉造成混乱。然后,似乎您使用 YAML 是最好的选择。使用 JSON 会添加额外的字符进行比较,因此可能会增加复杂性,具体取决于算法:)
猜你喜欢
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
  • 1970-01-01
  • 2022-10-07
  • 2019-02-08
相关资源
最近更新 更多