プロフィール

髭山髭人(ひげひと)

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

このサイトについて

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

サ終した Qrunch (クランチ) と呼ばれる技術ブログサービスに掲載していた記事も含まれます

Chrome.dll のバイナリ内で LocationIconView を特定してスキーム文字列を消したり LocationBarView を特定して、横幅の制限を撤廃したりする

趣旨

別途公開しているGoogleChromeの横幅制限値を撤廃させる手法の延長線上として、 より快適にソシャゲ用ブラウザとして取り廻すために自分が仕込んでいる設定を記載しています。

書き換え個所メモ

先にまとめておきます。 特に表記が無い場合は GoogleChrome Official Build x64Chrome.dll となります

スキーム文字列の除去

Chrome.dll のバイナリ内を検索し、前者で一件だけヒットする該当箇所を、後者へ書換

GoogleChrome v89.0.4389.114

FF 50 08 84 C0 0F 85 30 01
↓
FF 50 08 84 C0 90 E9 30 01
               ^^ ^^

jne を jmp 化

GoogleChrome 88.0.4324.182 Official Build x64 および
Chromium 88.0.4324.0 Developer Build x64 時

FF 50 08 84 C0 74 07 31 F6
↓
FF 50 08 84 C0 90 90 31 F6
               ^^ ^^

ロケーションバーの横幅制限撤廃

v89.0.4389.114

一連の計算処理を省略 (je→jmp化)

0F 84 87 01 00 00 48 8B 07 48 8D 74 24 30
↓
90 E9 87 01 00 00 48 8B 07 48 8D 74 24 30
^^ ^^

v88.0.4324.182

ebp へ 実数 0 の強制代入

03 6C 24 28 01 D5 0F 48 E9
↓
03 6C 24 28 BD 00 00 00 00
            ^^ ^^ ^^ ^^ ^^

Chromium 88.0.4324.0 Developer Build x64

横幅に関する計算処理を 74のje から EBのjmp にすり替えて強制省略

BB 00 00 00 00 74 71 4C 8D 77 F0
↓
BB 00 00 00 00 EB 71 4C 8D 77 F0
               ^^

スキーム文字列情報に関する当該ソースメモ

当時 chrome://flagsenable-mark-http-as に相当していた処理です。
「保護されていない通信」の文言を消す設定ですね。
https://www.chromium.org/Home/chromium-security/marking-http-as-non-secure
特にグラブルユーザーの方なんかは、この設定が残っていた時代にココを切っていたはず..

https://cs.chromium.org/chromium/src/chrome/browser/ui/views/location_bar/location_icon_view.cc?l=130&gsn=ShowText https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/ui/views/location_bar/location_icon_view.cc

↓ 昔控えていた時のソースメモ

bool LocationIconView::ShouldShowText() const {
  if (delegate_->IsEditingOrEmpty())
    return false;

  const auto* location_bar_model = delegate_->GetLocationBarModel();
  const GURL& url = location_bar_model->GetURL();
  if (url.SchemeIs(content::kChromeUIScheme) ||
      url.SchemeIs(extensions::kExtensionScheme) ||
      url.SchemeIs(url::kFileScheme)) {
    return true;
  }

  return !location_bar_model->GetSecureDisplayText().empty();
}

↓ 執筆時のソースメモ

bool LocationIconView::GetShowText() const {
  if (delegate_->IsEditingOrEmpty())
    return false;

  const auto* location_bar_model = delegate_->GetLocationBarModel();
  const GURL& url = location_bar_model->GetURL();
  if (url.SchemeIs(content::kChromeUIScheme) ||
      url.SchemeIs(extensions::kExtensionScheme) ||
      url.SchemeIs(url::kFileScheme) ||
      url.SchemeIs(dom_distiller::kDomDistillerScheme)) {
    return true;
  }

  return !location_bar_model->GetSecureDisplayText().empty();
}

この処理に false を必ず返させれば、「保護されていない通信」や「Chrome」(拡張機能のページ)などのスキーム文字列を、ブラウザのロケーションバー上に表示させない様にできる。 ( ※ ただし、アイコンの処理は別件 )

過去特定したバージョン時のメソッド名は ShouldShowText() だったのだが、いつからか GetShowText() に変更された模様

バイナリ上における LocationIconView:: 付近の特定

"chrome" "chrome-extension" "file"
の参照文字列が3つ近い位置に含まれている個所を探し出す。
いつからか "chrome-distiller" も含まれるようになった

各種候補が多すぎて、単純に参照文字列だけで検索すると物凄い量なんだけど、他にも参照となる足掛かりもあるので、絞っていけば特定しやすい。
以下は参照文字列内における当該箇所のスクリーンショット。
(GoogleChrome v88.0.4324.182 Chrome.dll)

バイナリバージョンにもよるけど、画像のスクロール箇所でおおよその目途が付くかも。

↓ 炙り出し用の参照文字列検索でつかう正規表現。コピペでどうぞ
"chrome"|"chrome-extension"|"file"|"chrome-distiller"|"ExtensionsToolbarMenu"

で、こちらの画像が全体における当該箇所。

content::kChromeUIScheme"chrome" 相当
extensions::kExtensionScheme"chrome-extension" 相当
url::kFileScheme"file" 相当
dom_distiller::kDomDistillerScheme"chrome-distiller" 相当

FF50 08     call qword ptr ds:[rax+8]
84C0        test al,al
74 07       je chrome.xxxxxxxxxxxxx
31F6        xor esi,esi
E9 1D010000 jmp chrome.xxxxxxxxxxxxx

testje の箇所で、不成立にさせて処理を飛ばす。
今回は je を 90で埋めて nop 化させ、test の結果が何であれ je で飛ばない様にした。

FF 50 08 84 C0 74 07 31 F6
↓
FF 50 08 84 C0 90 90 31 F6
               ^^ ^^

※ GoogleChrome 88.0.4324.182 Official Build x64 時の画像

芋づる式に LocationBarView を見つけ出す

今回特定した LocationIconView::GetShowText() は、
int LocationBarView::GetMinimumLeadingWidth() の中からも呼ばれている。

この為、ブレークポイント貼りつつ横幅を操作した時に停まった個所にて ret した呼び出し元を探れば、こっちも特定できる

https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/location_bar/location_bar_view.cc;l=840 https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/ui/views/location_bar/location_bar_view.cc

int LocationBarView::GetMinimumLeadingWidth() const {
  // If the keyword bubble is showing, the view can collapse completely.
  if (ShouldShowKeywordBubble())
    return 0;

  if (location_icon_view_->GetShowText()) // ←★ココで呼んでる
    return location_icon_view_->GetMinimumLabelTextWidth();

  return GetLayoutConstant(LOCATION_BAR_ELEMENT_PADDING) +
         location_icon_view_->GetMinimumSize().width();
}

更に int LocationBarView::GetMinimumLeadingWidth()
gfx::Size LocationBarView::GetMinimumSize() からも呼ばれているので、芋づる式にこちらも特定できる

https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/location_bar/location_bar_view.cc;l=427

gfx::Size LocationBarView::GetMinimumSize() const {
  const int height = GetLayoutConstant(LOCATION_BAR_HEIGHT);
  if (!IsInitialized())
    return gfx::Size(0, height);
  const int inset_width = GetInsets().width();
  const int padding = GetLayoutConstant(LOCATION_BAR_ELEMENT_PADDING);
  const int leading_width = GetMinimumLeadingWidth(); // ←★ココで呼んでる
  const int omnibox_width = omnibox_view_->GetMinimumSize().width();
  const int trailing_width = GetMinimumTrailingWidth();

  int alt_width = leading_width + padding + trailing_width;
  int width = inset_width + std::max(omnibox_width, alt_width);
  return gfx::Size(width, height);
}

ちなみにこの LocationBarView::GetMinimumSize() は、Chromeにおける横幅制限値計算の一端を担っており、従来の横幅制限撤廃のバイナリ値同様に、ここを見つけ出すのが個人的な最終目標の一つでもあった

ロケーションバー内部の横幅制限を撤廃させる

GoogleChrome v88.0.4324.182

執筆時のバイナリでは ebp への代入を改竄

// 変更前
| 036C24 28        | add ebp,dword ptr ss:[rsp+28]     |
| 01D5             | add ebp,edx                       |書換
| 0F48E9           | cmovs ebp,ecx                     |書換
| 48:8B7424 38     | mov rsi,qword ptr ss:[rsp+38]     |
| 892E             | mov dword ptr ds:[rsi],ebp        |
| 8B4424 2C        | mov eax,dword ptr ss:[rsp+2C]     |
| 31C9             | xor ecx,ecx                       |
// 変更後
| 036C24 28        | add ebp,dword ptr ss:[rsp+28]     |
| BD 00000000      | mov ebp,0                         | 強制代入
| 48:8B7424 38     | mov rsi,qword ptr ss:[rsp+38]     |
| 892E             | mov dword ptr ds:[rsi],ebp        |
| 8B4424 2C        | mov eax,dword ptr ss:[rsp+2C]     |
| 31C9             | xor ecx,ecx                       |

RBP(ebp)に対して色々加算している箇所の一部(後半)を弄り、 実数 0 の強制代入とした。

03 6C 24 28 01 D5 0F 48 E9
↓
03 6C 24 28 BD 00 00 00 00
            ^^ ^^ ^^ ^^ ^^

ちなみにRBP(ebp)の最終的な値は、従来だと0xCD(205) だった (GoogleChrome 88.0.4324.182)

逆コンパイル式では、この構造体に入る gfx::Size 型でほぼ間違いない。

struct s0 {
    int32_t f0;
    int32_t f4;
};

Chromium 88.0.4324.0 Developer Build x64

アセンブラ処理がソースコード同様二段式で呼ばれている様で、ret を足掛かりに LocationBarView::GetMinimumLeadingWidth() を呼ぶ LocationBarView::GetMinimumSize() を探り、 横幅に関する計算処理を 74のje から EBのjmp にすり替えて強制省略する形をとった

※ 参考画像は省略

BB 00 00 00 00 74 71 4C 8D 77 F0
↓
BB 00 00 00 00 EB 71 4C 8D 77 F0
               ^^