Determinando algoritmo CRC a partir de dados + CRC - aplicativo incorporado.
Pergunta
Eu tenho um conjunto de dados protegidos por somas de verificação de 16 bits que eu preciso para corrigir. Os locais de checksum são conhecidos, as áreas de exatas são calculados com e o algoritmo exato usados ??para calcular deles não são. 16bit, LSB primeiro. Eu suspeito que é algum tipo de 16bit CRC, mas eu não tenho sido capaz de encontrar o código que está realmente calcular as somas de verificação.
Exemplo:
00 4E00FFFF26EC14091E00A01830393630
10 30313131313030393030363030313030
20 30303131313030393030363030313030
30 30303131313030393030363030313030
40 3030FFFF225E363436304D313037**0CE0**
50 64000000000000008080808080800000
60 00000000**BE6E**FC01E001EB0013010500
As somas de verificação são armazenados em 4E e 64. Eu não sei se eles estão calcuated a partir do deslocamento na primeira palavra no início de cada seção de dados ou iniciar depois disso, ou em toda a gama. Eu tentei uma série de algoritmos CRC comuns e polinômios com nenhuma sorte. Não há referências ou especificações disponíveis para esta aplicação.
Aqui é outra seção de dados com diferentes CRCs para efeitos de comparação.
00 4E00FFFF26C014091600A01030393132
10 30313131313030393030313230313030
20 30303131313030393030313230313030
30 30303131313030393030313230313030
40 3030FFFF225E343231324F313044**8348**
50 64000000000000008080808080800000
60 00000000**72F8**E001EB00130105000E01
A minha pergunta é, alguém pode identificar o algoritmo? Existe alguma maneira de calcular o polinômio CRC e outros fatores a partir dos dados e a CRC?
Obrigado!
Editar:
A busca da minha desmontagem para o CRC16 comum polinomial 0xA001 revelou esta função:
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:
Solução
O código que você postou a partir loc_34FA6 baixo é basicamente o seguinte:
unsigned short
crc16_update(unsigned short crc, unsigned char nextByte)
{
crc ^= nextByte;
for (int i = 0; i < 8; ++i) {
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1);
}
return crc;
}
Este é um CRC-16 com um polinômio 0xA001. Depois de descobrir o intervalo de dados para o qual se aplica o CRC-16, você inicializa CRC a 0xFFFF ea chamada esta função para cada byte na sequência. Armazenar o valor de retorno e passá-lo de volta na próxima vez que passar. O valor devolvido no final é a sua CRC final.
Eu não tenho certeza o que o prólogo está fazendo ...
Outras dicas
De modo mais geral, parte do conceito de CRC é que o quando você computar o CRC de algum arquivo de dados, e em seguida, acrescentar o CRC no final, você tem um arquivo que está CRC é algum valor que depende do comprimento do arquivo, mas não o seu conteúdo. (Para alguns algoritmos CRC, nem sequer dependem do tamanho do arquivo.)
Então, se você suspeitar que o aplicativo que você está tentando fazer engenharia reversa está usando digamos CRC16, e você tem um programa que calcula CRC16, e você tem várias amostras do mesmo comprimento, apenas calcular o CRC16 desses arquivos de dados (que incluem a soma de verificação). Se ele volta com os mesmos dados de soma de verificação de cada vez (para arquivos do mesmo comprimento), então eles devem conter uma soma de verificação CRC usando a mesma largura e polinomial.
Por exemplo, uma vez eu tive que fazer engenharia reversa alguns arquivos onde o desenvolvedor pensou que estava sendo inteligente ao alterar o algoritmo CRC32 alterando duas constantes. Eu não tenho que encontrar o código objeto que verificou a soma de verificação, desmontá-lo e, em seguida, descobrir isso da maneira mais difícil. Este teste simples acertou em cheio.