Edited at

HSP3 のチェックサム計算

More than 1 year has passed since last update.

HSP3 (Hot Soup Processor 3) では、実行ファイルに含めるアーカイブにチェックサムが付与されていて、アーカイブの内容を改変するとチェックサムエラーで起動できないようになっています。

しかし、HSP3 のチェックサムは非常に簡単に計算できます。


チェックサム計算スクリプト

以下、チェックサムを計算する HSP3 のソースです。

; ファイル読み込み

dialog "exe", 16
if (stat == 0) {
end
}
filename = refstr
exist filename
filesize = strsize
sdim buf, filesize + 1
bload filename, buf, filesize

;; 実行ファイルか
;if (peek(buf, 0) != 'M' | peek(buf, 1) != 'Z') {
; dialog "実行ファイルではありません"
; end
;}
;
;; PE (Portable Executable) Header の位置を取得
;peOffset = lpeek(buf, 0x3c)
;
;; PE か
;if (peek(buf, peOffset) != 'P' | peek(buf, peOffset + 1) != 'E' | peek(buf, peOffset + 2) != 0 | peek(buf, peOffset + 3) != 0) {
; dialog "PE ではありません"
; end
;}

; 実行時オプション領域(HSPHED)を検索
; 先頭に DPM offset - 0x10000 が10進数で書かれているので
; ここではしらみつぶしにそれらしい箇所を探す (適当)
hedoffset = -1
repeat filesize
offset = cnt
c = peek(buf, offset)
if ((c >= '0' & c <= '9') | c == '+' | c == '-') {
getstr offsetstr, buf, offset, 0, 10
tmpoffset = int(offsetstr) + 0x10000
if (tmpoffset >= 0 & (tmpoffset + 3) < filesize) {
if (peek(buf, tmpoffset) == 'D' & peek(buf, tmpoffset + 1) == 'P' & peek(buf, tmpoffset + 2) == 'M' & peek(buf, tmpoffset + 3) == 'X') {
hedoffset = offset
dpmoffset = tmpoffset
break
}
}
}
loop
if (hedoffset < 0) {
dialog "HSPHED が見つかりません"
end
}

sumHED = wpeek(buf, hedoffset + 0x14)
cryptKey4 = peek(buf, hedoffset + 0x17 + 3)

sumDPM = 0
dpmsize = filesize - dpmoffset
; (DPM 以降のバイナリの) チェックサムを計算
repeat dpmsize, dpmoffset
offset = cnt
sumDPM += peek(buf, offset)

; ループ外で足しても問題ないはずなので
; ループ外で加算
; sumDPM += (cryptKey4 / 7)
loop
sumDPM += (cryptKey4 / 7) * dpmsize
sumDPM = sumDPM & 0xffff

if (sumDPM == sumHED) {
dialog "チェックサムが一致しました " + strf("%04X", sumDPM)
}
else {
dialog "チェックサムが一致しません " + strf("%04X", sumHED) + " / " + strf("%04X", sumDPM)
}
end