プロフィール

髭山髭人(ひげひと)

自分の書いた記事が、一人でも誰かの役に立てば...
活動信条の一つとして「貴方のメモは、誰かのヒント」というのがあります。

このサイトについて

本家HP packetroom.net から切り離した いわゆる技術メモ用のブログで、無料レンタルサーバーにて運用しています。広告表示はその義務なのでご容赦。
XREA さんには長年お世話になっています

chrome.dll 改造メモ - ツールバーから拡張機能ボタンやらアバターボタンやらを吹き飛ばす

※ ほぼネタ枠

バイナリレベルでアイコンボタンを非表示にする

ToolbarView::Init() という箇所で、幾つかのボタンアイコンを配置する様な処理が司られているようです。
これら処理が含まれていそうな箇所をバイナリ上で特定して書き換える事で、
内部で作成されたボタンアイコンを意図的に配置させない様に(=非表示に)できます

Chrome.dll の中から ToolbarView::Init() に相当する処理を探る

https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/toolbar/toolbar_view.cc;l=300 https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/ui/views/toolbar/toolbar_view.cc

参照文字列検索機能のRegex(正規表現)を用いる

※ 画像は執筆時 Chromium 88.0.4324.0 Developer Build x64

経験則上、

  • "ExtensionsToolbarMenu"
  • "GlobalMediaControls"
  • "AutofillEnableToolbarStatusChip"
  • "browser.show_home_button"

の文字列がそこそこ近く連続して固まっている場所が "それっぽい" ので、 以下の正規表現で調べて当該しそうな箇所を探る

↓コピペ用
AutofillEnableToolbarStatusChip|ExtensionsToolbarMenu|GlobalMediaControls|browser.show_home_button

モジュール解析機能を使い、「逆コンパイル」→「ファンクション」で Snowman を呼び出して関数ブロックを目視チェックしていく。
void を返す中々大きな function になったら、いよいよあやしい。

拡張機能ボタンアイコンをすっ飛ばす

上記で特定(仮定)した ToolbarView::Init() の関数内にて、
参照文字列として紐づけられている "ExtensionsToolbarMenu" の箇所を見つける。
そこでは test で比較し、je で条件付きジャンプさせている箇所が見つかる..と思う。

↓ 執筆時の該当箇所・近辺のバイナリメモ

48:8B01                 | mov rax,qword ptr ds:[rcx]          |
FF90 F8010000           | call qword ptr ds:[rax+1F8]         |
BD 00000000             | mov ebp,0                           |
84C0                    | test al,al                          | ← このへん
75 6E                   | jne chrome.7FFC1241BEAF             | ← このへん
48:8D0D A8409F02        | lea rcx,qword ptr ds:[7FFC14E0FEF0] | &"ExtensionsToolbarMenu"
E8 B3876DFD             | call <chrome.sub_7FFC0FAF4600>      |
84C0                    | test al,al                          |
74 28                   | je chrome.7FFC1241BE79              |
B9 B8040000             | mov ecx,4B8                         |
E8 A1C80602             | call chrome.7FFC144886FC            |

ここの 75 (jne = 条件付きジャンプ) 6E を、

84C0    test al,al
EB 6E   jmp chrome.7FFC1241BEAF

として、EB (jmp = 無条件ジャンプ) 6E に置き換える。

こうする事でソース中、↓ 以下の処理がすっ飛ばされる

if (extensions_container)
    extensions_container_ = AddChildView(std::move(extensions_container));

恐らくアセンブラ中では
「extensions_container が無かったら(84C0 test al,al)、次の処理へ移動してくれ~(75 6E jne chrome.XXXXXXXX)」
という事なのだと思う。
74→EB に書き換えたので、「extensions_container があっても無くても、次の処理へ移動してくれ~」になっているかと。

84 C0 75 6E 48 8D 0D A8 40 9F 02  
↓
84 C0 EB 6E 48 8D 0D A8 40 9F 02  
      ^^

アバターアイコンをすっ飛ばす

位置的には同じく void ToolbarView::Init() の内部。
バイナリ的にも、拡張機能ボタンアイコンを吹き飛ばした個所から幾らか下の部分にあるようです

for (auto* button : std::array<views::Button*, 5>{back_, forward_, reload_,
                                                  home_, avatar_}) {
  if (button)
    button->set_tag(GetViewCommandMap().at(button->GetID()));
}

にて、作成した各種ボタンを配置している処理に介入し、 avatar_ の処理だけ成さない様に弄るイメージで触ってました。

先程弄った当該箇所から幾分か下に、 testje がセットになったブロックが5つほどある。
これが for に相当していると判断

5番目の

4D:85E4            | test r12,r12               |
74 27              | je chrome.7FFC02B2C088     |

を弄り

4D 85 E4
EB 27

で強制ジャンプ

Chromium 88.0.4324.0(Developer Build) (x64)

4D 85 E4 74 27 48 8D 54 24 70
 ↓
4D 85 E4 EB 27 48 8D 54 24 70
         ^^

GoogleChrome だと

D0 04 00 00 4D 85 E4 74 35 4D 8B 86
↓
D0 04 00 00 EB 36 90 74 35 4D 8B 86
            ^^ ^^ ^^

という感じで二段ジャンプを仕込んだ

  • おまけ

    最初は未ログインのChromiumにてバイナリを弄り、

    84 C0 74 1E B9 C8 03 00 00
    ↓
    84 C0 EB 1E B9 C8 03 00 00
        ^^

    ―という感じで取り廻していたのですが、これと同じような方法で GoogleChrome を弄った場合
    ログインしていると落ちてしまったので別のアプローチをとりました。 恐らく、ログイン済みだとアバターアイコンが変わるので、そのあたりにうまく対応てきていないものと推測。

ちなみにシークレットモード(ゲストモード?)で起動した場合どうなるのかは未確認です。
最悪落ちるかもしれないので、そのあたりご留意を。

まとめ画像

最後に ToolbarView::Init() と思わしき箇所付近の画像を置いておきます
上の方は 拡張機能ボタンアイコンを吹き飛ばすメモ
下の方は アバターボタンアイコンを吹き飛ばすメモ