備忘録

備忘録

Frida の使い方

Ⅰ. はじめに

Frida は JavaScriptを用いてでネイティブアプリをデバッグすることができる強力なツールです。
www.frida.re

Ⅱ. インストール

pip install frida

Ⅲ. 使い方

Androidのアプリをトレースする

※予めAndroidにfrida-serverを入れ、起動しておく必要があります。

frida-trace -U -i *Func* app
Windows上のプロセスをトレースする
frida-trace -i *Func* notepad.exe
引数を表示する
onEnter: function (log, args, state) {
  for(var i=0; i<10; i++) {
    log("Func args[" + i + "]" + Memory.readUtf8String(args[i]));
  }
},
メモリダンプ
function dump(pointer, length) {
  var buf = Memory.readByteArray(pointer, length);
  console.log(hexdump(buf, {
    offset: 0,
    length: length,
    header: true,
    ansi: true
  }));
}

dump(pointer, 16);

f:id:kagasu:20161124114917p:plain

レジスタ(ARMの例)
console.log("r0: " + this.context.r0);
console.log("r1: " + this.context.r1);
console.log("r2: " + this.context.r2);
console.log("r3: " + this.context.r3);
console.log("r4: " + this.context.r4);
console.log("r5: " + this.context.r5);
console.log("r6: " + this.context.r6);
console.log("r7: " + this.context.r7);
直接アドレスを指定してメモリを読み取る
var pointer = new NativePointer("0x7ad1a4d0");
var buf1 = Memory.readUtf8String(pointer);
console.log(buf1);
メモリを書き換える
// 0x1CCA61C に 0x01を1バイト書き込む
Memory.writeS8(0x1CCA61C, 0x01);
アドレス(ポインタ)にオフセットを加える
function addOffset(pointer, offset) {
  var address = parseInt(pointer) + offset;
  var addressHex = "0x" + address.toString(16);
  return new NativePointer(addressHex);
}

addOffset(pointer, 0x10);
文字列を表示する(IL2CPP用)
function dumpString(pointer) {
  // length
  var lengthPointer = addOffset(pointer, 0x8);
  var length = Memory.readInt(lengthPointer);

  // data
  var dataPointer = addOffset(pointer, 0xC);
  var str = Memory.readUtf16String(dataPointer, length);
  console.log("[" + str + "]");
}
ネイティブ関数アドレスを取得し、呼び出す
function getFunctionPointer(moduleName, offset, ret, args) {
  var lib = Module.findBaseAddress(moduleName);
  var address = parseInt(lib) + offset;
  var functionPointer = new NativePointer("0x" + address.toString(16));
  var func = new NativeFunction(functionPointer, ret, args);
  return func;
}

var func = getFunctionPointer('libil2cpp.so', 0x1CCA61C, 'pointer', ['pointer', 'pointer']);

var result = func(thisPointer, arg);

Windows で send を frida-trace する場合の例

1. frida-trace する

frida-trace -i "send" hoge.exe

2. send.js を書き換える

onEnter: function (log, args, state) {
  var length = parseInt(args[2]);
  var buf = Memory.readByteArray(args[1], length);
  console.log(hexdump(buf, {
    offset: 0,
    length: length,
    header: true,
    ansi: true
    }));
},

オフセットを指定する場合

frida-trace -U -a libxxx.so!13c8112 xx.xx.xx

その他

System.Security.Cryptography.RijndaelManagedTransform のコンストラクタはkey,ivを引数に取っている
SymmetricAlgorithm の set_Key など

criWareUnity_SetDecryptionKey
System.Security.Cryptography.HashAlgorithm の ComputeHash
BestHTTP の set_RawData はPOSTデータ
BestHttpのSSL証明書チェックはICertificateVerifyerを継承しているIsValidメソッドで行われている。