chouett0's note

掃きだめ的なsomething

Chrome使用時にフリーズする問題の簡易的な解決法について

はじめに

Chromeを使用しているときになぜかフリーズしてしまう問題があり、その問題の根本的なものではないにせよ
簡易的に解決したいと思い簡易的なツールを作成したのでその経緯とちょっとした説明の記事です。 以下からDLして任意の場所に保存するだけで使用できます。

github.com

動機

先ほども書きましたが、Chromeを使用しているときになぜかフリーズしてしまう問題があり特に私のラップトップではChrome起動状態でスリープ復帰するとほぼ必ずフリーズしてしまいます。 タスクマネージャ立ち上げてプロセスを落とせばよいのですがタスクマネージャを立ち上げてプロセス探して落とす、という動作をいちいち行うのは面倒なので単純動作で行えるよ宇にしたいと考えて作成したのが「Ch0romeKill3er」です。

実装

仕組みというほどではありませんが内部的には
- 特定のプロセス名からプロセスIDを取得 - プロセスのハンドラを取得 - プロセス強制終了 という処理を行っています。
一応拡張性を持たせたいと思いmain関数で呼び出すKillProcess関数に任意のプロセス名を与えるとKillできるようになっています。

まとめ

幼稚園児でも実装できるレベルのツール && n番煎じ

Apple製品のゼロ幅非結合子処理の際に生じるクラッシュについて

初めに

つい先日、最新のものを含むiOSOS X,Watch OSに特定の文字列を送信することでクラッシュするバグが発見されました。  

gigazine.net

詳細についてはこちらを参照していただくとして、今回はこの現象を実際に検証してみた結果となります。
本来は画像を張りたかったのですがスクショを取り忘れていたので文字のみでの解説となります。
なお、今回の検証は個人の端末を用いてとなりますので第三者へ向けて行っていません。 またこの記事での内容を実際に行うと最悪の場合端末が利用できなくなる場合がありますのであくまで自己責任でお願いします。

追記: 2/21に公開されたiOS11.2.6へアップデートする事で今回のバグが修正されました

検証環境

今回の検証では
* iPhone5 iOS10.2 * iPhone6 iOS11.1.2 この2台で行い、文字列の送信・生成はPCとAndroid端末から行いました。
文字列を受信、通知させるため方法としてYahooメールアカウントを登録したiOS標準のメールクライアントとSMSにて行いました。
本来はTwitterを用いて行う予定でしたが、すでに対策がなされているようでWeb・モバイルともにバグを引き起こす文字列は送信できなくなっていました。

検証方法

まず初めにYahooメールを用いた検証について記述する前に、検証で用いる文字列について説明したいと思います。
今回問題となっている文字列は「テルグ語」と呼ばれる言語のテルグ文字という文字によるものであり、この文字を表現する際に必要な「ゼロ幅非結合子(以下ZWNJ)」という制御文と特定の組み合わせの際にのみ発火する文字のようです。
詳しい説明は

japanese.engadget.com

こちらに掲載されているので重要な部分のみを抜粋すると、今回のバグは「子音1、ヴィラーマ(発音区別符号)、子音2、ZWNJ 、母音」という組み合わせの際に発火するようです。
ということで、初めに検証のために利用したのがおそらくほとんどの記事で扱われている「U+0c1cU+0c4dU+0c1eU+200cU+0c3e」というUnicodeで表現される文字列です。当然といえば当然ですが、クラッシュを引き起こす文字列をニュース記事でそのまま記載することはまずないと思われますので、まずはこのUnicodeを実際の文字列に直していく作業です。

Unicodeから可読文字列に変換する方法はたくさんあると思われますが、私は

https://www.marbacka.net/msearch/tool.php

http://www.eva.hi-ho.ne.jp/cgi-bin/user/zxcv/decodeUTF8.cgi?req=oct&oct=343+222+242+343+202+244

この2つを用いて変換を行いました。

検証

それでは実際に検証を行う手順を記述していきます。
まずメールですが、あらかじめ検証機にメールの設定を入れておきます。
今回は標準メールクライアントを用いたので、まずはメールクライアントを開き「Yahooメール」を選択し、
メールアドレスとPWを入れて完了です。
送信する際はPCからブラウザ上で行いました。
一応件名と本文のどちらが表示されても発火するように両方に文字列を挿入しました。
両方の端末でメールクライアントを起動した状態で実際に送信してみると、正常にアプリケーションがクラッシュして再起動しました。
次に、バナーでの発火の検証をしてみるとバナーが表示される瞬間にSpringBoardがクラッシュして再起動していたことから
今回のバグの危険度がわかります。

メールソフトでの発火は確認できたので、その次にSMSを用いた検証を行いました。
この検証ではSIMを挿入したAndroid端末から同じくSIMを挿入したiPhone6にバグを引き起こす文字列を送信しました。
この検証でもメールのときと同じ結果で、アプリケーションを開いた状態ではアプリケーションがクラッシュし、バナーに表示させるとシステムがクラッシュしてしまいました。

ここまでの検証は記事にある内容の模範に過ぎず、あまり面白みはありませんでした。
そこで、私の先輩からの疑問でほかの組み合わせや少ない文字列では発火しないのかを検証してみました。
あまり長い文章だと読みにくくなってしまうので概要だけ説明すると、まず、今回の検証で用いた文字列から1文字分削った
文字列を送信してみましたが発火することはなく、次に長さは変わらずZWNJを別の場所に移して見たところやはり発火することはありませんでした。
次に、検証方法のところで記述した特定の組み合わせに従い最後の母音を別の文字に置き換えてみたところ正常に発火していました。
これらのことを踏まえると、やはり特定の組み合わせの文字列をZWNJを利用して処理する際にバグが発生していることがわかりました。

まとめ

今回の検証はただバグを引き起こす文字列を送信してクラッシュすることを確認するだけで詳しい原因やほかの組み合わせまでは調査できませんでした。
また、検証で用いた検証機が2台だけだったためそのうちより低いバージョンの端末やMac,Apple Watchでも発火するのかを検証してみたいなと思います。
ここからは完全に余談となりますが、今回メールとSMSを用いたのには理由があり本来であればTwitterを利用したかったのですが、どうやらweb・mobile両方で既に対策が行われているようで投稿はもちろん名前にすら入力できないようにされていました。
しかし、某緑のSNSアプリケーションでは対策がなされておらず、

本来検証する予定ではないプライベート機で発火してしまう事態になってしまいました。
さらに、連携させているApple Watchにも最悪の場合通知が行ってしまいクラッシュする羽目になりかけたり復旧する際に
MacBook Proで無意識にLINEを起動しようとして発火することを思い出したりと散々な思いをしたので早急にiOS11.3がリリースされることを祈ります。

割り込み処理について

初めに

今回の記事も前回同様、技術的な内容ではなく私が理解を深めるためのメモであり
特に面白みのないものとなっています。
また、誤字脱字、間違っている点も多くあると思われますのでご了承ください。

割り込み

  • 割り込みとは、ハードウェアから特定の処理を要求されたときに、一時的にソフトウェアの処理を中断させて要求された処理を実行することをいう。
    例)キーボードコントローラ->キーが押されたときにCPU割り混みを信号を出し、CPUはどのキーが押されたのかをキーボードコントローラから読み出す処理を行う
  • 割り込みを行うことでCPUがハードウェアを常に監視する必要性がなくなる

  • 割り込みの種類

    • 例外(Exception)
    • 割り込み要求(IRQ: Interrupt ReQuest)
    • ソフトウェア割り込み

例外(Exception)

  • CPUが異常を検出した際に発生する。
  • ページングで割り当てられたページがない時などに異常を検出して例外処理を行う。
  • 主にソフトウェアでの処理で異常を検出する
    例) 存在しない配列要素へのアクセス

割り込み要求

  • CPUの周辺のハードウェアから要求があった場合に発生する信号
  • CPUのピンとハードウェアは電気的にワイヤで接続されており、ハードウェアは割り込み要求を出すときにそのワイヤへ電気信号を出すことでCPUに伝達する
  • CPUはワイヤの信号が変化したことを検出すると要求にあった割り込みハンドラを呼び出す。
  • この信号はソフトウェアの動作に関係なくいつ信号が送信されるかはわからない
  • CPUはPIC(Programmable Interrupt Controller)とわいやでIRQラインが結ばれている。
  • PICはフロッピーディスクコントローラやDMAコントローラなどの割り込み要求を一括してCPUに伝える。

ソフトウェア割り込み

  • 例外とは異なり、意図的にソフトウェアが発生させることができる割り込み。
  • INT命令がソフトウェア割り込みでを発生させるめいれいであり、主にユーザプログラムがシステムコールを呼び出すときに使用する。

割り込みベクタと割り込みハンドラ

  • 割り込みが発生したときにどのハンドラを呼び出すのかを記述したものを割り込みハンドラという。
  • 割り込みベクタには割り込みハンドラのアドレスが順番に並んでいるようなテーブルのイメージで番号がつけられている。
  • 割り込みが発生したときに、その割り込みに対応した番号のハンドラは呼び出されることで、割り込み処理が行われる。
  • 割り込みベクタのうち、例外の部分はCPU仕様によって決まっている。

GDT(Global Descriptor Table)

  • 64bitを一つのデータとした配列
  • 一つの要素である64bitので0他派セグメントディスクリプタといい、セグメントの開始位置、セグメントの崔伊豆アクセス権限などを細かく設定できる。
  • このセグメントディスクリプタは最大で8192個まで持つことができる。

IDT(Interrupt Descriptor Table)

IDTR

  • CPUが持っている特殊なレジスタを指す。
  • LIDT命令を使用してIDTRにIDTのサイズとアドレスを格納する。
  • IDTRにIDTのサイズとアドレスが格納されている際にわりこみが発生することでCPUはIDTを参照し、対応する割り込みハンドラの処理を行う。

LDT(Local Descriptor Table)

参考文献

softwaretechnique.jp

VyOS

# 宣伝
harekaze.com


# 初めに
Harekaze Advent calendar 14日目の記事となります。
adventar.org


本来は技術的な記事にしたかったのですが、進捗が思ったように出なかったので
今回はVyOSにて家庭内ネットワークを再構築しようとした際に気づいたことのまとめを書いていこうと思います。

# VyOSについて
VyOSとは、Vyattaと呼ばれるLinuxベースのネットワークOSの無償版であるVyatta CoreというものからフォークされたOSです。
UNIXLinuxに近いと考えるとわかりやすいかもしれません(実際は全然違いますが)
このVyOSですが、実機にインストールできるだけでなくVBox等でVMとしても動作させることができる非常に面白いOSです。

# Edge Router
Edge Routerとは、先ほどのVyOSをベースに作られたOSを搭載した小型の高機能ルータのことで、一般的なルータの機能はもちろんのこと
CiscoYamahaなどの企業向けルータでできることは大体できるにもかかわらず10k以内で購入できる非常に素晴らしいルータのことです。
実際の我が家の家庭内ネットワークではこのルータを利用していて、小さいながらもなかなか頑張ってくれています。

# 気づいた点
## VyOSではTrackやTrigger shutdownと呼ばれる機能がない
まず、TrackやTrigger Shutdownとは、VRRPという冗長化機能を使用する際に設定されるもので

[ インターネット ]
/ \
/ \
[ Router ] [ Router ]
| |
[ L2SW ]
|
[ PC ]

例としてPC側にVRRPを設定してこのような構成を組んでいるときに、インターネット側が切断されてしまったと想定すると
PC側の回線は接続されている状態なのでVRRPのみでは障害検知ができません。
そこで、先ほどの機能を設定することで対向の回線がDownした際にはPC側もDownするので冗長化構成が効率的に気のすることになります。
そのTrackやTrigger shutdownと呼ばれる機能ですが、私の調べた限りではVyOSに存在しないようです。
とても残念ではありますが、VRRP構成を組んでいるルータ間で渡となる回線を作り、OSPFで自動的にルーティングさせることで回避できます。

# VRRPの仕様
先ほども取り上げたVRRPですが、私はどうしてもこの構成をインターネット側に取り入れたかったのですが、某comのONUの仕様で
MACアドレスの一致した機器以外は接続できないためVRRPは構成できない状態でした。
そこで、VRRPを構成する機器のMACアドレスを同一にすれば問題が解決するのではないかと考えて実際に行ってみました。
結果としては成功したものの、不安定でありなかなかうまいようには行きませんでした。
しかし、私はこの際に両機器がVRRPの切り替わりを正常に行えていることに疑問を抱きました。
なぜかというと、MACアドレスを同一にしているのであればお互いで疎通をとることはできないはずなのにもかかわらず
瞬時に切り替わりを行えていたからです。その原因を探ってみると、VRRPはペアとなる機器に直接パケットを送るのではなく
masterとなるルータがHelloパケットと呼ばれるパケットを定期的にユニキャストしていたことが原因のようです。
この結果、MACアドレスが同一でもbackupルータはHelloを正常に確認できるので、VRRPも正常に切り替えを行えていたようです。

# 〆
今回はあまり技術的な内容を書くことができず、何をしたのかも詳しく書けていないのでそのうち記事にしたいと思います。

UNIXとLinuxとBSDと色々

はじめに

この記事の内容はUNIXLinuxBSDとその他色々なOSの違いや成り立ちを忘れないよう、自分なりに理解するためのまとめです。新たな発見も無ければ間違いが多く含まれていると思われます。

UNIX

UNIXとは、言わずと知れた現在にUbuntuRHELなどのLinuxの誕生に影響を与えたOSです。1969年に米国のAT&Tベル研究所で開発が行われ、1971年に初めて公開されました。当時はアセンブラ言語での実装が一般的であったため、初期のUNIXアセンブラ言語で記述されていましたが後にC言語で改めて実装がなされました。オペレーションシステムを高級言語で記述するという試みは、先駆的であり他のプラットフォームへの移植をようにしました。
UNIX高級言語で記述された初めての言語」と言われますが、実は最初はアセンブラ言語で実装されていた、と言うのは初耳でした。さらに、当時では高級言語でOSが記述されるという事自体が一般的ではない(と言うよりもCの実装が今より使える言語ではなかった?)と言うことも意外でした。

UNIXの誕生にはさらに深い歴史があり、1960年代中ごろにマサチューセッツ工科大学ベル研究所、General Electric(GE)がGEのメインフレームコンピュータ用に開発した「Multics」というタイムシェアリングシステム、つまりは複数ユーザで様々な処理を行うことができるシステムを共同開発していました。しかし、革新的かつタイムシェアリングシステムという様々な処理を行うというコンセプトからわかるように、機能が増えていっていくに比例してその複雑さは増す一方となりついにはベル研究所Multics開発から離脱します。そこで、よりシンプルなシステムを開発しようとして生まれたのがUNIXです。つまりは、UNIXMulticsの複雑さを複雑さを解消する目的で開発されたということです。
このことから、UNIXMulticsの影響を受けて開発されたのだろうと解釈しました。また、「UNIX」という名称の由来も初期のUNIX、このころは「Unics」というシステムはMulticsと違いシングルタスクでのみしか動作できなかったのでMultiの逆で単一という意味の「Unit」から生まれたようです。 余談ですが、UNIXAT&Tの様々な事情によりソースコードが公開され、大学や企業に広まったようです。

GNU

初期のUNIXの公開から約10年後の1983年にリチャード・ストールマンによって、「フリーソフトウェアのみで構成されたUNIXの完全互換ソフトウェア」を開発するという目標の元作り出されたGNUは、ライブラリ、コンパイラテキストエディタUnixシェル、Windowシステムなどを備えていたものの、低水準の要素であるデーモンやカーネルデバイスドライバといったものは利用できなかったようです。後にLinuxを世に送り出すリーナス・トーバルズは、GNUカーネルが利用できなかったこともLinuxを開発した要因の一つであると述べています。
この記事を書くまでGNUについて詳しく調べてみたことがなかったのですが、GNUはOSでありLinuxとはまた違ったコンセプトで開発されたということがわかりました。さらに、LinuxUNIXを無料で利用するために誕生したという話を聞いていたので、意外なものが関係しているのだなと思いました。

BSD

1970年代後半から1980年代にかけて、カリフォルニア大学バクレー校のCSRGはUNIXの派生版としてBSDを開発しましたが、UNIXの利用者のライセンスを制限する、つまりは現代でいうところの著作権のようなものの関係がありBSDを公開することができなくなってしまいました。そこで、ライセンスに関わる部分を削り必要な部分を書き換えました。さらに、386で動かすコードを補って1992年にウィリアム・ジョリッツによってリリースされたのが386BSDであり、NetBSDFreeBSDの祖先となるシステムです。当時、現代的なマルチプロセスやメモリ保護などの機能が実装できる安価な32bitパーソナルコンピュータが普及され始めたこともあり、BSDのようなUNIXの移植が行われるようになりLinuxの開発にも影響しました。 BSDの成り立ちが私の中で一番あいまいで、BSDUNIXの関係性がイマイチ理解できていませんでしたが 、BSDLinuxの開発にも影響していたということは知らなかったのでなるほどなと思いました。また、この頃から今のようなPCが徐々に世に出ていくと考えるとなかなか面白くもあり時代が変わっていくのだなと感じます。

Linuxの誕生

上記BSDでもあるように、1990年代には比較的安価で買えるIntel 80386CPUを搭載した32bitPC/AT互換パーソナルコンピュータが普及し始めていました。その当時ヘルシン大学の学生であったリーナスはオペレーティングシステムについて強い好奇心を抱いていました。そこで彼はその安価なコンピュータを使用してUNIX互換の動作をするOSを動作させたいと考えますが、商業UNIXは高価であり、ここでは登場していませんがMINIXという教育用のOSは制限が多かったため、彼の思うようにはいきませんでした。そこで、自作のターミナルエミュレータファイルシステムなどのUNIX互換APIを実装して独自のOSカーネルを開発しました。これが後のLinuxカーネルになっていきます。
Linuxの開発はMINIX上で行われていたため、MINIXで動作するソフトウェアはLinuxでも動作可能でしたが後にLinux上でLinuxの開発が行えるようになると、MINIXコンポーネントGNUのプロダクトによって置き換わっていきました。
当時のLinuxの実装は単純であり他のUNIX互換のシステムと比べても見劣りするもので、機能面でLinuxは劣っていたものの自由なUNIX互換カーネルを利用でき、かつライセンスなどの問題が発生しないシステムは当時Linuxのみであった。
当時の、PCで動作するフリーのUNIX環境を求めるユーザたちの多くはMINIXを利用していたため、リーナスはMINIXメーリングリスト上でLinuxを公開しGPLの下で利用しました。ちょうど32bit PC/AT互換パーソナルコンピュータが普及し始めた時期であったためGPLでの改良が可能であったため、多くの開発者たちへ改良を促しました。その結果として開発者たちはLinuxカーネルをより良いものにしていくと同時に、GNUコンポーネントと統合する作業を行い、今のLinuxの形となりました。 今でこそ多くのOSの素となっているLinuxですが、当初は他のOSとは比較できないほど未熟であったのにも関わらずフリーかつLinuxの開発に影響を与えたGNUよりも早い段階で独自のカーネルを形にしていたというところを武器にして負けず劣らずな戦いを繰り広げていたというのはとても面白いですね。また、やはりOSSとしての利点として多くの開発者たちの手によってより良く改良されていったのも要因の一つなのかもしれませんね。さらに、上記BSDのライセンス問題を解消してリリースされたFreeBSDの公開が1994年11月であるのに対して、Linuxが公開されたのが1990年代前半というタイミングもLinuxの広まった要因の一つのように思えます。ここからは私の想像になってしまいますが、一般的に「Linux」と呼ばれているOSは、ここまで書いてきた「Linuxカーネル」を指すものでありRHELDebianは「Linuxカーネル」に独自のプログラムを追加したものなのではないかなと思います。

MINIX

Linuxでたびたび出てきたMINIXについても少しだけメモしておきたいと思います。
MINIXは、アンドリュー・タネンバウムによって作られたUNIX系のOSです。コンピュータ科学におけるオペレーティングシステムの教育という目的に重点を置いた設計で、企業ライセンスなどが無いように書かれたものでしたが、コンパイラにライセンスの問題がある、教育目的なので教科書として広く配布するために商業出版を必要とした関係もありライセンスには制限がありました。

まとめ

知っていたようで意外に知らないことも多く、特にUNIXが初めはアセンブラで書かれていたことに驚きました。
BSDの歴史やライセンスの問題、MINIXMulticsなどのあまり聞きなれないOSなど深く調べれば調べるほど様々な情報が得られ
よりコンピュータについての興味が生まれてくるので現代の技術も大切ですが歴史についても調べてみるのも良いかもしれないなと感じました。
特に、歴史の関連性などがまだ調べられていないのでいつか調べてみたいと思います。

参考文献

Unixの歴史 - Wikipedia

Linux - Wikipedia

ISUCON7で予選落ちした話

はじめに

先週の土日で行われたISUCON7に「インターネットは爆発しました」と言うチームで出場しました。
今回がISUCON初参加だったので参加しての感想とそのWriteupがメインの記事となります。

やったこと

僕の所属していたチームでは、3人中2人がサーバ担当、残りの1人でコードのチューンを行うと言う分担を行いました。
今回の競技ではメインで実行されていたアプリケーションはPythonのようでしたが、PHPに切り替えてチューンを行うことにしました。 補足として、PHPでのオリジナルコードのベンチマークスコアは「6000」でした。
やったこととして、まず始めに

パフォーマンス1000%UP!PHPでMySQLのDB処理を行うと重いときに行うパフォーマンス施策~基礎編~

この記事を参考にコード内のSQLクエリの命令をバッククォートで囲みました。
具体的には

SELECT UserName, Pass, ScreenName FROM UserList WHERE UserName = "hogehoge"

と言うようなクエリがあった場合

SELECT UserName, Pass, ScreenName FROM UserList WHERE UserName = "hogehoge"

と言ったように、テーブル名や要素名をクォートで囲むことで無駄な処理が減り、今回のように数千単位のデータを扱う場合では有効なようです。 さらに、今回のコードではいくつかの機能別に関数を定義しておきそれを別関数内で読んでいる構造をしているためなのか
DBからデータを取得する際に「*」で全フィールドを取ってきていたので、各関数で必要なフィールドを書き出して必要最低限の
データのみを処理するように変更しました。
ひとまずはこれでSQL部分のチューニングはいいだろうと考え、今度はコード全体を眺めていくと、「str_replace」と言う関数を使っている処理を発見しました。この関数でもまったく問題なく動作するのですが、どうやらこの関数はあまり速度的に速く無いようだったため
「strtr」と言う関数へ変更しました。

たったこれだけのことにかなりの時間をかけてしまいましたが、たったこれだけで最終スコアは20000代に跳ね上がり、約4倍の高速化を行うことができました。
それもサーバサイドのチューニングを一切行なっていなかったのでSQLがかなりのボトルネックになっていたのだろうと感じました。
もしこれでサーバサイド、そして記事内で触れていませんでしたが画像呼び出しがSQL内のバイナリを変換して画像化すると言う処理をしている影響で 見て分かるほど処理が重たくなっていたので画像の実ファイル化を行えていればもしかすると今回のボーダーの40000点も超えられたのかなと感じました。

まとめ

今回は予選敗退という結果に終わりましたが、初参戦ながらもそこそこ良い結果を出せたのかなと思いました。また、今までコードチューンを 行う機会がなかったので初めて聞いたことや初めて知ったことなどが多く久しぶりに真剣に取り組んだなぁと感じました。
最近はやたら周りがCTFで盛り上がっていて萎えr...勢いについていけなくなったのもあってか、ISUCON非常に熱いなと感じたので来年も参加したい。

Goバイナリ解析メモ

はじめに

chouett0note.hatenablog.com

前回の記事ではC, PythonそしてRustで「Hello World!」を表示するだけのプログラムをコンパイル等を行なって実行ファイルへ変換したものの解析を行いましたが、先日の某LTの懇親会にてGo言語で実装したものを解析してみたら面白いのではないかと意見をいただいたため、今回の検証を行いました。なお、今回も最適化を無効化した32bitバイナリを対象としています。

検証メモ

以下は検証を行なった際のメモとなります。

Stirling

f:id:chouett0:20171010231347p:plain
* Cバイナリに比べてやはりサイズが大きくなっている、ヘッダーとヘッダーとボディー感のNULL領域以外は相似していない
* 先頭付近に「Go Build」と言う文字列が存在する f:id:chouett0:20171010231505p:plain
* 途中から可読文字列が現れ始める(expやesiなど)
-> この周辺になんらかの処理が埋まってる?
f:id:chouett0:20171010231528p:plain
* 一部下毒文字列ではない文字列を挟んだ後にintやboolなどの型名らしき文字列が出現
* 後半に進むに従ってGoの関数と思われる名称が多く現れる
f:id:chouett0:20171010231608p:plain
* io.Writer, Sync.PoolなどのGoの要素がいくつか確認できる
-> 内部でGoの関数定義を行なっている?
* 「kernel32.dll」などのDLLファイルの名称が含まれている
-> 内部でバイナリに変換する際に利用?
f:id:chouett0:20171010231742p:plain
* Cで利用される関数名が存在する
-> 独自で関数を持っている?
* Goソース、Goライブラリを列挙した部分がある
-> コンパイル時に必要?
-> 1.5以降のGoではGoとアセンブリで実装されていると言う仕様から、その線が高い
f:id:chouett0:20171010231711p:plain

vxPEViewer

f:id:chouett0:20171010231918p:plain
f:id:chouett0:20171010232009p:plain
* ヘッダーに特に変わった点は無し
* ImportLibraryでは「winmm」「ws2_32」「kernel32」がインポートされている f:id:chouett0:20171010232022p:plain
* Stirlingを用いた解析時に現れたCの関数と同じ関数がインポートされている
* 直接関係のない関数を読み込んでいる点はRustと同じように思える
-> Goソース内でimportしたGoライブラリで利用されている関数で利用されているもの?
* なぜかWriteConsoleWはあるもののWriteConsoleAが読み込まれていない(他の関数ではどちらも読み込まれている)

Ollydbg, x32dbg

f:id:chouett0:20171010232320p:plain
* これまで同様初期化処理と思われるコードからjmpする
* WriteFile, WriteConsoleにBPを仕掛けるもののそのまま通常終了している点から、別の関数を利用 or 独自の処理を行なっている?
* 今までのように特定のDLLの関数を直接呼び出さずに外部関数を呼び出す総合的なcall命令が存在する
-> 実質一つの命令で様々な命令を再現できる
-> 上記の関数にBPを仕掛けても効果がなかったことも頷ける

f:id:chouett0:20171010232711p:plain
このcall命令が文字列を表示する関数を呼び出しているようで、同時にeaxに関数のアドレスを渡すことで様々な関数を呼び出すことのできる命令でもある
f:id:chouett0:20171010232832p:plain
このように、eaxに関数のアドレスを渡すことで呼び出していました。

f:id:chouett0:20171010232918p:plain
f:id:chouett0:20171010232930p:plain
先ほどのcall命令の内部へ入ると上記のようになっており、eaxに与えるアドレスによって呼び出す関数が変わっていることがわかります。
f:id:chouett0:20171010233055p:plain
最後に、このcall命令が最終的な文字列表示を行う処理でありWriteConsoleWを呼び出していることがわかります。
f:id:chouett0:20171010233226p:plain
f:id:chouett0:20171010233239p:plain

まとめ

今回の検証は、今まで行ってきたどのバイナリよりも複雑なものでありWriteConsole関数にBPを仕掛けるだけではうまくいかないと言うこともありかなり苦戦しました。特に、関数名や処理名をデバッガ側でアシストされなかったのが一番の難点だったと思います。
しかし、関数アドレスを渡すことで呼び出しを行う処理の攻略は自バイナリで主要処理を保持していたりパッカーまではいかなくとも難読化を行われているようなバイナリを解析する練習としては非常に良い経験になったと思います。
今回もおそらく本来の仕様とは異なる点が多くあるかと思うでの意見等頂ければ嬉しいです。