【问题标题】:How would I reverse this simple-looking algorithm?我将如何反转这个看起来很简单的算法?
【发布时间】:2016-07-09 12:52:34
【问题描述】:

我有一些旧的 LED 板,您可以向其发送一些文本并将其挂在某个地方...它是 1994/95 年制造的,它通过串行端口进行通信,带有一个 16 位 MS-DOS 应用程序您可以输入一些文本。

所以,因为除了使用 DOSBox 或类似的技巧你可能无法在任何地方运行它,我决定用 C# 重写它。

在对原始 dos-exe 进行端口监控后,我发现它对你重建它真的不感兴趣 - 必须以合适的方式回答请求、不同的字节、预先发送的“ping”消息等......

也许您知道我的 dos-exe 使用的类似校验和例程/模式,或者您可以提供任何尝试逆向工程的提示...此外,因为我只熟悉编程并且没有花太多时间关于反转方法和/或分析协议,如果这个话题有点愚蠢,请不要评判我 - 我会很高兴得到任何帮助......

真正包含应该显示的文本的消息是 143 字节长(之所以这么长,是因为如果您没有用完文本的所有空间,它会放置填充字节),并且在该消息我注意到以下模式:

  • 第四个字节(仍属于 msg 标头)不同于 6 或 7 个重复值的列表(在我的示例中,该字节始终为 0F)。

  • 最后两个字节用作校验和

一些例子

  • 显示文本:“123”(十六进制:“31 32 33”),校验和十六进制:“45 52”
  • 文本:“132”(“31 33 32”),十六进制校验和:“55 FF”
  • 文本:“122”(“31 32 32”),十六进制校验和:“95 F4”
  • 文本:“133”(“31 33 33”),十六进制校验和:“85 59”
  • 文本:“112”(“31 31 32”),十六进制校验和:“C5 C8”
  • 文本:“124”(“31 32 34”),十六进制校验和:“56 62”
  • 文本:“134”(“31 33 34”),十六进制校验和:“96 69”
  • 文本:“211”(“32 31 31”),十六进制校验和:“5D 63”
  • 文本:“212”(“32 31 32”),十六进制校验和:“3C A8”
  • 文本:{empty},十六进制校验和:“DB BA”
  • 文本:“1”(“31”),十六进制校验和:“AE 5F”

到目前为止,我完全确定校验和确实取决于标头中的第四个字节,因为如果它发生变化,对于要显示的相同文本,校验和将完全不同。

这是一个完整的 143 字节字符串显示“123”的示例,只是为了给您一个更好的方向:

02 86 04 0F 05 03 01 03 01 03 01 03 00 01 03 00   ...............
00 31 00 32 00 33 00 20 00 20 00 20 00 20 00 20   .1.2.3. . . . . 
00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20   . . . . . . . . 
00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20   . . . . . . . . 
00 20 00 20 00 20 00 20 00 20 00 FE 03 01 03 01   . . . . . .þ....
04 01 03 00 01 03 00 00 20 00 20 00 20 00 20 00   ........ . . . .
20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00    . . . . . . . .
20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00    . . . . . . . .
20 00 20 00 20 00 20 00 20 00 20 00 20 45 52

(文本信息从第2行第2个字节开始"31 00 32 00 33 00 (...)"

不幸的是,在整个网络上,没有用户手册、文档,甚至没有真正的证据表明这种信息板设备曾经存在过。

【问题讨论】:

  • 嗯,你的问题是?第 4 个字节的值从何而来?他们使用的是哪种类型的校验和(或 CRC)?
  • 谷歌搜索“checksum algorithm”和“checksum online”。如果幸运的话,您会找到使用过的那个。
  • 可能是摩托罗拉 S 格式。第一个字节 02 表示数据是两个字节。它始于 70 年代 S1(一个字节),然后是 S2(两个字节),最后是 S4(四个字节)。见网页amelek.gda.pl/avr/uisp/srecord.htm
  • @jdweng 非常感谢!就一件事,0x86真的是你说的132吗?
  • 抱歉数学错误。所以我们有 Start Char (0x02), Count (0x86), Address (6 bytes), Data (134 bytes), Checksum (1 byte) = 143。

标签: c# reverse-engineering


【解决方案1】:

我会为你输入字符串 s 时得到的校验和写 F(s)。

注意:

  • F("122") xor F("123") = 95 F4 xor 45 52 = D0 A6
  • F("132") xor F("133") = 55 FF xor 85 59 = D0 A6
  • F("123") xor F("124") = 45 52 xor 56 62 = 13 30
  • F("133") xor F("134") = 85 59 xor 96 69 = 13 30

所有这些都与具有以下属性的校验和一致,校验和并不罕见:更改输入中的给定位总是用相同的东西异或输出

我预测,例如,F("210") = F("211") xor D0 A6 = 8D C5,类似地,F("222") = 3C A8 xor C5 C8 xor 95 F4 = 6C 94 .

如果这是真的,那么如果您有一个为您计算校验和的黑匣子(显然您有),那么以下内容为您提供了一种蛮力计算校验和的方法:

  • 查找所有位为 0 的输入的校验和。将此称为 a
  • 对于每个位位置k,找到一个输入的校验和,除了位k为1之外,所有位都为0。将此称为a XOR b(k).
  • 现在任意输入的校验和是 a XOR 每个 b(k) 其中位 k 是在输入中设置。

通常 b(k) 将彼此密切相关——通常的模式是将位输入移位寄存器——所以鉴于对算法的理解,以上内容比您需要的更暴力。但我希望它可以工作,如果您能够输入任意选择的位模式作为输入。

如果没有,您可能仍然可以这样做。例如,假设您实际可以选择的只是 29 个 7 位 ASCII 字符值,位于输入的 17,19,...73 位置。然后,您可以首先输入所有空格 (0x20),然后在位置 0..6 中依次对每个空格进行 XOR。这不会给你所有的 b(k) 但它会给你足够的任意 29-ASCII 字符输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多