Homebrewで入るNASMは古すぎて、aptで入るNASMとは挙動が違う

自作CPUエミュの動作確認をしているときに、Homebrewで入るNASMとaptで入るNASMの挙動が違うことに気がついた。

挙動の違いを見る

簡単なコードをアセンブルして違いを見る。

BITS 32
    org 0x7c00
    sub esp, 16

aptで入るNASM

Ubuntuにaptで入るNASMを使って、アセンブルした結果をhexdumpで確認する。

$ nasm sub-test.asm -o sub-test-linux
$ hexdump -C sub-test-linux
00000000  83 ec 10                                          |...|
00000003

0x83のopcodeは、メモリとレジスタの間で8bitの即値を操作する。 ModR/Mによってどんな操作をするのかが分かる。この場合はレジスタの値から8bitの即値を引いている。

Homebrewで入るNASM

macOSにHomebrewで入るNASMを使って、アセンブルした結果をhexdumpで確認する。

$ nasm sub-test.asm -o sub-test-mac
$ hexdump -C sub-test-mac 
00000000  81 ec 10 00 00 00                                 |......|
00000006

0x81のopcodeは、メモリとレジスタの間で32bitの即値を操作する。 この場合もModR/Mによってどんな操作をするのかが分かる。レジスタの値から8bitの即値を引いている。 オペランドに指定している0x16は8bitで収まるのに32bitの無駄に大きい値を扱っていて、うまくアセンブルできていないことがわかる。

バージョンの違いが原因だった

macOSでHomebrewを使ってインストールできる最新のNASMのバージョンは以下の通り。

$ nasm -v
NASM version 0.98.40 (Apple Computer, Inc. build 11) compiled on Aug 24 2016

Ubuntuでaptを使ってインストールできる最新のNASMのバージョンは以下の通り。

$ nasm -v
NASM version 2.10.09 compiled on Jun 28 2018

この通り、バージョンが大幅に違う。 appleが独自にメンテしているからバージョンの進み方が違うのかなと思ったけど、 単に古いだけっぽくて、最新のmacOS向けのビルドは以下のリンクで配布されている。 Index of /pub/nasm/releasebuilds/2.13/macosx

まとめ

このようにアセンブラのversionが違うと、出力されるopcodeが変わってくるので気をつけたい。

LLVM IR、LLVM bitcodeを扱うコマンドたちのメモ

LLVM IR、LLVM bitcodeを扱うコマンドをよく忘れるのでメモしておく。 CのコードをLLVM IR、LLVM bitcodeに変換するコマンド、LLVM bitcodeをインタプリタから実行するコマンド、コンパイルするコマンドなどを書いておく。 以下のCのコードを変換していく。

# include <stdio.h>

int main() { 
  int a = 1;
  int b = 2;
  int sum = a + b;
  printf("%d", sum);
  return 0;
}

LLVM IRを出力する

LLVM内ではLLVM IRという中間言語表現が用いられる。LLVM内で使えるアセンブリのようなものである。 LLVMを用いたコンパイラでは、ソースコードLLVM IRコードに変換したあと、そのLLVM IRコードをターゲットのアーキテクチャのバイナリに変換することでコンパイルが行われる。

Cのコードを変換する

clangに-emit-llvm-Sの2つのオプションを指定して実行するとLLVM IRが出力される。 以下のようにコマンドを実行するとtest.llが出力される。

$ clang test.c -emit-llvm -S

出力されたLLVM IR

以下のようなLLVM IRのコードが出力される。

$ cat test.ll
; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.12.0"

@.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1

; Function Attrs: nounwind ssp uwtable
define i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  store i32 1, i32* %2, align 4
  store i32 2, i32* %3, align 4
  %5 = load i32, i32* %2, align 4
  %6 = load i32, i32* %3, align 4
  %7 = add nsw i32 %5, %6
  store i32 %7, i32* %4, align 4
  %8 = load i32, i32* %4, align 4
  %9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i32 %8)
  ret i32 0
}

declare i32 @printf(i8*, ...) #1

attributes #0 = { nounwind ssp uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"Apple LLVM version 8.0.0 (clang-800.0.38)"}

LLVM bitcodeを出力する

LLVM bitcodeはLLVM IRのバイナリフォーマットである。 LLVM IRと LLVM bitocodeは相互変換でき、LLVM bitcodeはバイナリ(.out, .exeなど)に変換せずとも、LLVMインタプリタから直接実行することができる。

Cのコードを変換する

clangに-emit-llvm-cの2つのオプションを指定して実行するとLLVM bitcodeが出力される。 以下のようにコマンドを実行するとtest.bcが出力される。

$ clang test.c -emit-llvm -c

LLVM IRを変換する

llvm-asコマンドを使うことでLLVM IRをLLVM bitcodeに変換できる。 以下のようにコマンドを実行するとtest.bcが出力される。

$ llvm-as test.ll 

出力されたLLVM bitcode

人の目で直接読むのはきびしい。

$ file test.bc
test.bc: LLVM bitcode, wrapper x86_64
$ hexdump -C test.bc
00000000  de c0 17 0b 00 00 00 00  14 00 00 00 a8 09 00 00  |................|
00000010  07 00 00 01 42 43 c0 de  35 14 00 00 05 00 00 00  |....BC..5.......|
00000020  62 0c 30 24 49 59 be a6  ee d3 3e 2d 44 01 32 05  |b.0$IY....>-D.2.|
00000030  00 00 00 00 21 0c 00 00  1e 02 00 00 0b 02 21 00  |....!.........!.|
00000040  02 00 00 00 13 00 00 00  07 81 23 91 41 c8 04 49  |..........#.A..I|
00000050  06 10 32 39 92 01 84 0c  25 05 08 19 1e 04 8b 62  |..29....%......b|
00000060  80 10 45 02 42 92 0b 42  84 10 32 14 38 08 18 4b  |..E.B..B..2.8..K|
00000070  0a 32 42 88 48 90 14 20  43 46 88 a5 00 19 32 42  |.2B.H.. CF....2B|
00000080  04 49 0e 90 11 22 c4 50  41 51 81 8c e1 83 e5 8a  |.I...".PAQ......|
00000090  04 21 46 06 51 18 00 00  e9 00 00 00 1b 4c 25 f8  |.!F.Q........L%.|
000000a0  ff ff ff ff 01 90 00 0d  08 03 82 1c d2 61 1e c2  |.............a..|
000000b0  41 1c d8 a1 1c da 80 1e  c2 21 1d d8 a1 0d c6 21  |A........!.....!|
....

LLVM bitcodeをLLVM IRにデコンパイル

相互変換できるのでLLVM IRに戻すことができる。すごい。

$ llvm-dis test.bc

LLVM bitcodeをインタプリタで実行する

lliコマンドを使うことでLLVM bitcodeをインタプリタから直接実行できる。

$ lli test.bc 
3

LLVMの bitcodeをバイナリにする

llcコマンドを使うことでLLVM bitcodeをターゲットアーキテクチャアセンブリに変換し、そのアセンブリをclangでコンパイルすることでバイナリが出力される。

$ llc test.bc 
$ clang test.s
$ ./a.out
3

LLVMのPassを題材にした0CTF CTF quals 2017のChoicesを解いた

最近、LLVMに興味があって、いろいろ調べているうちにLLVMのPassのreversingの問題を見つけたので解いてみた。

write-ups-2017/0ctf-quals-2017/reverse/Choices-297 at master · ctfs/write-ups-2017

問題

All roads lead to Vegas.
Compile: clang -Xclang -load -Xclang lib0opsPass.so -mllvm -oopsSeed=BAADF00DCAFEBABE3043544620170318 source.c
Clang && LLVM Version: 3.9.1

Choicesとlib0opsPass.soの2つの64bitのELFバイナリが与えられる。lib0opsPass.soはLLVMのPassのバイナリっぽい。

$ file Choices
Choices: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped

$ file lib0opsPass.so 
lib0opsPass.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=2662bbaf3e7f926a3773d814e5f3c63240ee57e5, not stripped

解く

ChoicesをIDAで見てみると、main関数でcalculation関数を呼んだ後、memcmpでデータとflagを比較してflagがあってたらCorrect!! The flag is %sを出力している。 f:id:TAKEmaru:20180608031647p:plain

calculation関数はCFGをflattenにする、Control Flow Flatteningという難読化が施されている。このCFGを生成するのにhopperは結構時間かかったけど、IDAはシュッと生成してくれてすごい。高いだけある。

f:id:TAKEmaru:20180608031603p:plain

flattenになっているCFGの一番上でscanfで入力を受けている。

f:id:TAKEmaru:20180608031709p:plain

どのように難読化したのかを知りたいので、lib0opsPass.soをIDAで見る。 OSSLLVMを使った難読化ツールであるobfuscator-llvm/obfuscatorと全く同じシンボルがいくつもあって、これを参考に実装されているのが分かっておもしろい。

Oops::CryptoUtils::hogeのようなシンボルが多数あったので、 ida/idapython_tools/findcrypt · you0708/idaを使って、 暗号で使われている定数の抽出を試みた。以下のようにRijndaelで使われているラウンドキーを見つけることができた。

f:id:TAKEmaru:20180608034828p:plain f:id:TAKEmaru:20180608035745p:plain

このキーは、scramble32関数で使われていた。 switchのcaseで指定する値を生成するのにこの関数は使われていて、Control Flow Flatteningを施すOops::OopsFlattening::flatten関数で呼び出されていた。 switch文を使って無駄に分岐をいれることでCFGをflatにすることができる。 以下にControl Flow Flatteningによる難読化例を示す。 https://github.com/obfuscator-llvm/obfuscator/wiki/Control-Flow-Flatteningよりコードは引用した。

難読化前の例

#include <stdlib.h>
int main(int argc, char** argv) {
  int a = atoi(argv[1]);
  if(a == 0)
    return 1;
  else
    return 10;
  return 0;
}

難読化後の例

case 0の部分に難読化前で行っていたコードが入っている。それ以外の分岐では無意味なコードが実行される。

#include <stdlib.h>
int main(int argc, char** argv) {
  int a = atoi(argv[1]);
  int b = 0;
  while(1) {
    switch(b) {
      case 0:
        # 本来行われる処理
        if(a == 0)
          b = 1;
        else
          b = 2;
        break;
      case 1:
        return 1;
      case 2:
        return 10;
      default:
        break;
    }
  }
  return 0;
}

solverを書く

switch文の中で意味のある処理を行う部分の処理を実行するような値をscanfで入力することを考えればいい。 コンパイル時に指定したseed値のBAADF00DCAFEBABE3043544620170318とLabel%dで読み取られる難読化対象の関数のindex、Rijndaelのラウンドキーによってaesっぽい暗号化をすることによってswitchのcaseの値は生成されている。 aesっぽくあるもののRound数が4回と少ないことや、必要なロジックを省いているので完全なaesではない。 Oops::OopsFlattening::flattenでscramble32関数を呼んでいるあたりのロジックをPythonで書き起こし、switch文の全ての分岐を実行することでflagを出力させる作戦でいく。 scramble32関数は obfuscator/CryptoUtils.cpp at llvm-4.0 · obfuscator-llvm/obfuscator · GitHubと完全に一致していておもしろい。

f:id:TAKEmaru:20180608195754p:plain

RijndaelのラウンドキーをIDAからコピペするのに、ふるかわプロに教えてもらったLazyIDAを使った。便利。

github.com

#!/usr/bin/env python2
# coding: UTF-8

from Crypto.Cipher import AES
import itertools
import struct

aes = AES.new('BAADF00DCAFEBABE3043544620170318'.decode('hex'), AES.MODE_ECB)

Rijndael_Te0 = [
    0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554, 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B, 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, 0x6834345C,
    0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5, 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497, 0xA65353F5, 0xB9D1D168,
    0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594, 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75,
    0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D, 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883, 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E,
    0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B, 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651, 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD,
    0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9, 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631,
    0x844242C6, 0xD06868B8, 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A
]

Rijndael_Te1 = [
    0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5, 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676, 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0, 0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0, 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC, 0x5C683434,
    0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515, 0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A, 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575, 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0, 0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484, 0xF5A65353, 0x68B9D1D1,
    0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B, 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF, 0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585, 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8, 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5, 0xDF63BCBC, 0xC177B6B6, 0x75AFDADA,
    0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2, 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717, 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373, 0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888, 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB, 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A,
    0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C, 0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979, 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9, 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808, 0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6, 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B,
    0xDC61BDBD, 0x860D8B8B, 0x850F8A8A, 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E, 0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E, 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494, 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF, 0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6,
    0xC6844242, 0xB8D06868, 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616
]

Rijndael_Te2 = [
    0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5, 0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76, 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0, 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0, 0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC, 0x345C6834,
    0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15, 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A, 0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75, 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0, 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384, 0x53F5A653, 0xD168B9D1,
    0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B, 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF, 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185, 0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8, 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5, 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA,
    0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2, 0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17, 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673, 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88, 0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB, 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A,
    0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C, 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279, 0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9, 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008, 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6, 0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B,
    0xBDDC61BD, 0x8B860D8B, 0x8A850F8A, 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E, 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E, 0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394, 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF, 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6,
    0x42C68442, 0x68B8D068, 0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16
]

Rijndael_Te3 = [
    0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, 0x34345C68,
    0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, 0x5353F5A6, 0xD1D168B9,
    0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF,
    0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14,
    0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96,
    0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7,
    0x4242C684, 0x6868B8D0, 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
]


def gen_pool():
    out = []
    for i in range(0x2000):
      ctr = '\0' * 8 + struct.pack('>Q', i+1)
      out.append(aes.encrypt(ctr))
    return ''.join(out)

def scramble32(input, key):
    # Round 1
    tmpA = 0x0
    tmpA ^= Rijndael_Te0[((input >> 24) ^ key[0]) & 0xFF]
    tmpA ^= Rijndael_Te1[((input >> 16) ^ key[1]) & 0xFF]
    tmpA ^= Rijndael_Te2[((input >> 8) ^ key[2]) & 0xFF]
    tmpA ^= Rijndael_Te3[((input >> 0) ^ key[3]) & 0xFF]

    # Round 2
    tmpB = 0x0
    tmpB ^= Rijndael_Te0[((tmpA >> 24) ^ key[4]) & 0xFF]
    tmpB ^= Rijndael_Te1[((tmpA >> 16) ^ key[5]) & 0xFF]
    tmpB ^= Rijndael_Te2[((tmpA >> 8) ^ key[6]) & 0xFF]
    tmpB ^= Rijndael_Te3[((tmpA >> 0) ^ key[7]) & 0xFF]

    # Round 3
    tmpA = 0x0
    tmpA ^= Rijndael_Te0[((tmpB >> 24) ^ key[8]) & 0xFF]
    tmpA ^= Rijndael_Te1[((tmpB >> 16) ^ key[9]) & 0xFF]
    tmpA ^= Rijndael_Te2[((tmpB >> 8) ^ key[10]) & 0xFF]
    tmpA ^= Rijndael_Te3[((tmpB >> 0) ^ key[11]) & 0xFF]

    # Round 4
    tmpB = 0x0
    tmpB ^= Rijndael_Te0[((tmpA >> 24) ^ key[12]) & 0xFF]
    tmpB ^= Rijndael_Te1[((tmpA >> 16) ^ key[13]) & 0xFF]
    tmpB ^= Rijndael_Te2[((tmpA >> 8) ^ key[14]) & 0xFF]
    tmpB ^= Rijndael_Te3[((tmpA >> 0) ^ key[15]) & 0xFF]

    LOAD32Hed = ((key[2] << 8) | (key[1] << 16) | (key[0] << 24) | key[3])
    return LOAD32Hed ^ tmpB

pool = gen_pool()

enc = map(ord, pool[:16])

for i in range(1000):
    x = scramble32(i, enc)
    print(struct.unpack('<i', struct.pack('<I', x))[0])

flag!!

$ python solver.py |./Choices 
Correct!! The flag is flag{wHy_d1D_you_Gen3R47e_cas3_c0nst_v4lUE_in_7h15_way?}

技術書展4でTomoriNao Vol.2を頒布してきた!!

11時20分くらいに着いたら整理券が1918番で結局入れたのは12時半ごろだった。予想以上に人が多い。

f:id:TAKEmaru:20180422113318j:plain

13時頃には200冊全部売れてよかったですね。

f:id:TAKEmaru:20180422150141j:plain

urandomとかksnctfとかハニーポットとか言語処理系の本が買えたのもよかった。

TomoriNao Vol.1, Vol.2ともにkindleで発売中なので、よろしくお願いします!!

rails 5.1.6 のアプリをrails 5.2.0にアップデートしたときに困ったとこメモ

rails 5.1.6 のアプリをrails 5.2.0にアップデートしたときに、いろいろハマったのでメモ。

rails

rails側での作業メモ。

cannot load such file -- bootsnap/setup

とりあえず rails app:updateしてみる。 route.rbなどは上書きしたらダメだけど、boot.rbとか触った覚えのないファイルは上書きしていく。

$ rails app:update
conflict  config/boot.rb
Overwrite /Users/tkmru/code/old_app/config/boot.rb? (enter "h" for help) [Ynaqdh] Y
       force  config/boot.rb
       exist  config
    conflict  config/routes.rb
Overwrite /Users/tkmru/code/old_app/config/routes.rb? (enter "h" for help) [Ynaqdh] n
...

rails serverを起動するとbootsnapというrailsの起動を早くするgemがないとエラーが出た。railsが標準で使うようになったとのこと。

週刊Railsウォッチ(20170728)bootsnapがRailsで正式採用、Ruby Prizeの推薦開始、PostgreSQL配列の重複を除去ほか

gemファイルに追加してbundle installする。

$ bin/rails s
Traceback (most recent call last):
    3: from bin/rails:3:in `<main>'
    2: from bin/rails:3:in `require_relative'
    1: from /Users/tkmru/code/old_app/config/boot.rb:4:in `<top (required)>'
/Users/tkmru/code/old_app/config/boot.rb:4:in `require': cannot load such file -- bootsnap/setup (LoadError)

undefined method `halt_callback_chains_on_return_false=' for ActiveSupport:Module

halt_callback_chains_on_return_falseはRails 4との後方互換のためのメソッドで、rails serverを起動するとこれがないというエラーが出た。

$ bin/rails s
=> Booting Puma
=> Rails 5.2.0 application starting in development 
=> Run `rails server -h` for more startup options
Exiting
Traceback (most recent call last):
    73: from bin/rails:4:in `<main>'
    72: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `require'
    71: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'
    70: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `block in require'
...
    10: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:613:in `each'
     9: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:614:in `block (2 levels) in <class:Engine>'
     8: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:656:in `load_config_initializer'
     7: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/notifications.rb:170:in `instrument'
     6: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/engine.rb:657:in `block in load_config_initializer'
     5: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:277:in `load'
     4: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'
     3: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:277:in `block in load'
     2: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
     1: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
/Users/tkmru/code/old_app/config/initializers/new_framework_defaults.rb:23:in `<main>': undefined method `halt_callback_chains_on_return_false=' for ActiveSupport:Module (NoMethodError)

Ruby on Rails 5.2.0 Deprecations – Drifting Rubyによると、 5.2よりhalt_callback_chains_on_return_falseは削除されたみたい。 config/initializers/new_framework_defaults.rbの中のhalt_callback_chains_on_return_falseの行をコメントアウトした。

# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 5.0 upgrade.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.

Rails.application.config.raise_on_unfiltered_parameters = true

# Enable per-form CSRF tokens. Previous versions had false.
Rails.application.config.action_controller.per_form_csrf_tokens = true

# Enable origin-checking CSRF mitigation. Previous versions had false.
Rails.application.config.action_controller.forgery_protection_origin_check = true

# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
# Previous versions had false.
ActiveSupport.to_time_preserves_timezone = true

# Require `belongs_to` associations by default. Previous versions had false.
Rails.application.config.active_record.belongs_to_required_by_default = true

# Do not halt callback chains when a callback returns false. Previous versions had true.
# ActiveSupport.halt_callback_chains_on_return_false = false # これをコメントアウトした!!

# Configure SSL options to enable HSTS with subdomains. Previous versions had false.
Rails.application.config.ssl_options = { hsts: { subdomains: true } }

これでrailsは起動するようになった。

frontend 側

フロントエンド側の作業メモ

can't find executable webpack for gem webpacker

webpackを実行してみると、gemのwebpackerから動かせるwebpackがないってエラーが出た。

$ bin/webpack
Traceback (most recent call last):
    2: from bin/webpack:17:in `<main>'
    1: from /Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/rubygems_integration.rb:489:in `block in replace_bin_path'
/Users/tkmru/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-1.16.1/lib/bundler/rubygems_integration.rb:458:in `block in replace_bin_path': can't find executable webpack for gem webpacker (Gem::Exception)

rails webpacker:binstubsでwebpackのバイナリを再インストールすると、webpackも動くようになった。

$ bin/rails webpacker:binstubs
Copying binstubs
       exist  bin
    conflict  bin/webpack
Overwrite /Users/tkmru/code/old_app/bin/webpack? (enter "h" for help) [Ynaqdh] Y
       force  bin/webpack
    conflict  bin/webpack-dev-server
Overwrite /Users/tkmru/code/old_app/bin/webpack-dev-server? (enter "h" for help) [Ynaqdh] Y
       force  bin/webpack-dev-server

$ bin/webpack
set is deprecated! Use append instead

Hash: 9c54321948fe9d42f554
Version: webpack 3.11.0
Time: 4625ms
                                                                                       Asset     Size  Chunks                    Chunk Names
                                                         application-07d7627f2dffd5e35ab1.js   607 kB       1  [emitted]  [big]  application
  _/node_modules/font-awesome/fonts/fontawesome-webfont-674f50d287a8c48dc19ba404d20fe713.eot   166 kB          [emitted]         
 _/node_modules/font-awesome/fonts/fontawesome-webfont-fee66e712a8a08eef5805a46892932ad.woff    98 kB          [emitted]         
...

技術書典4で TomoriNao vol.2 を頒布します!!

技術書典4で TomoriNao vol.2 を頒布します!! 場所は「お16」です!!!

techbookfest.org

f:id:TAKEmaru:20180416133313j:plain

f:id:TAKEmaru:20180415220914j:plain

ぼくは、「アンチデバックのためのデッドコードをLLVM optimizerで緩和してみる」という題で書きました。 LLVMのパスを使った難読化/難読化緩和の研究がちょくちょくあるけど、 バイナリをLLVM IRにデコンパイルして、LLVMのデフォルトの最適化パスを使うだけで、 デッドコードくらいならまあまあ消えるのでは〜という実験をやってみたという内容です。

そのうち、自作パスによる難読化/難読化緩和もやってみたいですね!!

みなさま!ご購入の検討を!!よろしくお願いします!!!

JSONを扱いやすくするコマンド(jq, gron)のメモ

JSONを扱いやすくするコマンドのjqgronのメモ。

jq コマンド

jq コマンドはJSON向けのawkのようなコマンド。

インストール方法(on Mac

$ brew install jq

使い方

パイプで渡されたJSONデータにフィルターをかけることができる。

GitHub APIを使ってリポジトリ名を列挙する例

$ curl -s `curl -s https://api.github.com/users/tkmru | jq -r .repos_url`  | jq '.[].name'
"anarchy_proof"
"anti_debugging_test"
"aoj"
"awesome-linux-rootkits"
"a_and_d_web_nara"
"biwx"
...
"isucon4-qualifier-mokumoku"
"isucon6-qual-practice"
"isucon_pixv"
"ldap3"
"linux-driver-playground"
"linux-insides"
"linux-insides-ja"
"machine-learning-playground"

GitHub APIを使って最新コミット情報を取って来る例

$ curl 'https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1' | jq '.[0]'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7328  100  7328    0     0   9488      0 --:--:-- --:--:-- --:--:--  9492
{
  "sha": "c764b1baad95cb18cec14a1b7f84b460b6f0b3cc",
  "commit": {
    "author": {
      "name": "tkmru",
      "email": "i.am.tkmru@gmail.com",
      "date": "2018-04-10T14:33:34Z"
    },
    "committer": {
      "name": "tkmru",
      "email": "i.am.tkmru@gmail.com",
      "date": "2018-04-10T14:33:34Z"
    },
    "message": "Merge branch 'master' of github.com:tkmru/dotfiles",
  ...
  "parents": [
    {
      "sha": "495ddbfd8c19564a5c72260eb9c857f2d7f3a6d5",
      "url": "https://api.github.com/repos/tkmru/dotfiles/commits/495ddbfd8c19564a5c72260eb9c857f2d7f3a6d5",
      "html_url": "https://github.com/tkmru/dotfiles/commit/495ddbfd8c19564a5c72260eb9c857f2d7f3a6d5"
    },
    {
      "sha": "7f0f75610a2856c6cc97a3b1d949f5a4345a53df",
      "url": "https://api.github.com/repos/tkmru/dotfiles/commits/7f0f75610a2856c6cc97a3b1d949f5a4345a53df",
      "html_url": "https://github.com/tkmru/dotfiles/commit/7f0f75610a2856c6cc97a3b1d949f5a4345a53df"
    }
  ]
}

GitHub APIを使ってコミットメッセージ、名前を列挙する例

$ curl 'https://api.github.com/repos/tkmru/dotfiles/commits?per_page=2' | jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7328  100  7328    0     0   9382      0 --:--:-- --:--:-- --:--:--  9382
[
  {
    "message": "Merge branch 'master' of github.com:tkmru/dotfiles",
    "name": "tkmru"
  },
  {
    "message": "add ungron",
    "name": "tkmru"
  }
]

gron コマンド

JSONgrepしやすい形式、JavaScriptで扱える形式に変換してくれるコマンド。 Golang製。

インストール方法(on Mac

$ brew install gron

使い方

URLもしくはJSONファイルを指定すると変換してくれる。

$ gron "https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1"
json = [];
json[0] = {};
json[0].author = {};
json[0].author.avatar_url = "https://avatars3.githubusercontent.com/u/1628214?v=4";
json[0].author.events_url = "https://api.github.com/users/tkmru/events{/privacy}";
json[0].author.followers_url = "https://api.github.com/users/tkmru/followers";
json[0].author.following_url = "https://api.github.com/users/tkmru/following{/other_user}";
....
json[0].parents[1].html_url = "https://github.com/tkmru/dotfiles/commit/7f0f75610a2856c6cc97a3b1d949f5a4345a53df";
json[0].parents[1].sha = "7f0f75610a2856c6cc97a3b1d949f5a4345a53df";
json[0].parents[1].url = "https://api.github.com/repos/tkmru/dotfiles/commits/7f0f75610a2856c6cc97a3b1d949f5a4345a53df";
json[0].sha = "c764b1baad95cb18cec14a1b7f84b460b6f0b3cc";
json[0].url = "https://api.github.com/repos/tkmru/dotfiles/commits/c764b1baad95cb18cec14a1b7f84b460b6f0b3cc";

これによってgrepしやすくなる。

$ gron "https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1" | grep commit.message
json[0].commit.message = "Merge branch 'master' of github.com:tkmru/dotfiles";

ungron

gronの出力結果をJSONに戻すには--ungronオプションを付ければいい。 以下のようにaliasを設定するよう、READMEで推奨されている。

alias norg="gron --ungron"
alias ungron="gron --ungron"

grepした結果をJSONで欲しいときに使える。

$ gron "https://api.github.com/repos/tkmru/dotfiles/commits?per_page=1" | grep commit.message | ungron
[
  {
    "commit": {
      "message": "Merge branch 'master' of github.com:tkmru/dotfiles"
    }
  }
]

diffもgronを使えば見やすい結果で取れる。

$ diff <(gron http://echo.jsontest.com/number/one) <(gron http://echo.jsontest.com/number/two)
2c2
< json.number = "one";
---
> json.number = "two";

JavaScriptから出力結果をさわる

出力されたテキストはJavaScriptのObjectとして扱える。

$ gron http://headers.jsontest.com/ > tmp.js
$ echo "console.log(json);" >> tmp.js
$ node tmp.js
{ Accept: 'application/json',
  Host: 'headers.jsontest.com',
  'User-Agent': 'gron/dev',
  'X-Cloud-Trace-Context': '0f152eb1d17dc08fd257b8b4383faaa6/9190834354357706108' }