HSP3 のチェックサム計算

  • 1
    Like
  • 0
    Comment
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