Windowsエクスプローラーを逆アセンブルする-タスクバーのグループ化を無効にする

2009年のある日、Windows 7がリリースされましたが、そのとき、古いコンピューターでは速度が落ちていたVistaに座っていたので、リリース後すぐに7に移行することにしました。



インストール後に最初に気付いたのは、新しいタスクバーです。 より具体的には、ボタンが属するプログラムに従ってボタンをグループ化するという事実。







すぐにこの不名誉をオフにするために設定に登り、グループ化がオフになっていないことを知って驚いた。 それにもかかわらず、目的のオプションに最も近いオプションである「結合しない」は、ボタンをグループ化します。







私と同じように、多くの人がこれを好まないだろうと思っていたので、1、2週間後にこの問題の解決策がインターネット上に現れると確信しました。 しかし、私は価値のあるものを見つけられず、自分で行動しなければならないことに気付きました。



カットの下:



降りる



以下で説明するプロセスを理解するには、アセンブラーの基本的な知識が必要です。



タスクバーをグループ化から切り離す ために、コンパイル済みの実行可能ファイルとユーザーモード(ring-3)で動作するライブラリを分析および変更するように設計され無料の32ビットアセンブラレベルデバッガーであるWindowsオペレーティングシステム向けの OllyDbgが必要になります © Wikipedia



Windows 7またはWindows 8でプロセスを繰り返すことができます。残念ながら、現時点ではOllyDbgの32ビットバージョンしかないため、64ビットOSを使用している場合、次の手順を繰り返すことはできません(この場合、仮想マシンを使用できます)



インストールOllyDbg


OllyDbgは移植可能なプログラムであり、インストールの必要はありません。 書き込み許可を持つフォルダーを作成し、 このアーカイブからファイルを書き換えます。



Microsoft Symbol Serverのセットアップ


Microsoft Symbol Server-Microsoftデバッグシンボルサーバー。これにより、純粋なアセンブラに加えて、関数と変数の名前も表示されます。 これは、コードを分析するときに非常に役立ちます。



これを行うには、次を実行します。



エクスプローラープロセスの接続


ご存知のように、タスクバーはWindowsエクスプローラープロセスの一部です。 OllyDbgを起動し、[ ファイル]-> [添付...]を選択します。 次に、 エクスプローラーを選択し、 添付をクリックします。

スクリーンショット








アタッチ、英語から-アタッチ-つまり、デバッガーをコンダクターにアタッチしてデバッグします。



次に、すべてのモジュールがロードされるまで待機します。 これには数分かかる場合があり、コンダクターはこの時点では応答しません。 ダウンロードが完了すると、右側のステータスバーに黄色の背景で一時停止と表示されます。つまり、プロセスは中断されます。 F9キーを押してプロセスを再開します。



注意、例外 :プロセスが一時停止され、ステータスバーに例外xxxxxxxxが表示される場合(下のスクリーンショットのように)、Shift + F9を押して、意図したとおりに例外を渡します。

スクリーンショット






エクスプローラー機能の概要


現在、コンダクターは、デバッガーOllyDbgの監視下で機能しています。 デバッグシンボルサーバーへの接続が正常に終了した場合、エクスプローラーの機能を確認できます。



まず、デバッガーのCPUウィンドウでエクスプローラープロセスモジュールを開きます。 これを行うには、モジュールウィンドウ(青い背景のE)を開き、 Explorerを右クリックして、[ CPUでコードを表示]を選択します

スクリーンショット






次に、コードを右クリックして、[ 検索 ] -> [名前 ]を選択します。 表示される前に、エクスプローラーに存在する関数のリストが表示されます。 リストでより便利に作業するには、名前でソートし、お気に入りのテキストエディターでテキストにコピーして貼り付けます。

スクリーンショット








そのため、グループ化を無効にする必要があります。 単語グループで検索を開始することは論理的です。 CTaskBtnGroupCTaskGroupの 2つのクラスがすぐにわかります。 一緒に、これらの2つのクラスには131個の関数があります。名前を簡単に確認するにはあまりありません。



名前の多くをよく知っているので、名前を調べるだけで必要な機能を見つけることができるかどうかを言うのは難しいです。 いずれにせよ、必要な関数はCTaskGroup :: DoesWindowMatchで 、その名前はウィンドウが一致するかどうかに変換されます

スクリーンショット






選択した機能を表示


おもしろい名前の関数を見つけました。それが何であるか見てみましょう。 OllyDbgに戻り、Ctrl + Gを押して、関数のアドレス(行の先頭の8桁の数字、この場合は00973629)に移動します。



PS ジャンプと呼び出しの強調表示をオンにすることをお勧めします。どの関数呼び出しと条件付き/無条件のジャンプがはっきりと見えるからです。

スクリーンショット






ここに関数があります:





列、左から右:アドレス、バイト、コマンド(アセンブラー)、コメント。

関数は青で、遷移は黄色でマークされています。 それらに焦点を当てます。



まず、いくつかの関数が呼び出され、結果に応じて遷移が発生します。 ここで私はそれらにとどまりません、私は彼らが私たちの仕事とは何の関係もないことに注意するだけです。



次に、3つの遷移があります。 最初は2番目と3番目を飛び越えます。 2番目と3番目は遠くどこかに行きます-どこを見てみましょう...



最初に

2つの構造を比較するWinAPI ILIsEqual関数は、すぐに目を引きます。 いくつかの分析の後、比較された構造がグループに関連付けられていることが明らかになります。 私たちの目標は、グループ化をキャンセルすることです。そのため、コンダクターが構造が等しくないと考えるようにコードを修正しましょう。







これを行うには、上記のスクリーンショットのように、無条件のJMPジャンプを記述します。



第二

初回と同様に、比較用のWinAPI関数、今度はテキスト-CompareStringOrdinalがすぐに表示されます 。 繰り返しますが、実験後、この比較はグループにも関連していることが明らかになります。 今回は、いわゆるアプリケーションID、つまりタスクバーがボタンをグループ化するアプリケーション識別子が比較されます。







繰り返しますが、無条件ジャンプを設定し、すべての識別子が異なるとエクスプローラーに考えさせます。



お試しください


たとえば、単純な逆アセンブラからのデバッガの大きな利点は、実行中のプロセスのメモリを直接変更するため、変更がすぐに有効になることです。 同じ理由で、エラーがプロセスのクラッシュを引き起こす可能性があるため、非常に注意する必要があります。



ノートブックの複数のコピーを開いて、それらがグループ化されていないことを確認してみましょう。







それは判明しました:)



実行中のプロセスのメモリでのみコードを変更したため、変更はプロセスが完了するまで続きます。



ボーナス-CTaskGroupの逆コンパイル版:: DoesWindowMatch関数


このコードの元の言語はC ++であるという事実にもかかわらず、純粋なCでの自己記述の逆コンパイルを以下に示します。



/* return: S_OK if there's a match, E_FAIL otherwise *pnMatch: 1: AppId matches, ITEMIDLIST is missing 2: AppId matches, ITEMIDLIST doesn't match 3: ITEMIDLIST matches 4: hWnd already exists (pTaskItem recieves the CTaskItem) */ HRESULT CTaskGroup_DoesWindowMatch(void /*CTaskGroup*/ *this, /*IN*/ HWND hCompareWnd, /*IN*/ ITEMIDLIST *pCompareItemIdList, /*IN*/ WCHAR *pCompareAppId, /*OUT*/ int *pnMatch, /*OUT*/ void /*CTaskItem*/ **pTaskItem) { void /*CTaskItem*/ *CompareWndTaskItem; int nMatch; HRESULT hr; nMatch = 0; hr = this->lpVtbl->GetItemFromWindow(this, hCompareWnd, &CompareWndTaskItem); if(SUCCEEDED(hr)) // if an item for this window already exists { if(pTaskItem) { *pTaskItem = NULL; IUnknown_Set(pTaskItem, CompareWndTaskItem); } nMatch = 4; CompareWndTaskItem->lpVtbl->Release(CompareWndTaskItem); } else { if(!(this->SomeFlags & 0x80000000)) { if(pCompareItemIdList && this->pItemIdList && ILIsEqual(pCompareItemIdList, this->pItemIdList) != 0) { nMatch = 3; hr = S_OK; } else if(pCompareAppId && CompareStringOrdinal(this->pAppId, -1, pCompareAppId, -1, TRUE) == CSTR_EQUAL) { hr = S_OK; if(pCompareItemIdList && this->pItemIdList) nMatch = 2; else nMatch = 1; } } } *pnMatch = nMatch; return hr; }
      
      







ターンキーソリューション



私が作者である7+ Taskbar Tweakerプログラムは、アプリケーションIDによってグローバルに選択的にグループ化を無効にすることができます。 さらに、さらに興味深いタスクバー設定があります。







おわりに



時々私はハブで記事を開きますが、それは私にとっては面白そうですが、読み始めてからはそれほど面白くない(またはあまり明確ではない)ことを理解しています。 そのような場合、私はしばしば結論に至ります。



同じ理由でここにいる場合、議論されたことについて簡単に説明します。

デバッガーを取り、コンダクターに接続しました。 次に、目的の機能を見つけ、それを変更して、作成されたウィンドウが既存のグループのいずれにも適合しないとエクスプローラーが考えるようにしました。 この変更により、エクスプローラーはタスクバーのボタンのグループ化を停止しました。



All Articles