Android Game Cheat with Frida

Last Update Article: 2024-01-29 13:20:18


Android Game Cheat with Frida

Assalamualaikum warahmatullahi wabarakatuh, pada tulisan kali ini setelah melakukan cheating pada platform Windows Game / Desktop Game kali ini saya akan menuliskan hal yang telah saya pelajari, yaitu cheating dengan menggunakan frida di platform android, ide dari tulisan ini adalah memanfaatkan frida untuk berinteraksi dengan libshared milik aplikasi android dan melakukan patching flow code-nya.

  1. https://play.google.com/store/apps/details?id=net.cubers.assaultcube&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1

Untitled

Game yang ditargetkan adalah seperti Screenshot di atas, bisa diunduh di tautan Play Store di atas, berikut ini adalah langkah-langkah yang dapat ditempuh.

  1. Extract Application from Devices

    1. adb shell pm list packages -f | findstr assault

      Untitled

    2. ls :/data/app/~~hacSXCjloDQ9GB_QFwLRHg==/net.cubers.assaultcube-UisYnvIoXF_Xd7EpXZ3UwQ==

      Untitled

    3. adb pull /data/app/~~hacSXCjloDQ9GB_QFwLRHg==/net.cubers.assaultcube-UisYnvIoXF_Xd7EpXZ3UwQ==/base.apk

      Untitled

    4. Reverse the Application

      Pada proses ini kita dapat menggunakan JADX untuk mengetahui aplikasi ini berjalan dengan skema kode dan algoritma bagaimana.

      Untitled

      Jika dilihat dari AndroidManifest.xml tidak ada yang menarik dari permission yang ada juga tidak ada yang spesial dari intent yang didefinisikan, kita dapat mulai melakukan eksplokrasi ke LaunchActivity.

      Untitled

      Tidak ada yang menarik dari kode-kode JAVA yang ada, dikarenakan semua algoritma diload pada AssaultCubeLib dan berikut adalah isinya

      Untitled

      Dari kode yang ada, semua algoritma dan skema permainan diload dalam loadLibrary dengan nama file [libmain.so](http://libmain.so) kita dapat mengunduhnya di

       adb pull /data/app/~~hacSXCjloDQ9GB_QFwLRHg==/net.cubers.assaultcube-UisYnvIoXF_Xd7EpXZ3UwQ==/lib/x86_64/libmain.so

      Untitled

    Analyze the ELF Library

    Kita dapat menggunakan beberapa tools public untuk melakukan analisa, ada beberapa tools seperti

    1. IDA Pro / IDA Free
    2. Binary Ninja
    3. Ghidra
    4. Radare2 / Cutter

Namun sepengalaman saya pada kasus ini, tools paling kacau ada di Ghidra, dan terbaik ada di IDA Pro, namun pada tulisan ini kita dapat menggunakan Radare2 / Binary Ninja. Sebelum melakukan analisa cepat, saya biasanya melakukan analisa symbol-symbol apa saja yang di-load oleh [libmain.so](http://libmain.so) saya menggunakan frida untuk hal ini, berikut ini code yang saya gunakan

var libAddr = Module.findBaseAddress('libmain.so');

Module.enumerateExports("libmain.so", {
  onMatch: function (exp) {
    console.log("Exported symbol: " + exp.name + " at address: " + exp.address);
  },
  onComplete: function () {
    console.log("Export enumeration complete");
  }
});

Module.enumerateSymbols("libmain.so", {
    onMatch: function (symbol) {
      console.log("Loaded Symbol: " + symbol.name + " at address: " + symbol.address);
    },
    onComplete: function () {
      console.log("Symbol enumeration complete");
    }
});

Script tersebut akan dijalankan dengan loader, loader ini yang akan berfungsi melakukan spawing terhadap aplikasi juga akan melakukan load script ke targeted attach, berikut kode loadernya (pemilik asli)

import time,frida

device = frida.get_usb_device()
print(device)
pid = device.spawn(["net.cubers.assaultcube"])
device.resume(pid)
time.sleep(5)
# print(device.enumerate_processes())
session = device.attach(pid)
with open("debug.js") as f:
    script = session.create_script(f.read())
script.load()

input()

Kode kita akan ditulis pada debug.js dan menjalankan frida via python, jalankan saja loadernya dan kita akan mendapatkan Exported Symbol dan Loaded Symbol yang akan dipanggil dari [libmain.so](http://libmain.so) saya melakukan analisa manual, dan mendapatkan beberapa fungsi yang menarik dari Symbol yang ada antara lain

Exported symbol: _ZTV6weapon at address:
Exported symbol: _Z12damageeffectiP9playerent at address: 0x73ce1992e300
Exported symbol: hitplayer at address: 0x73ce19b037c8
Exported symbol: __dummy_playerinfo at address: 0x73ce19afcad5
Exported symbol: damageindicatordist at address: 0x73ce19b0a8fc
Exported symbol: _ZN11playerstate8dodamageEii at address: 0x73ce198691a0

Hal-hal paling menarik dan menjadi target kita adalah pada _ZN11playerstate8dodamageEii kita dapat menggunakan keywords, damage untuk mencari Symbol tersebut dalam decompiler

Untitled

Symbol tersebut ternyata juga melakukan reference ke function dodamage yang berada pada state playerstate kita dapat memfokuskan pada fungsi dodamage

Untitled

Dari kode di atas, kita dapat melakukan debbuging, dengan Interceptor untuk mengetahui apakah memang kode di atas terpanggil atau tidak, kita dapat menggunakan frida seperti berikut ini untuk debbuging.

var libAddr = Module.findBaseAddress('libmain.so');

try{
    var interceptdamage = Interceptor.attach(libAddr.add(0x9be40), {
        onEnter: function(args){
            console.log("Im in")
            console.log("Arg0: " + args[0].toInt32());
            console.log("Arg1: " + args[1].toInt32());
            console.log("Arg2: " + args[2].toInt32());
            console.log("Arg3: " + args[3].toInt32());
            console.log("Arg4: " + args[4].toInt32());
            console.log("Arg5: " + args[5].toInt32());

        }
    });
}catch(e){
    console.log(e, "Halo");
}

Interceptor.attach(libAddr.add(0x9be40) pada line tersebut copykan address yang ada pada BinaryNinja tepat pada fungsi dodamage

Untitled

Dan akan mendapatkan 0x9be40 saat dijalankan akan mendapatkan hasil seperti berikut ini

Untitled

Dan benar saja, fungsi dodamage akan terpanggil dan terlihat pada console terlihat 6 argumen yang sesuai dengan fungsi hasil dekompilasi yang ada, dari sini kita dapat memetahkan beberapa argumen yang ada

Argumen 0 → adalah damage yang masuk ke player

Argumen 1 → address target pemain yang akan diberi damage

Argumen 2 → address pemberi damage

Itulah argumen-argumen yang dapat kita kontrol untuk melakukan cheating, idenya adalah kita dapat merubah damage yang masuk ke address kita untuk menjadikannya 0 dan merubah damage kita menjadi yang paling besar atau menjadikannya 500, langkah pertamanya adalah dengan mencari base address dari player kita sendiri, pada dodamage sudah terdapat base player address milik kita

Untitled

Lakukan double click ke variable player 1 dan akan mendapatkan address 0x32df98 dan kita sudah lengkap untuk membuat cheat code frida kita, berikut ini full codenya

var libAddr = Module.findBaseAddress('libmain.so');
console.log("libmain.so address: " + libAddr);

// console.log(libAddr.add(0x7151efd5c1a0));

// Module.enumerateExports("libmain.so", {
//   onMatch: function (exp) {
//     console.log("Exported symbol: " + exp.name + " at address: " + exp.address);
//   },
//   onComplete: function () {
//     console.log("Export enumeration complete");
//   }
// });

try{
  var interceptdamage = Interceptor.attach(libAddr.add(0x98c20), { //0019be40
      onEnter: function(args){
          console.log("Player info")
          console.log("Arg0: " + args[0].toInt32());
          console.log("Arg1: " + args[1].toInt32());
      }
  });
}catch(e){
  console.log(e, "Halo");
}

try{
    var interceptdamage = Interceptor.attach(libAddr.add(0x9be40), { //0019be40
        onEnter: function(args){
            console.log("Im in")
            console.log("Arg0: " + args[0].toInt32());
            console.log("Arg1: " + args[1].toInt32());
            console.log("Arg2: " + args[2].toInt32()); // target attack 1499958976 0x32df98 0042df98
            console.log("Arg3: " + args[3].toInt32());
            console.log("Arg4: " + args[4].toInt32());
            console.log("Arg5: " + args[5].toInt32());

            var playerptr = ptr(0x32df98)
            var fixedAddr = libAddr.add(playerptr)
            var fixplayeraddr = Memory.readPointer(fixedAddr)

            if(fixplayeraddr.toInt32() == args[1].toInt32()){
                console.log("Patching damage incoming to 0")
                args[0] = ptr(0x0)
            }

            if(fixplayeraddr.toInt32() == args[2].toInt32()){
                console.log("Patching damage outgoing to 0x7fffffff")
                args[0] = ptr(0x200)
            }
        }
    });
}catch(e){
    console.log(e, "Halo");
}

Result of Cheating

Untitled

Terlihat pada gambar di atas, saya menghadapi 2 orang musuh terkena damage dan masih memiliki jumlah HP 100 dikarenakan kita sudah melakukan patching damage masuk ke player kita, dan juga seharusnya saat kita melakukan damage ke musuh kita akan mengirimkan damage paling besar ke musuh.

Penutup

Terima kasih sudah membaca dokumentasi saya untuk belajar cheating ini, semoga dapat terus berkembang dan dapat bermanfaat bagi kegiatan yang lain.