買っただけの本とか多いので確実に処理していきたい。2019の13日目の記事です。9日遅れでの投稿でもあります。誠に申し訳ございません...。adventar.org序論ところで、皆さんはシェル芸人と呼ばれるものをご存知でしょうか。終わらせること」(USP友の会会長・上田隆一による定義)である。https://qiita.com/t_nakayama0714/items/bfe4852e0535858ee662www.usptomo.com一時期話題になっていたojichatやその派生系のhimechatも優秀なシェル芸人達によって日々生み出されています。しますね!僕も偉大な先輩方に近づけるよう、日々精進しております。そんなシェル芸界隈ではう〇こをあらゆる手段で出力することが流行っています。2019これは一番最近観測したkingunkoしかし、bashでうんこを出力するなんてありきたりなことじゃ感動が薄れるのではないか?と思い、そうだPowershellで書いたら面白いんじゃないかとなり今にいたります。うんことかで終わってしまっては面白くないので、今回はbase64で書いたうんこをデコードするコマンド群を書いて、さらにそのワンライナー自体を難読化させることを目標に作ることにしました。-dと似たようなことをコマンドレットのみで実現したいとなります。ちなみに、熟練したシェル芸人は目でbase64をデコードするといわれています。まとめると以下の二つです。任意のアルファベットを生成するそれを連結させてeval()するここで言うevalとは、bashで用いられるものであり主な用途はevalコマンドが威力を発揮する場面は2つあります。1つはあるコマンドが出力した文字列自体をコマンドとして実行すること、もう1つは(入れ子になった)変数を評価することです。www.atmarkit.co.jpこれはpowershellではInvoke-Expressionと呼ばれるコマンドレットで実現可能です。これで、引数に指定した文字列をコマンドとして実行することを可能にします。これはiexでaliasされています。iex自体を実行するには実行演算子&を用います。&"iex"イメージはこんな感じ。任意のアルファベットを用意する方法ですが、int型の数値をchar型にキャストできることを利用します。"[char]72"をiexにかけてやると、"H"が出力されます。文字コードを作り、それをなんらかの手段で作ったcharでキャストしてiexにかければいいわけです。数値を作るpowershellでは${}で囲むとほとんどの記号を変数にできる性質を持ちます。初めに、変数をすべて記号化する為、以下のようにします。#9まず変数${;}を用意します。$()は空の部分式で、$nullと等しくなります。これに+を付けると$nullがintにキャストされて0になります。それを${;}に代入。インクリメントして完成です。”Char”を作る"r"は"True"から、"c","h","a"は連想配列から生み出します。Trueは自動変数"$?"から生成することができます。"$?"は前のコマンドが正常終了されればTrue,異常終了されればFalseを吐き出すものです。ここでは、Trueの二文字目のみを取得したいので、文字列にインデックスを付けるとそのインデックスの場所にある文字を取得できることを利用して"$?[${+}]"このように記述します。次に"c","h","a"ですが、空の連想配列@{}を用意してこれを部分式$()の中に格納し、"$(@{})"としてstringにキャストすると"System.Collections.Hashtable"という文字列が得られることを利用して実現します。#char"iex"を作る"i"と"e"は"System.Collections.Hashtable"に含まれているので、xをどうにかして工面する方針で考えます。これはSystem.stringでカバーします。value)ここにxが含まれているので、このxをなんとかして取り出したいです。これは、PowerShellで<オブジェクト>.メソッド名とするとメソッド情報が格納されたPSMethodオブジェクトを取得できることを利用して解決できます。PSMethodオブジェクトをstringにキャストするとそのメソッドのシグネチャが文字列として得られます。"$method"このようなコードを記号で記述すればいいわけです。"${;}"["${@}${)}"]とすれば"x"が得られます。#iex組み立てる後は実行したいコードを文字コードに変換するだけです。今回はpowershell上でbase64デコードによりうんこを表示するので、ワンライナーは以下のようになります。$txtこれを一度手元で文字コード番号に変換してあげる必要があります.........当然全て手で変換するのは骨が折れるので簡易的なスクリプトを組みました。$b64txt="44GG44KT44GT""こうなると正しく認識されないわけですね。このバグ探しを全部エンコードし終わった後にやるから精神がすり減る。