まぁ、年末に大掃除なるものをするわけですが。
ついでにということで模様替えをしてみたわけです。
どーん!!?
カオスってるwwww
部屋の中で点在していたのを集めたらこうなったw
案外持ってたんだなぁ…
せっかくもらったので貼ってみる その1
せっかくもらったので貼ってみる その2
例のワイド液晶。
と、益々ダメな感じになってます…
まぁ、年末に大掃除なるものをするわけですが。
ついでにということで模様替えをしてみたわけです。
どーん!!?
カオスってるwwww
部屋の中で点在していたのを集めたらこうなったw
案外持ってたんだなぁ…
せっかくもらったので貼ってみる その1
せっかくもらったので貼ってみる その2
例のワイド液晶。
と、益々ダメな感じになってます…
いろいろとどたばたしていた関係上、ずいぶん前の話になってしまうのですが…
タイムリープの発売日にやってしまいましたw
やってしまった…。
ATI Radeon HD 3870とタイムリープ同時購入(爆笑
でかーw
ささらもついでにげっと。
でかーw
というか、いや、でかいって。
お顔もなかなかの出来でニヤニヤ(・∀・)してしまう…
横からー
下からー。
…って、ただの変態アングルやんかw
もう、ダメかもしれんw ワテ。
いやぁ、なやんだわぁw
というわけで、私的技術メモ。
※内容の正誤も含め、これらを利用したことによる被害について、管理人は一切の責任を負いません。
まぁ、つまり間違っている可能性も多々ありますので、その点はご留意ください…。
★リフレクションのアセンブリロード関数の制限について。
アセンブリを読み込む関数に、生バイトを流し込むオーバーロード関数があります。
System.Reflection.Assembly.Load
http://msdn2.microsoft.com/ja-jp/library/system.reflection.assembly.load(VS.80).aspx
や、
System.AppDomain.Load
http://msdn2.microsoft.com/ja-jp/library/system.appdomain.load(VS.80).aspx
の、第一引数にバイト配列を受け取る関数が該当します。
これらは、アセンブリのファイルバイナリデータをそのまま渡して、ロードするというもの。
ぉ、ということは!
ファイルアーカイバデコーダーを作る
↓
アーカイブからアセンブリDLLをバイナリデータをして取得
↓
バイナリデータをそのままアセンブリとしてロード
…つまり、アーカイブファイル内のDLLをメモリ内で展開し、直接読み込めるので、
複数のDLLがひとまとめにでき、スッキリ( ゚Д゚)ウマウマー
と、思ったので、やってみるテスト。
まずは、ファイルストリームから直読み込みで。
System::IO::FileInfo^ infFileIO = gcnew System::IO::FileInfo(“infinity.FileIO.dll”);
System::IO::FileStream^ streamFileIO = gcnew System::IO::FileStream(infFileIO->FullName, System::IO::FileMode::Open, System::IO::FileAccess::Read, System::IO::FileShare::Read);
// バイトを読み込む
array
streamFileIO->Seek(0, System::IO::SeekOrigin::Begin);
streamFileIO->Read(bytesFileIO, 0, bytesFileIO->Length);
// ストリームを閉じる
streamFileIO->Close();
// 読み込むよ
assemblyFileIO = System::AppDomain::CurrentDomain->Load(bytesFileIO);
…実行時にこんなエラーが。
System.IO.FileLoadException が発生しました。
Message=”確認不可能なコードによるポリシー チェックが失敗しました。 (HRESULT からの例外: 0x80131402)”
Source=”mscorlib”
StackTrace:
場所 System.Reflection.Assembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection)
場所 System.AppDomain.Load(Byte[] rawAssembly)
場所 infinity.Core.infinityCore.PluginManager..ctor(infinityCore objCore)
Σ(´Д`lll)ナンデストー
というわけで、テキトーに証拠を自前で指定してみりゅ。
System::IO::FileInfo^ infFileIO = gcnew System::IO::FileInfo(“infinity.FileIO.dll”);
System::IO::FileStream^ streamFileIO = gcnew System::IO::FileStream(infFileIO->FullName, System::IO::FileMode::Open, System::IO::FileAccess::Read, System::IO::FileShare::Read);
// バイトを読み込む
array
streamFileIO->Seek(0, System::IO::SeekOrigin::Begin);
streamFileIO->Read(bytesFileIO, 0, bytesFileIO->Length);
// SHA1を計算
System::Security::Cryptography::SHA1Managed^ shaFileIO = gcnew System::Security::Cryptography::SHA1Managed();
streamFileIO->Seek(0, System::IO::SeekOrigin::Begin);
shaFileIO->ComputeHash(streamFileIO);
// 証拠
System::Security::Policy::Evidence^ evidenceFileIO = gcnew System::Security::Policy::Evidence();
evidenceFileIO->AddHost(gcnew System::Security::Policy::Zone(System::Security::SecurityZone::MyComputer));
evidenceFileIO->AddHost(gcnew System::Security::Policy::Url(“file://” + infFileIO->FullName));
evidenceFileIO->AddAssembly(System::Security::Policy::Hash::CreateSHA1(shaFileIO->Hash));
// ストリームを閉じる
streamFileIO->Close();
// 読み込むよ
// ちなみに、第2引数はデバッグシンボルのバイナリを流し込むことができる(*.pdbのバイナリ)
assemblyFileIO = System::AppDomain::CurrentDomain->Load(bytesFileIO, nullptr, evidenceFileIO);
実行してみよう。
System.IO.FileLoadException が発生しました。
Message=”Attempt to load an unverifiable executable with fixup を含む確認できない実行可能ファイルを読み込もうとしています (3 セクション以上、または TLS セクションを含む IAT です)。 (HRESULT からの例外: 0x80131019)”
Source=”mscorlib”
StackTrace:
場所 System.Reflection.Assembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection)
場所 System.AppDomain.Load(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence securityEvidence)
場所 infinity.Core.infinityCore.PluginManager..ctor(infinityCore objCore)
(´・ω・`)ショボーン
検証できないコードがあるとのご指摘のようです。
検証可能なタイプ セーフ コードの作成
http://msdn2.microsoft.com/ja-jp/library/01k04eaf(VS.80).aspx
確かに、コンパイラはC++/CLIであるし、コンパイラオプションは /clr、
つまり、アンマネージコードと混在しているため、PEVerifyでも警告が出る。
しかしながら、混在アセンブリがロードできないのでは、実用性として微妙なので、
どうにかならないものかと調べてみるが、衝撃の事実が…
以下のフォーラムを参照されたし。
http://www.dotnet247.com/247reference/msgs/26/134245.aspx
一番最後のレスポンスがトドメデアリマシタ。
意訳してみると、こんな感じでしょうか。
バイトストリームから、アンマネージコードを含むマネージアセンブリを読み込むことはできません。
CLRローダーのその部分の実装ではWindowsのLoadLibraryを使用していないため、
一切のアンマネージコードを扱うことができません。
ションボリダ…
■今日のまとめ
リフレクションでバイト配列からアセンブリをロードする場合、
対象のアセンブリは純粋なマネージコード(=検証可能なタイプセーフコード)で無ければなりません。
VB.NETやC#では、基本的には検証可能なタイプセーフコードになります。
C++/CLIの場合は、/clr:safe でコンパイルされたアセンブリが読み込めます。
■最後に
すごい長くなりましたが、これらのエラーで悩んでいた方の手助けになれば幸いです…orz
たまには真面目な話題を書いてみようかと思います。
WindowsのAPIにGetCurrentProcessという関数があります。
日本語のMSDNはこちら。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdllpro/html/_win32_getcurrentprocess.asp
さて、英語版の方を覗いてみると、一歩踏み込んで面白いことが書いてあります。
http://msdn2.microsoft.com/en-us/library/ms683179.aspx
解説(Remarks)冒頭部分を意訳するとこんな感じでしょうか。
解説:
擬似ハンドルは現在のプロセスを示す特別な定数値です。
現在では-1が常に返されますが、将来のWindowsの為に(仕様変更する可能性もあるため)
-1をそのままコードに書き込むべきではなく、この GetCurrentProcess 関数を呼び出すのが最善の方法です。
あれ? -1の値のハンドルって…
#define INVALID_HANDLE_VALUE (HANDLE)-1
…不正なハンドルを示す値と同じなのですね…
なので、念には念をと思っても、こんなことはしちゃいけない訳ですねw
HANDLE hndCurProcess = ::GetCurrentProcess();
if (hndCurProcess == INVALID_HANDLE_VALUE) {
// エラー処理;
}
あと、ハンドルを閉じようとしても駄目ですw
HANDLE hndCurProcess = ::GetCurrentProcess();
BOOL result = ::CloseHandle(hndCurProcess);
普通にエラーが返ってきちゃいますw
大概日本語版のMSDNは古いことが多いので、本家の英語版も確認しましょうというお話なのでした。
トリビアでも何でもねぇな、コレw
久々に買いました。
『吸血鬼のひめごと』
実はラノベに出会ったのが、『吸血鬼のおしごと』(1巻)だったので、非常に思い入れが深いシリーズだったりします。
ほぼ日手帳 2年目です。
http://www.1101.com/store/techo/index.html
こうして、今2007年の手帳を振り返ると、空白ばかり…
私は本当に毎日つけるのが下手なようですね。
もうすこしがんばらないと…。
HPも大規模更新したい衝動に駆られてはいますが、今のところ時間がとれずに…
…というより、エースコンバットに魅入られすぎなんですね、きっとw
ちょっとしたら、ロストオデッセイが…
(´-`).。oO(すごい、Xbox 360の稼働率ですね…)
は、置いといて、風邪引きました…
急に寒くなったからですかね…熱を出したので、かなり久しぶりに会社休みましたわ…
さてと、熱も下がって大丈夫そうですし、明日はいっちょがんばりますかー。
そうそう、実際に買ったのは結構前ですが、ワイド液晶を買いましたー。
HDMI端子対応ー♪ フルHDでは無いですが、HD対応なのでXbox 360をつないでみましたー。
うん。ばっちぐー。
あの妙にでかくなったほしフルも…
ひろび~ろ、余裕なのですよ♪