SLP1.0およびMulti-SLPの考察
**************** <出典および注意事項> ******************
以下の考察は2chの「WinXPアクティベーション 総合スレッド Part29 Final」において
"爺さん"が発言された内容、及び同氏がUPされたドキュメントをもとに再編集
したものである。
なお、ここに書かれている内容については、あくまでもXP/Server2K3のSLP
のメカニズムを研究することを目的とするものであり、違法行為に類する目的に
使用・流用してはならない。
**********************************************
【SLP1.0の基礎知識】
WindowsXPやWindowsServer2003でSLP1.0が機能するためには以下の条件を満たす
必要がある。
(1) OSがSLP用のKeyでインストールされている。
(2) メーカーが決めたSLP-String(文字列)情報が存在する。
(3) (2)と対になるOEMBIOS.*のファイル群を利用している。
(4) (2)がメモリ上の指定されたアドレス範囲に存在する
(1)~(3)については衆知のことであるが、意外と見落とされているのが(4)の条件であり、
SLPの成否を握る重要な条件である。
これらのSLPの条件はOEMBIOS.*ファイル群のOEMBIOS.DAT"の中で定義されており、
SLP文字列とそれが置かれるべきアドレス範囲が決められ、しかもそれらはメーカー毎に異なる。
文字列が異なるのは当然だが、アドレス範囲も異なるので厄介である。
アドレス範囲をかなり広く設定している"寛大な"メーカーもあれば、
非常に狭い範囲に限定している"意地悪な"メーカーもある。
このアドレス範囲の設定の仕方によってメーカーを以下のように分類できる。
(A) アドレス範囲が非常に広いメーカーのグループ
- アドレス範囲: BIOS領域(F000:0000 - F000:FFFF) + 拡張BIOS領域(E000:0000 - E000:FFFF)
- メーカー例: IBM、Lenovo、HP&Compaq、NECやFujitsuの海外モデル、など
(B) アドレス範囲が比較的広いメーカーのグループ
- アドレス範囲: BIOS領域 (F000:0000 - F000:FFFF)
- メーカー例: TCL、Acer、Legend、など
(C) アドレス範囲が狭いメーカーのグループ
- アドレス範囲: BIOS領域の限定された範囲
- メーカー例: Dell、Gateway、Sony、Panasonic、Samsung、LG、
ASUS、日本メーカーの国内モデルなど
では、具体的にWindowsXPのOEMBIOS.DATに書き込まれているSLP定義の例を見てみよう。
(A)グループの例
【IBM】
<SLP文字列> |
<メモリ上のアドレス範囲> |
IBM Corporation |
E000:0000 - E000:FFFF |
IBM Corporation |
F000:0000 - F000:FFFF |
(B)グループの例
【TCL】
<SLP文字列> |
<メモリ上のアドレス範囲> |
TCL123 |
F000:0000 - F000:FFFF |
(C)グループの例
【Dell】
<SLP文字列> |
<メモリ上のアドレス範囲> |
Dell System |
F000:49A9 - F000:49B8 |
Dell System |
F000:E05E - F000:E06D |
Dell System |
F000:E076 - F000:E085 |
Dell Inc |
F000:E838 - F000:E84F |
Dell Computer |
F000:E840 - F000:E84F |
※ 実際には、終了アドレスはなく、開始アドレスとそこからのバイト数。
メーカー別のSLP定義情報は
ここを参照。
このSLP定義をどのように読むのかというと、たとえばDellの例では、5通りの
「文字列とそれが置かれるべきアドレス範囲」のパターンのうち、どれかひとつ
でも満たしていればOK!ということ。 Windowsが起動して、LicenseTypeが
SLP方式だという情報を受け取るとOEMBIOS.DATに定義された文字列と
アドレス範囲をもとにメモリ上をスキャンしていって、定義されたパターンのどれか1つ
がOKであればSLP成立となる。SLPの真偽判断ロジックは「AND」ではなく、
「OR」のロジックだからであり、どのメーカーの場合であっても、少なくとも1通り
の正しい「SLP文字列 & SLPアドレス」の条件を満たせばOKである。
さて、BIOSが展開されるメモリ上のアドレスは「F000:0000 - F000:FFFF」なので、
上の例を見ても分かる通り、(A)と(B)のグループはBIOSの中のどこに文字列を
置いてもSLPは成立する。さらに、(A)の場合は「E000:0000 - E000:FFFF」
の拡張BIOS領域も対象範囲に入っている。従って、NVRAMの領域に文字列
を置いてもOKであり、まさにサルでも出来るSLPのパターン。
これに対して、(C)のグループの場合は通常のDMI領域以外の部分にアドレス範囲が
指定されているので、いくらDMI情報をこねくり回しても無駄。唯一の方法はBIOS
を直接編集してしかるべき場所に文字列を埋め込むことである。このようにSLPの
原理とロジックさえ分かればどのメーカーのSLPにも対応できる。
【OEMBIOS.DATとSLP定義情報について】
上に述べたように、メーカーごとのSLP定義情報はOEMBIOS.DATの中に書かれて
いるので、このファイルがSLPの"キモ"になる。ただ、その情報は多重に暗号化
されているので、バイナリエディタで覗いてみても無駄。実は数年前にドイツの
クラックサイトにOEMBIOS.DATの解読ツールがUPされたが、すぐに地下に潜った
模様。しかし、上記のmsfn.orgのフォーラムに主要メーカーのOEMBIOS.DATの内容
(SLP文字列とアドレス範囲)が掲載されているし、また以下に述べる方法によって
OEMBIOS.DATのSLP定義情報を抜き出すことができる。
◆ OEMBIOS.DATを解読する方法 ◆
Reverse-Engineeringのような"違法"なことをせずとも、MS自身が提供して
いるツールを使って合法的に(?)SLPの定義情報を見ることができる(笑)。
MS謹製のWPA/WGA確認ツールである「MGADiag.exe」はWPAの状態を診断するために、
WindowsXP起動時の"WPA-CALL"と殆ど同じプロセスをシミュレートする。その際に、
当然ながらOEMBIOS.DATをdecryptしてその内容を一旦メモリに展開するので、
それを覗いてやれば良い。
<解読方法>
1) まず、XPをセーフモードで立ち上げ、解読したいメーカーのOEMBIOSファイル群
(dat/bin/sig)をsystem32のディレクトリに上書きコピーする。
2) セーフモードのまま、MGADiag.exeを起動し「Continue」を押す。
(この時、"Validation Status"の結果は関係なし。)
3) MGADiag.exeはそのままで、WinHexを起動し以下の通りにメニューをたどる。
Tools → Open RAM → Mgadiag #**** → Primary Memory → 「OK」
4) WinHexの検索メニュー(Search→Find Text)で次の文字列を検索する。
"[OEMBIOS]"
5) すると、[OEMBIOS]と[HashTable]に囲まれた範囲に以下のような
SLP定義情報が展開されている。
【 Dellの場合 】
[OEMBIOS]
BIOS=f000,e076,0010,Dell System
BIOS0=f000,e840,0010,Dell Computer
BIOS1=f000,49a9,0010,Dell System
BIOS2=f000,e05e,0010,Dell System
BIOS3=f000,e838,0018,Dell Inc
[HashTable]
※ SLP定義情報の読み方
(例:f000,e076,0010,Dell System)
- 開始アドレス:F000:E076 (0x000FE076)
- 格納範囲:0x10(16)バイト
- SLP文字列:Dell System
ちなみに、SLP文字列のみを簡便的に知りたい場合には以下の通りにする。
1. MGADiag.exeを実行して「Windows」タブの右下の「Copy」をクリックし、
メモ帳などにペーストする。
2. 色んな情報が表示されるが、下の方の<SLPBIOS>と</SLPBIOS>に囲まれた部分
がSLP文字列である。
【マルチSLP-BIOSについて】
SLPの真偽判断ロジックが「AND」ではなく「OR」のロジックであることを利用して、
"マルチSLP"なBIOSを作成することができる。つまり、上の基礎知識編で説明
したように、どのメーカーでも少なくとも1通りの正しい「SLP文字列 & SLPアドレス」の
条件を満たせばOKなので、メーカーごとにSLP文字列を1個ずつ正しいアドレスに
置いてやれば、アドレスが重複しない限り、いくらでもSLP文字列を埋め込むことが
原理的には可能となる。
特に(A)と(B)のグループのものは「F000:0000-F000:FFFF」の範囲ならOKなので、
DMI情報エントリのStringValue(文字列値)が入力可能な部分に連ねて放り込んで
やれば、かなりの数のSLP文字列を埋め込むことができる。ただ、(C)グループ
のものについては、アドレスが重複しないこととBIOSに埋め込むための空き領域
があることに留意が必要。
なお、SLP文字列を連ねて埋め込む場合の方法は、次のようにコンマ(".")で
区切って連ねることもできるし、直接つなげてもOK。
IBM Corporation.Compaq.Hewlett-Packard (区切る場合)
IBM CorporationCompaqHewlett-Packard (直接連結する場合)
【BIOSの直接編集について】
(C)グループのSLPについては、BIOSを直接編集してしかるべき場所に文字列を
埋め込むことによって対応可能となるが、その注意点を以下に記す。
1) メモリのダンプリストと、ターゲットにするSLP文字列のアドレスをよく比較
して文字列埋め込みの可能性を慎重に検討する。
BIOSの未使用エリアである0x00や0xFFが連続しているエリアか、
"書き換え可能な"文字列がすでに存在しているエリアに埋め込む
のが基本。(ただ、その場合でも問題発生の可能性は排除できない)
2) AMIやPhoenix系のBIOSではそのような未使用エリアとSLP用アドレス
が重なっているケースが多々あるので編集の可能性があるが、Award
のBIOSではBIOSプログラムのメモリ上のアロケーションが大きく異なるので、
編集は困難である。
3) 確かにAward-BIOSでは「F000:E05E - F000:E06E」あたりに
BIOS Versionの文字列("Phoenix-Award BIOS"など)がある
ので、Dellの文字列に変更できると思われがちであるが、ここは
システムBIOSの中心であり簡単には変更できない。もしかりに、
AwardBIOS Editorなどで強引に書き換えたら"Checksum Error"
になって必ずBIOSが死ぬ。また、modbin6でORIGINAL.BINを
抽出してバイナリエディタで変更しても、BIOSを再構築すれば元に
戻っているはずである。ここのエリアは非常に高いスキルがある人
以外は触らぬように。
いずれにしても、実機でのBIOSの編集はくれぐれも慎重にやること。もし、挑戦
するのであれば、BIOSの構造をよく理解した上で、自己責任で挑戦すること。
<ASUSのP4P800での編集例>
P4P800(AMI-BIOS)を例にとるとBIOS改造のツールとしては、MMTool(Ver 2.22.1)
とバイナリエディタだけで作業が出来る。AMI-BIOSの場合はメモリ上に展開された時に
「F000:FF00-F000:FFFF」や「F000:E800-F000:E880」の範囲に未使用領域(0x00で
埋められた部分)が多く、SLP文字列のアドレスと重なっているケースが多い。
1. まずターゲットとするメーカーの文字列があるアドレスをメモリダンプし、どのアドレス範囲
が編集可能かをじっくり検討してターゲットとなるアドレスとその前後の状態を
スクリーンショットか何かで撮っておく。
2. MMToolの"PowerMMTool"の画面でBIOSを読み込み、'1B'の"Single Link Arch"
のモジュールを解凍・抽出してバイナリエディタで編集し、終わったら"Replace"で書き
戻す。
3. どの箇所を編集するかは、メモリダンプの結果と上記モジュールの内容を比較すれば
分かる。
◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
2chのXPアクチスレ Part.34に転載された「爺さん」のSLPに関する技術的説明を
以下に再録します。(但し、未完のドキュメントにつきご注意ください)
◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
【SLP1.0の基本原理】
1-1. Windowsの起動とSafeModeチェック
Windowsが起動すると、Winlogon.exeはシステムがSafeModeで起動
されているかどうかをチェックし、もしSafeModeで起動されていれば、
アクティベーションの確認プロセスである「WPA-CALL」ルーチンはスキップされる。
(WPAとは、Windows Product Activationの略)。
しかし、SafeMode以外で起動されていれば、次に述べるWPA-CALLの
プロセスに移る。
≪Tips≫
上記のSafeModeチェックを逆に利用して「SafeModeで起動されていますよ~」
とWinlogon.exeをだましてWPAをスキップさせるトリックを使っているのが、
例の"AntiWPA-3.4.6"というアプリ。メモリ上でAPI-Hookingを利用して、
- user32.dll → GetSystemMetrics(SM_CLEANBOOT{=0x43})
- ntdll.dll → NtLockProductActivation
をフックし、Winlogon.exeに「WindowsシステムがSafeModeで起動されている」
と勘違いさせる。
1-2. WPA-CALLのしくみ (1) - License Typeのチェック -
WPA-CALLは次のプロセスをたどって実行される。
1) レジストリの’HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
Windows NT\CurrentVersion’にある'DigitalProductId' のHexデータ
を読み込む。
2) その中の'RPC'(Regional Product Code)と'BINK_ID'の情報を読み
取り、DPCDLL.DLLを開いてその中のLicenseテーブルを検索し、
RPCとBINK_IDに対応するLicense Typeを特定する。
3) License Typeは'01'~'06'までのコードで表されており、
License TypeによってWPA確認プロセスが分岐する。
'05'であればOEM=SLPであり、次のチェック・ルーチンへ移る。
1-3. WPA-CALLのしくみ (2) - OEMBIOSファイル群 -
License Typeが'05'(OEM=SLP)であることが確認されると、いよいよ
SLPの検証が実行される。ここで例の「OEMBIOSファイル群」が登場する。
それぞれのファイルの役割は次の通り。
OEMBIOS.DAT: SLP文字列やそれが置かれるメモリ・アドレスなどのSLP定義
情報とファイル群の正当性を確認するためのHash値の情報
が格納されている。ただし、多重に暗号化(encrypt)されて
いるので、バイナリ・エディタで開いても解読できない。
(※ SLPの機能上、もっとも重要なファイル!)
OEMBIOS.SIG: OEMBIOS.DATを解読(decrypt)するための鍵(Signature)の
情報が格納されている。
OEMBIOS.BIN: OEMBIOS.DATのHash情報と合わせてファイル群の正当性
をチェックするためのHash生成用バイナリ・データを持つ。
OEMBIOS.CAT: セキュリティ・カタログのファイル。
(SLPの機能上は無視してもOK。OSインストール時には必要だが、
一旦インストールした後は削除してもSLPは機能する)
1-4. WPA-CALLのしくみ (3) - SLPの検証(Validation) -
Windowsは次のプロセスを実行してSLPの検証を行なう。
1) まずOEMBIOS.SIGの先頭ブロックから80バイトのデータを読み込み、それを
鍵として、暗号化されているOEMBIOS.DATの解読とデータの展開を行なう。
2) OEMBIOS.DATの'[HashTable]'ブロックにある100個の'HashBlock'テーブルの
中からランダムにひとつのHashBlockを選び、次にOEMBIOS.BINの該当オフセット
から131,072バイトのHashデータを読み込んでHash値を計算する。
3) このHash計算の結果とHashBlockのHash値が一致するかどうかチェックし、
これによってOEMBIOSファイル群の正当性を確認する。
4) 次にOEMBIOS.DATの'[OEMBIOS]'ブロックに格納されているSLPの定義情報を
参照し、そこに定義されているSLPの文字列が所定のアドレスにあるか
どうかを物理メモリ内をスキャンして検証する。
→ 定義されたSLP文字列が所定のアドレスに存在 → アクティベーション成立!
2-1. SLPの定義情報 - OEMBIOS.DAT -
前章で述べたOEMBIOS.DATに格納されているSLPの定義情報の中身を説明
する。 この情報がまさにSLPの「キモ」になる。解読(decrypt)されたDATファイル
には下記のような情報が格納されており、これがSLPの最も重要な定義情報である。
【DellのOEMBIOS.DATの例】
[OEMBIOS]
BIOS=f000,e076,0010,Dell System
BIOS0=f000,e840,0010,Dell Computer
BIOS1=f000,49a9,0010,Dell System
BIOS2=f000,e05e,0010,Dell System
BIOS3=f000,e838,0018,Dell Inc
[HashTable]
HashBlocks=100
HashSize=131072
:
:
2-2. SLP定義情報の読み方 (1)
BIOS=f000,e076,0010,Dell System
BIOS0=f000,e840,0010,Dell Computer
BIOS1=f000,49a9,0010,Dell System
BIOS2=f000,e05e,0010,Dell System
BIOS3=f000,e838,0018,Dell Inc
この情報の読み方は次の様になる。一番上の行を例にとると:
【例】 BIOS=f000,e076,0010,Dell System
↓
物理メモリ内のF000:E076 (0x000FE076)を開始アドレスとして
そこから0x10バイト(16バイト)の範囲内に'Dell System'という
SLP文字列が存在しなければならない。
つまり、F000:E076 ~ F000:E086の範囲内にDell Systemという
文字列が存在すればSLPが成立する、ということ。
2-3. SLP定義情報の読み方 (2)
[A] f000,e076,0010,Dell System
[B] f000,e840,0010,Dell Computer
[C] f000,49a9,0010,Dell System
[D] f000,e05e,0010,Dell System
[E] f000,e838,0018,Dell Inc
さて、それぞれの行のSLP定義の読み方は分かったとして、Dellの例では
上記の様に5通りのパターンが定義されている。実際には、メーカーによって
このSLP定義は異なり、1通りのパターンもあれば20通り以上のパターンもある。
これはどう解釈すればいいのだろうか?
Dellを例にとると、この定義の解釈の仕方は:
[A] OR [B] OR [C] OR [D] OR [E] が真ならばSLPが成立!
ということ。つまり、SLPの真偽判断ロジックは「AND」ではなく、
「OR」のロジックであり、[A]~[E]の5通りの定義パターンのうち、
どれかひとつを満たせばOKである。
3-1. OEMBIOS.DATの詳細 (1) - SLP定義の作成ルール -
OEMメーカーがOEMBIOSのファイルセットをMicrosoftに作成依頼する際に、SLP定義
の設定の仕方には、当然ながら一定のルールがある。
すでに説明したように、OEMBIOS.DATの中に格納されているSLP定義情報
は下記のように公式化できる。
BIOS# = [アドレス・セグメント],[アドレス・オフセット],[メモリ範囲],[SLP文字列]
これの設定ルールは下記の通り。
1) BIOS#の部分は第1行目は'BIOS='で始まり、2行目以降から'BIOS0='
のように#の部分に連番がふられる。#の値は'0'~'99'まで可能。
従って、理論上、最大101個の定義を格納することができる。
2) [アドレス・セグメント]の範囲: 0xE000 - 0xFFF0
3) [アドレス・オフセット]の範囲: 0x0000 - 0xFFFF
4) [メモリ範囲]は 0x0005(バイト) - 0xFFFF(バイト)。ここは省略することも
可能であり、省略された場合は、0x104バイト(260バイト)となる。
5) [SLP文字列]は"ASCII文字"で、長さは5文字以上65,535文字以下。
OEMメーカーの社名あるいは略称が含まれていなければならない。
但し、大文字・小文字の区別はないので、例えば、"Dell System"
だけでなく、"dELL sYStEM"や"DeLl SyStEm"でもOK。