1. 程式人生 > >利用frida實現遊戲作弊

利用frida實現遊戲作弊

前言

frida是一款輕量級hook框架,支援js、c,python,所以用它來除錯各種軟體非常便捷,不需要編譯,反覆注入等等

安裝

python環境

pip install frida frida-tools

原始碼地址 https://github.com/frida/frida
下載地址 https://github.com/frida/frida/releases
將frida-server push到手機中,並啟動

除錯

遊戲逆向

該遊戲時il2cpp的,獲取到遊戲函式偏移。

	public void UpdateGold(int addGold)
; // 0x1A05AC

編寫指令碼

啟動遊戲。發現存在反除錯,已經被attach了。
在這裡插入圖片描述
這是咋辦呢?正常情況下,如果是so注入的話,一般有這麼些思路:

  • 注入zygot程序,然後由zygot 進行fork,這樣所有app都被注入
  • 預載入程式時暫停(am start -D -n XXXXX啟動),然後ptrace注入,在detach
  • 修改原始碼,編譯過程複雜,耗時間

這裡frida支援預載入注入,編寫指令碼main.py

# -*- coding: utf-8 -*-
# @Author: saidyou
# @Date:   2018-07-10 01:51:54
# @Last Modified by: saidyou # @Last Modified time: 2018-12-05 10:24:10 # -*- coding: utf-8 -*- import frida import sys import os from struct import * import traceback package_name = 'com.ztgame.yyzy' # package_name = 'com.sdg.woool.xuezu' #send js_name = 'yyzy.js' is_launch = 1 pwd = sys.path[0]
script = None session = None protocal_list = [] def port_forward(): os.system('adb forward tcp:27042 tcp:27042') os.system('adb forward tcp:27043 tcp:27043') def get_js_code(): buf = open(pwd+'\\'+js_name).read() return buf def send_continue(): script.post({"type": "continue"}) def witch_pro_num(pro_num): for line in protocal_list: if line.find(pro_num)+1: print line[:-1] return line def on_message(message, data): global lua_num try: if data and len(data)>0: aaaa='' else: return if message['payload'].find('save')+1: open('e:\\'+message['payload'],'wb+').write(data) elif message['payload']=='send' : # print type(data),len(data),`data` protocal_num = unpack('<H',data[:2])[0] pro_buf = witch_pro_num(hex(protocal_num)) if pro_buf.find('pt_state_skill')+1: send_continue() elif message['payload'] == 'Assembly-CSharp.dll' : open('e:\\Assembly-CSharp.dll','wb').write(data) else : # print message['payload'] file_type = '.lua' if data[:4]=='\x1bLua': file_type = '.luac' full_path = 'e:\\lua\\'+message['payload'].replace('/','\\')+file_type full_dir = full_path[:full_path.rfind('\\')] if os.path.exists(full_dir) == False: os.system('mkdir '+full_dir) print full_path open(full_path,'wb+').write(data) except: traceback.print_exc() def attach(): global script global session device = frida.get_usb_device() session = device.attach(package_name) script = session.create_script(get_js_code()) script.on('message', on_message) script.load() sys.stdin.read() def launch(): global script global session # local device = frida.get_usb_device() # remote #device = frida.get_device_manager().add_remote_device('192.168.123.20') p1 = device.spawn([package_name]) session = device.attach(package_name) script = session.create_script(get_js_code()) script.on('message', on_message) script.load() device.resume(p1) sys.stdin.read() def main(): reload(sys) sys.setdefaultencoding('utf-8') port_forward() if is_launch: launch() else: attach() if __name__ == '__main__': main()

hook程式碼yyzy.js

/*
* @Author: saidyou
* @Date:   2018-11-27 10:41:42
* @Last Modified by:   saidyou
* @Last Modified time: 2018-12-04 19:43:31
*/


function get_func_by_offset(module_name,offset){
    module=Process.getModuleByName(module_name)
    addr=module.base.add(offset);
    return new NativePointer(addr.toString());
}
// UpdateGold 0x1A05AC
function attach_gold(so_path){
    func = get_func_by_offset("libil2cpp.so",0x1A05AC)
    console.log('[+] hook '+func.toString())
    Interceptor.attach(func, {
        onEnter: function (args) { 
            console.log('**********************')
            var1 = args[1].toInt32()
            args[1] = ptr(999)
            console.log('[!] modify UpdateGold from '+var1+' to 1000')
            console.log('[*] '+args[1].toString())
        },
        onLeave: function (retval) {

        }
    });
}

var is_matched = false;

function attach_matched(so_path){
    if(so_path.indexOf('libil2cpp.so')<0 || is_matched == true){
        return
    }
    is_matched = true
    console.log('[*] '+so_path)
    attach_gold(so_path)

}

function hook_dlopen(){
    // func = get_func_by_offset('libc.so','dlopen')//492d
    // func = Module.findExportByName("linker","dlopen") //33ed
    var func = get_func_by_offset('linker',0x2C31  )

    console.log('[+] dlopen '+ func.toString())
    Interceptor.attach(func, {
        onEnter: function (args) { 
            this.so_path =  Memory.readCString(args[0])
            console.log('[*] ')
        },
        onLeave: function (retval) {
            // console.log(this.so_path)
            attach_matched(this.so_path)
        }
    });
}


hook_dlopen()
// hook_open()

// addr = DebugSymbol.getFunctionByName('dlopen')
// console.log(addr)

這裡修改的時金幣,點選購買,金幣增加,完美作弊。