他のバージョンの Windows のファイルを差し替えてもソフトが動かない3つの理由

よく、『プロシージャ エントリ ポイント MOFMOF がダイナミック リンク ライブラリ KERNEL32.dll から見つかりませんでした』 などのエラーが出た時に、 Windows XP や 7から 同名のファイルを持ってきて上書きすればいいんじゃないか?などの安直な考えを実行してしまってPCが起動しなくなってしまったというトラブルがありますがなぜだめなのかを分かり易く説明してみます ・ω・

1. 関数間のリンクの問題

DLLやEXE 形式の プログラムは、後から使うかもしれない関数と 必ず使う関数のテーブルをファイルの中に持っています。使うかもしれない関数はプログラム起動時に発見できなくてもエラーにはなりませんが、必ず使う関数が目的のDLLに存在しないと
『プロシージャ エントリ ポイント ~ がダイナミック リンク ライブラリ ~ から見つかりませんでした』 のエラーになります。

Windows 2000のKERNEL32.DLLは約 800、Windows VistaのKERNEL32.DLLは約 1200の関数があります。
ところが、NTDLLの必要な関数が 2000 とVistaでは違います
kr
Windows 2000にVista のkenrel32.dllを読み込ませてみた所です。
NTDLLの機能不足によって、読み出しに失敗しています
逆に、2000に存在したのに、Windows Vista のKernel32.dllでは削られてしまった関数もあります。

ほぼすべてのDLLやEXEは KERNEL32.DLL にリンクしているのですが、上位バージョンの Windows のDLLを使うためには、NTDLLを含む、KERNEL32.DLL を置き換えなくてはいけないわけです。

WindowsのNTDLL.DLL は関数の外部参照がないため、入れ替えてしまえば動作するように見えます。

2. 一部のDLLは カーネル機能を使う問題

実は、NTDLLやGDI32や KERNEL32 や USER32 や WIN32K は カーネル関数という、関数名ではなく、機能番号を用いた関数を利用しています。

 NtFsControlFile:
          mov    eax,00000048h
          lea    edx,[esp+04h]
          int    2Eh
          retn    0028h
;------------------------------------------------------------------------------
 NtGetContextThread:
          mov    eax,00000049h
          lea    edx,[esp+04h]
          int    2Eh
          retn    0008h

Windows 2000

 NtFsControlFile:
          mov    eax,00000086h
          mov    edx,7FFE0300h
          call    [edx]
          retn    0028h
;------------------------------------------------------------------------------
          Align    4
 NtGetContextThread:
          mov    eax,00000087h
          mov    edx,7FFE0300h
          call    [edx]
          retn    0008h

Windows 7

eax に代入されているのが機能番号です。
一目見て分かるように、 Windows 番号が変わると、機能番号が、変わってしまうのです。
2000とXPですら、番号が違うのです。

さぁたいへん、 NTDLLや WIN32K.SYSや GDI32.DLLや USER32.DLLを入れ替えてしまうと、外部関数参照の問題が解決できても、カーネルの関数番号がずれてしまうので、全く別の処理が行われてしまいます!

3. Teb / Peb 等の システム構造体の配置が違うよ!

そして一番大きいのが、 Process / Thread Environment Block  と呼ばれる 変数領域の使い方がOSによって若干異なるということです。

PEB Evolution
Peb に関してはそれほどおおきなちがいはないのですが、スレッド情報などを参照すると、オフセットがずれていたりするので、「情報が入ってるアドレスを参照したら、使用中のメモリブロックの数が返ってきた!」なんてこともあり、クラッシュの原因になります。

Windows XPから 2000に関数を移植するときに、めんどくさいのもこれだったりします

なので、安直に、システム DLLを別のOSから持ってきて動かすというのは無謀なのです・ω・

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です