【发布时间】:2020-03-21 06:59:32
【问题描述】:
我目前正在对一个软件进行逆向工程,该软件为给定的数据缓冲区计算 2 字节宽的校验和。该代码来自一个 16 位 DLL(NE 格式),并使用 Borland C++ 编译。我怀疑校验和是 CRC-16,其 poly 为 0x8408,但我没有机会计算相同的 CRC,所以我想知道实现是否是“CRC16 标准”。
这是组装实现:
crc_cal proc far
var_4= word ptr -4
arg_0= word ptr 6
arg_2= dword ptr 8
mov ax, seg dseg37
inc bp
push bp
mov bp, sp
push ds
mov ds, ax
sub sp, 2
push si
push di
xor cx, cx
mov dx, 0FFFFh
mov [bp+var_4], 8408h
loc_42646:
les bx, [bp+arg_2]
add bx, cx
mov al, es:[bx]
xor al, dl
mov dl, al
inc cx
xor di, di
jmp short loc_42672
loc_42657:
mov si, dx
dec si
mov ax, si
shr ax, 1
mov si, ax
mov ax, dx
shr ax, 1
mov dx, ax
cmp si, dx
jnz short loc_42671
mov ax, dx
xor ax, [bp+var_4]
mov dx, ax
loc_42671:
inc di
loc_42672:
cmp di, 8
jb short loc_42657
cmp cx, [bp+arg_0]
jb short loc_42646
mov ax, dx
not ax
mov dx, ax
les bx, [bp+arg_2]
add bx, cx
mov es:[bx], dl
inc cx
mov ax, dx
shr ax, 8
mov dx, ax
les bx, [bp+arg_2]
add bx, cx
mov es:[bx], dl
inc cx
pop di
pop si
pop cx
pop ds
pop bp
dec bp
retf
crc_cal endp
还有一些带有相关 CRC(最后两个字节)的数据,由软件计算得出:
| DATA |Inc|CRC|
|----------------------------------------------------------|---|---|
00 00 00 00 00 00 01 ef f7 fe ef ff fd ef fb fa fd a2 aa 21 01 f4 e0
00 00 00 00 00 00 01 ef f7 fd ef ff fd fe fb fa fd a2 aa 21 02 f4 d1
00 00 00 00 00 00 01 f7 fe fd fd ff fd df ff fb fd a2 aa 21 03 f4 cd
00 00 00 00 00 00 01 f7 fe fe fd ff f7 ef ff fa fd a2 aa 21 04 f4 c2
00 00 00 00 00 00 01 ef f7 fe ef ff fe ef fb fa fd a2 aa 21 05 f4 db
00 00 00 00 00 00 01 ef f7 fe ef ff fd ef fb fa fd a2 aa 21 06 f4 db
【问题讨论】:
-
没有标准的 CRC-16 实现,即使对于给定的多项式,也有多种实现方式可以为相同的输入给出不同的答案。见:en.wikipedia.org/wiki/Cyclic_redundancy_check#Specification
-
那么,我的问题的答案是肯定的,你确实有一些输出已知的测试数据......那么你举个例子,看看我们是否可以做得更好?跨度>
-
该实现似乎将最终结果与 0FFFFh 与
not ax行进行异或。我对数学 CRC 知之甚少,无法确定它使用什么位或字节顺序。 -
嗯,我已经运行了代码,但它似乎没有产生您显示的值。对于第一行,我得到
e6 ef。此外,所有校验和都具有f4非常可疑……我希望CRC会发生很大变化。你确定是20字节的数据+2字节的校验和,直接用这段代码计算的吗?哎呀,最后两行具有相同的校验和,即使它们在一个字节上有所不同?这将是一个疯狂的巧合。 -
我组装它并在dosbox中运行它。它将数据大小和指向字节的远指针作为参数。它把校验和放在最后,就像你的例子一样。
标签: assembly reverse-engineering x86-16 checksum crc16