从数据确定 CRC 算法 + CRC——嵌入式应用程序。
我有一组受 16 位校验和保护的数据,需要更正。 校验和位置是已知的,计算它们的确切区域以及用于计算它们的确切算法却未知。 16 位,最低有效位在前。 我怀疑这是某种 16 位 CRC,但我无法找到实际计算校验和的代码。
示例:
00 4E00FFFF26EC14091E00A01830393630
10 30313131313030393030363030313030
20 30303131313030393030363030313030
30 30303131313030393030363030313030
40 3030FFFF225E363436304D313037**0CE0**
50 64000000000000008080808080800000
60 00000000**BE6E**FC01E001EB0013010500
校验和存储在4E和64处。我不知道它们是从每个数据部分开头的第一个字的偏移量开始计算还是从之后开始计算,或者从整个范围开始计算。 我尝试了一些常见的 CRC 算法和多项式,但没有成功。 没有适用于此应用的参考资料或规范。
这是另一个具有不同 CRC 的数据部分,以便进行比较。
00 4E00FFFF26C014091600A01030393132
10 30313131313030393030313230313030
20 30303131313030393030313230313030
30 30303131313030393030313230313030
40 3030FFFF225E343231324F313044**8348**
50 64000000000000008080808080800000
60 00000000**72F8**E001EB00130105000E01
我的问题是,有人能识别该算法吗? 有没有办法根据数据和 CRC 计算 CRC 多项式和其他因子?
谢谢!
编辑:
对常见 CRC16 多项式 0xA001 的反汇编搜索揭示了此函数:
34F86 ; =============== S U B R O U T I N E =======================================
34F86
34F86
34F86 Possible_Checksum: ; CODE XREF: MEM_EXT_4:00034FEEP
34F86 ; MEM_EXT_4:0003503AP ...
34F86 mov [-r0], r9 ; Move Word
34F88 mov r4, r12 ; Move Word
34F8A mov r5, r13 ; Move Word
34F8C shr r4, #14 ; Shift Right
34F8E shl r5, #2 ; Shift Left
34F90 or r5, r4 ; Logical OR
34F92 mov r4, r12 ; Move Word
34F94 mov DPP0, r5 ; Move Word
34F98 and r4, #3FFFh ; Logical AND
34F9C movb rl3, [r4] ; Move Byte
34F9E mov DPP0, #4 ; Move Word
34FA2 movbz r9, rl3 ; Move Byte Zero Extend
34FA4 mov r15, #0 ; Move Word
34FA6
34FA6 loc_34FA6: ; CODE XREF: MEM_EXT_4:00034FC8j
34FA6 mov r4, [r14] ; Move Word
34FA8 xor r4, r9 ; Logical Exclusive OR
34FAA and r4, #1 ; Logical AND
34FAC jmpr cc_Z, loc_34FBA ; Relative Conditional Jump
34FAE mov r4, [r14] ; Move Word
34FB0 shr r4, #1 ; Shift Right
34FB2 xor r4, #0A001h ; Logical Exclusive OR
34FB6 mov [r14], r4 ; Move Word
34FB8 jmpr cc_UC, loc_34FC0 ; Relative Conditional Jump
34FBA ; ---------------------------------------------------------------------------
34FBA
34FBA loc_34FBA: ; CODE XREF: MEM_EXT_4:00034FACj
34FBA mov r4, [r14] ; Move Word
34FBC shr r4, #1 ; Shift Right
34FBE mov [r14], r4 ; Move Word
34FC0
34FC0 loc_34FC0:
I have a set of data protected by 16bit checksums that I need to correct. The checksum locations are known, the exact areas they are calculated on and the exact algorithm used to calculate them are not. 16bit, LSB first. I suspect it's some sort of 16bit CRC, but I have not been able to find the code that's actually calculating the checksums.
Example:
00 4E00FFFF26EC14091E00A01830393630
10 30313131313030393030363030313030
20 30303131313030393030363030313030
30 30303131313030393030363030313030
40 3030FFFF225E363436304D313037**0CE0**
50 64000000000000008080808080800000
60 00000000**BE6E**FC01E001EB0013010500
Checksums are stored at 4E and 64. I don't know if they are calcuated starting from the offset in the first word at the beginning of each data section or starting after that, or on the whole range. I have tried a number of common CRC algorithms and polynomials with no luck. There are no references or specifications available for this application.
Here is another data section with different CRCs for comparison's sake.
00 4E00FFFF26C014091600A01030393132
10 30313131313030393030313230313030
20 30303131313030393030313230313030
30 30303131313030393030313230313030
40 3030FFFF225E343231324F313044**8348**
50 64000000000000008080808080800000
60 00000000**72F8**E001EB00130105000E01
My question is, can anyone identify the algorithm? Is there any way to calculate the CRC polynomial and other factors from the data and the CRC?
Thanks!
Edit:
A search of my disassembly for the common CRC16 polynomial 0xA001 revealed this function:
34F86 ; =============== S U B R O U T I N E =======================================
34F86
34F86
34F86 Possible_Checksum: ; CODE XREF: MEM_EXT_4:00034FEEP
34F86 ; MEM_EXT_4:0003503AP ...
34F86 mov [-r0], r9 ; Move Word
34F88 mov r4, r12 ; Move Word
34F8A mov r5, r13 ; Move Word
34F8C shr r4, #14 ; Shift Right
34F8E shl r5, #2 ; Shift Left
34F90 or r5, r4 ; Logical OR
34F92 mov r4, r12 ; Move Word
34F94 mov DPP0, r5 ; Move Word
34F98 and r4, #3FFFh ; Logical AND
34F9C movb rl3, [r4] ; Move Byte
34F9E mov DPP0, #4 ; Move Word
34FA2 movbz r9, rl3 ; Move Byte Zero Extend
34FA4 mov r15, #0 ; Move Word
34FA6
34FA6 loc_34FA6: ; CODE XREF: MEM_EXT_4:00034FC8j
34FA6 mov r4, [r14] ; Move Word
34FA8 xor r4, r9 ; Logical Exclusive OR
34FAA and r4, #1 ; Logical AND
34FAC jmpr cc_Z, loc_34FBA ; Relative Conditional Jump
34FAE mov r4, [r14] ; Move Word
34FB0 shr r4, #1 ; Shift Right
34FB2 xor r4, #0A001h ; Logical Exclusive OR
34FB6 mov [r14], r4 ; Move Word
34FB8 jmpr cc_UC, loc_34FC0 ; Relative Conditional Jump
34FBA ; ---------------------------------------------------------------------------
34FBA
34FBA loc_34FBA: ; CODE XREF: MEM_EXT_4:00034FACj
34FBA mov r4, [r14] ; Move Word
34FBC shr r4, #1 ; Shift Right
34FBE mov [r14], r4 ; Move Word
34FC0
34FC0 loc_34FC0:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您从 loc_34FA6 开始发布的代码基本上如下:
这是带有 0xA001 多项式的 CRC-16。 一旦找到 CRC-16 适用的数据范围,即可将 CRC 初始化为 0xFFFF,并为序列中的每个字节调用此函数。 存储返回值并在下次通过时传回。 最后返回的值就是您的最终 CRC。
不知道序言在做什么...
The code you posted from loc_34FA6 down is basically the following:
This is a CRC-16 with a 0xA001 polynomial. Once you find out the range of data for which the CRC-16 applies, you initialize CRC to 0xFFFF and the call this function for each byte in the sequence. Store the return value and pass it back in the next time through. The value returned at the end is your final CRC.
I'm not sure what the prologue is doing...
更一般地说,CRC 概念的一部分是,当您计算某个数据文件的 CRC,然后将 CRC 附加到末尾时,您会得到一个文件,该文件的 CRC 是某个取决于文件长度的值,但是不是它的内容。 (对于某些 CRC 算法,它甚至不依赖于文件长度。)
因此,如果您怀疑您尝试逆向工程的应用程序正在使用 CRC16,并且您有一个计算 CRC16 的程序,并且您有多个相同长度的样本,只需计算这些数据文件的 CRC16(包括校验和)。 如果每次都返回相同的校验和数据(对于相同长度的文件),则它们必须包含使用相同宽度和多项式的 CRC 校验和。
例如,我曾经不得不对一些文件进行逆向工程,开发人员认为他通过更改两个常量来更改 CRC32 算法很聪明。 我不必找到验证校验和的目标代码,将其反汇编,然后通过艰难的方式找出它。 这个简单的测试就解决了这个问题。
More generally, part of the concept of CRC is that the when you compute the CRC of some data file, and then append the CRC on the end, you get a file who's CRC is some value that depends on the length of the file, but not it's contents. (For some CRC algorithms, it doesn't even depend on the file length.)
So, if you suspect the app you're trying to reverse-engineer is using say CRC16, and you have a program that computes CRC16, and you have multiple samples of the same length, just compute the CRC16 of those data files (which include the checksum). If it comes back with the same checksum data every time (for files of the same length), then they must contain a CRC checksum using the same width and polynomial.
For example, I once had to reverse engineer some files where the developer thought he was being clever by changing the CRC32 algorithm by changing two constants. I didn't have to find the object code that verified the checksum, disassemble it and then figure it out the hard way. This simple test nailed it.