How would I cancel this simple algorithm?

I have some old LED board on which you would send some text and hang it somewhere ... it was released in 1994/95 and communicates via a serial port with 16-bit MS-DOS An application that you can enter into some text.

So, because you probably couldnโ€™t run it anywhere except using DOSBox or similar tricks, I decided to rewrite it in C #.

After the monitoring port of the original dos-ex, I found that it was not really interested in you recovering it - requests should respond suitable, varying bytes, previously sent a "ping" message, etc. ... p>

Maybe you know a similar routine / pattern checksum, as my dos-ex uses, or could you give any advice in trying to reverse engineer this ... Also, since I am only familiar with programming and don't spend much time on methods of reversing and / or protocol analysis, please do not judge me if this topic is a little stupid idea - I will be glad of any help I receive ...

The message is really containing text that should be displayed in 143 bytes (just that long because it puts byte placeholders if you don't use all the space with your text), and in msg I noticed the following patterns:

  • fourth bytes (which still belongs to the MSG header) is changed from a list of 6 or 7 duplicate values โ€‹โ€‹(in my examples, this byte will always be 0F).

  • The last two functions of bytes as a checksum

Some examples :

  • displayed text: "123" (hexadecimal: "31 32 33"), checksum hex: "45 52"
  • text: "132" ("31 33 32"), checksum hex: "55 FF"
  • text: "122" ("31 32 32"), checksum hex: "95 F4"
  • text: "133" ("31 33 33"), checksum hex: "85 59"
  • text: "112" ("31 31 32"), checksum hex: "C5 C8"
  • text: "124" ("31 32 34"), checksum hex: "56 62"
  • text: "134" ("31 33 34"), checksum hex: "96 69"
  • text: "211" ("32 31 31"), checksum hex: "5D 63"
  • text: "212" ("32 31 32"), checksum hex: "3C A8"
  • text: {empty}, checksum hex: "DB BA"
  • text: "1" ("31"), checksum hex: "AE 5F"

So far, I am completely sure that the checksum really depends on this fourth byte in the header, because if it changes, the checksums will be completely different to display the same text.

Here's an example of a complete 143-byte string displaying "123" just to give you a better orientation:

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 

(textual information begins with the 2nd byte in the line "2 31 00 32 00 33 00 (...)"

Unfortunately, there are no user manuals, documentation on the entire web page, not even proof that this information device has never existed.

+8
c # reverse-engineering
source share
1 answer

I will write F (s) for the checksum that you will receive when serving in line s.

Notice, that:

  • 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

all of which are consistent with a checksum that has the following property: checksums often have: changing a given bit at the input always XOR outputs the same.

I predict, for example, that F ("210") = F ("211") xor D0 A6 = 8D C5 and similarly that F ("222") = 3C A8 xor C5 C8 xor 95 F4 = 6C 94.

If this is true, then the following gives you a brute force-y method for determining the checksum as a whole, if you have a black box that calculates the checksums for you (which apparently you have):

  • Find the input checksum, all bits of which are 0. Name it.
  • For each bit position k, find the input checksum, all bits of which are 0, except for bit k, which is 1. Name it XOR b (k).
  • Now, the random input checksum is an XOR every b (k), where a bit bit is input.

Usually b (k) will be closely related to each other - the usual picture is that you feed the bits into a shift register - so higher is a brighter force-y than you would need to give an understanding of the algorithm. But I expect this to work if you can feed arbitrarily selected bit patterns as input.

If not, you can still do it. For example, suppose all you really can choose is 29 7-bit ASCII characters, at positions 17.19, ... 73 of your input. Then you can first load all the spaces (0x20), and then XOR each one at a time with 1-bits at positions 0..6. This will not give you all b (k), but it will give you enough for arbitrary 29-ASCII characters.

+6
source share

All Articles