利用frida实现游戏作弊

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_19683651/article/details/84830335

前言

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)

这里修改的时金币,点击购买,金币增加,完美作弊。

猜你喜欢

转载自blog.csdn.net/qq_19683651/article/details/84830335