我将如何反转这个 simple-looking 算法?
How would I reverse this simple-looking algorithm?
我有一些旧的 LED 板,您可以向其发送一些文本并将其挂在某个地方...它是 1994/95 年制造的,它通过串行端口进行通信,具有 16 位 MS-DOS 应用程序,您可以在其中输入一些文本。
因此,因为除了使用 DOSBox 或类似技巧,您可能无法在任何地方 运行 它,所以我决定用 C# 重写它。
在 port-monitoring 原来的 dos-exe 之后,我发现它真的对你重建它不感兴趣 - 必须以合适的、不同的字节回答请求,pre-sent "ping" 消息等...
也许您知道与我的 dos-exe 使用的校验和 routine/pattern 相似,或者您可以提供任何尝试 reverse-engineer 的提示...此外,因为我只熟悉编程,并没有花太多时间在逆向方法上 and/or 分析协议,如果这个话题有点愚蠢,请不要评判我 - 我会很高兴得到任何帮助...
真正包含应该显示的文本的消息是 143 字节长(之所以这么长是因为如果您没有用完所有 space 与您的文本),并且在该消息中我注意到以下模式:
第四个字节(仍属于消息 header)不同于 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”
- 文本:{空},十六进制校验和:"DB BA"
- 文本:“1”(“31”),十六进制校验和:"AE 5F"
到目前为止,我完全确定校验和确实取决于 header 中的第四个字节,因为如果它发生变化,显示的相同文本的校验和将完全不同。
这是一个完整的 143 bytes-string 显示“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 (...)"
不幸的是,在整个网络上,没有用户手册、文档,甚至没有真正的证据表明此信息 board-device 曾经存在过。
输入字符串 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 中的 1 位进行 XOR。这不会给你所有的 b(k) 但它会给你足够的任意 29-ASCII 字符输入。
我有一些旧的 LED 板,您可以向其发送一些文本并将其挂在某个地方...它是 1994/95 年制造的,它通过串行端口进行通信,具有 16 位 MS-DOS 应用程序,您可以在其中输入一些文本。
因此,因为除了使用 DOSBox 或类似技巧,您可能无法在任何地方 运行 它,所以我决定用 C# 重写它。
在 port-monitoring 原来的 dos-exe 之后,我发现它真的对你重建它不感兴趣 - 必须以合适的、不同的字节回答请求,pre-sent "ping" 消息等...
也许您知道与我的 dos-exe 使用的校验和 routine/pattern 相似,或者您可以提供任何尝试 reverse-engineer 的提示...此外,因为我只熟悉编程,并没有花太多时间在逆向方法上 and/or 分析协议,如果这个话题有点愚蠢,请不要评判我 - 我会很高兴得到任何帮助...
真正包含应该显示的文本的消息是 143 字节长(之所以这么长是因为如果您没有用完所有 space 与您的文本),并且在该消息中我注意到以下模式:
第四个字节(仍属于消息 header)不同于 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”
- 文本:{空},十六进制校验和:"DB BA"
- 文本:“1”(“31”),十六进制校验和:"AE 5F"
到目前为止,我完全确定校验和确实取决于 header 中的第四个字节,因为如果它发生变化,显示的相同文本的校验和将完全不同。
这是一个完整的 143 bytes-string 显示“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 (...)"
不幸的是,在整个网络上,没有用户手册、文档,甚至没有真正的证据表明此信息 board-device 曾经存在过。
输入字符串 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 中的 1 位进行 XOR。这不会给你所有的 b(k) 但它会给你足够的任意 29-ASCII 字符输入。