☆ドライバのソースを変更した場合、バイナリの何処が変わるか調べてみました

前回の ☆バイナリファイルを書き換えてUSB無線LANクライアントを認識させる は、depmodが調べているセクション、シンボルをとりあえず書き換えてみただけです。
この2箇所の書き換えは、必要ではありますが、必要十分であるかは不明です。
本当はUSB無線LANクラアントのカーネルモジュールが備えるべきインターフェースの仕様がわかればよいのですが、検索してもそのものズバリは見つけられませんでした。

2010/06/01 追記
USB_DEVICEマクロを使ってIdVendor,IdProductの指定をしている
("__mod_usb_device_table"のmatch_flagsが0x03)
場合は前回の方法で問題ないとおもわれますが、match_flagsの値がそれ以外の場合は十分でないようです。
hitoさんによる此方の投稿を参照してください。
https://forums.ubuntulinux.jp/viewtopic.php?pid=60947#p60947

そこでカーネルモジュールのソースの箇所だけUSBデバイス認識用の"idProduct"を書き換え、ビルドしてバイナリファイルの何処が変わったか比較してみることにしました。
RT2870_LinuxSTA_V2.3.0.0.tar.tar.bz2を使用して検証します。(これは私の環境で正攻法で動かなかったものなので、材料としては若干不安なのですが。)
結果を先に書くと、前回のバイナリ書き換えはおそらく正解(必要十分)であろうと思われます。

比較用のモジュールをビルドする際は同一のパスでビルドする方が良いです。
".rodata.str1.4"にはパスを保持している箇所があって、比較の際にそこが差分として出てくるとかなり面倒です。
パスの長さが違うとファイルサイズやシンボルのファイル先頭からのオフセットも違ってくる可能性がありそうです。

●ソースコードの変更箇所(および自動的に変更された箇所)

■common/rtusb_dev_id.c

下記がソースを手で変更する唯一の箇所です。

--- a/common/rtusb_dev_id.c 2009-11-26 15:22:40.000000000 +0900
+++ b/common/rtusb_dev_id.c 2010-05-30 21:14:50.800580320 +0900
@@ -59,7 +59,7 @@
  {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */
  {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */
  {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */
- {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */
+ {USB_DEVICE(0x2019,0xED14)}, /* Planex Communications, Inc. */
  {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */
  {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */
  {USB_DEVICE(0x14B2,0x3C07)}, /* AL */

■os/linux/rt2870sta.mod.c

RT2870_LinuxSTA_V2.3.0.0.tar.tar.bz2では自動で変更されます。
MODULE_INFOの部分が変わるのは実施前に想定していませんでした。

--- a/os/linux/rt2870sta.mod.c 2010-05-30 21:17:10.616580922 +0900
+++ b/os/linux/rt2870sta.mod.c 2010-05-30 21:19:10.388580922 +0900
@@ -151,7 +151,7 @@
 MODULE_ALIAS("usb:v0DF6p002Dd*dc*dsc*dp*ic*isc*ip*");
 MODULE_ALIAS("usb:v14B2p3C06d*dc*dsc*dp*ic*isc*ip*");
 MODULE_ALIAS("usb:v14B2p3C28d*dc*dsc*dp*ic*isc*ip*");
-MODULE_ALIAS("usb:v2019pED06d*dc*dsc*dp*ic*isc*ip*");
+MODULE_ALIAS("usb:v2019pED14d*dc*dsc*dp*ic*isc*ip*");
 MODULE_ALIAS("usb:v07D1p3C09d*dc*dsc*dp*ic*isc*ip*");
 MODULE_ALIAS("usb:v07D1p3C11d*dc*dsc*dp*ic*isc*ip*");
 MODULE_ALIAS("usb:v14B2p3C07d*dc*dsc*dp*ic*isc*ip*");
@@ -198,4 +198,4 @@
 MODULE_ALIAS("usb:v100Dp9031d*dc*dsc*dp*ic*isc*ip*");
 MODULE_ALIAS("usb:v0DB0p6899d*dc*dsc*dp*ic*isc*ip*");
 
-MODULE_INFO(srcversion, "BFE72125F5BC16053AC2BDE");
+MODULE_INFO(srcversion, "F9CA397B948AAF46EC1F3E8");

●バイナリが変わった箇所

"cmp -l"を使用してカーネルモジュールが変わった位置を調べました。
出力は下記の通りでした。

"cmp -l"はreadelfやodと違いファイルの先頭バイトの位置が"1"になっているので、"cmp -l"で出た差分をodで調べる際はオフセットの値に注意が必要です。
値は8進数でダンプされます。

そのままでは見にくいので、連続する領域の先頭アドレスと長さ、該当するセクションに変換すると下記の通りです。

start   length  Section
    68  20      .note.gnu.build-i
486964   1      .rodata.str1.1
491211  23      .modinfo
494162   2      .modinfo
520852   1      .data

cmp -l の出力
69  53  51
    70 324 343
    71 114 131
    72 302 122
    73 262 135
    74 153 213
    75 225 136
    76 260 221
    77 334 157
    78 243  75
    79 213 135
    80 141 361
    81 154 145
    82  17 350
    83  52 224
    84   6 232
    85 147 104
    86 342  21
    87 215 246
    88 102 253
486965  67  71
491212 102 106
491213 106  71
491214 105 103
491215  67 101
491216  62  63
491217  61  71
491218  62  67
491219  65 102
491220 106  71
491221  65  64
491222 102  70
491223 103 101
491224  61 101
491225  66 106
491226  60  64
491227  65  66
491228  63 105
491229 101 103
491230 103  61
491231  62 106
491232 102  63
491233 104 105
491234 105  70
494163  60  61
494164  66  64
520853   6  24

■ソース修正が反映されるバイナリの箇所
▼".modinfo"セクションのalias

"elfdump -p '.modinfo'"の出力の差分だけ示します。(-uをつけないdiff)
srcversionの変更は予想していなかったものですが、ソースの変更がそのまま反映されています。
下記の2箇所に相当します。

start   length  Section
491211  23      .modinfo
494162   2      .modinfo

9c9
<   [    e0]  srcversion=BFE72125F5BC16053AC2BDE
---
>   [    e0]  srcversion=F9CA397B948AAF46EC1F3E8
55c55
<   [   c60]  alias=usb:v2019pED06d*dc*dsc*dp*ic*isc*ip*
---
>   [   c60]  alias=usb:v2019pED14d*dc*dsc*dp*ic*isc*ip*

▼".data"セクションの"__mod_usb_device_table"シンボル

前回と同じ要領で"__mod_usb_device_table"シンボルをダンプした結果の差分だけ示します。
下記の箇所に相当します。

start   length  Section
520852   1      .data

21c21
< 0520848 0003 2019 ed06 0000 0000 0000 0000 0000 0000 0000
---
> 0520848 0003 2019 ed14 0000 0000 0000 0000 0000 0000 0000

■変わると想定していなかったが変わったバイナリの箇所
▼".note.gnu.build-i"セクション
start   length  Section
    68  20      .note.gnu.build-i

このセクションは こちらに よると
"ファイルを識別する為のユニークなビットフィールド"が埋め込まれているようです。
20Byteの長さにわたって差分が出たので160-bit SHA1 hash だと思われます。
ひょっとしたら改ざんを検出するためにこの部分をチェックするシステムも存在するのかもしれませんが、
前回のエントリで動いていたのでUbuntuはチェックしていないと思われます。

▼".rodata.str1.1"セクションのビルドした時刻
start   length  Section
486964   1      .rodata.str1.1

"readelf -p '.rodata.str1.1'"でセクションの内容を見てみると、主にメッセージに使用される文字列などが格納されているようです。
変更前後のセクションのダンプを比較すると下記の様になっていました。
ビルドしたタイムスタンプが格納されている部分で違っています。
ここはバイナリを直接書き換える際に修正しなくても問題なさそうです。
@@ -968,7 +968,7 @@
 
   [  246b]  ConnStatus is not connected
 
-  [  2488]  21:17:00
+  [  2488]  21:19:00
   [  2491]  May 30 2010
   [  249d]  2.3.0.0
   [  24a5]  Driver version-%s, %s %s

0 件のコメント:

コメントを投稿