zoukankan      html  css  js  c++  java
  • APP脱壳方法三

    第一步

    手机启动frida服务

    第二步

    手机打开要脱壳的app

    第三步编辑hook代码

    agent.js

    /*
    * Author: hluwa <hluwa888@gmail.com>
    * HomePage: https://github.com/hluwa
    * CreatedTime: 2020/1/7 20:44
    * */
    
    
    var enable_deep_search = false;
    
    function verify_by_maps(dexptr, mapsptr) {
        var maps_offset = dexptr.add(0x34).readUInt();
        var maps_size = mapsptr.readUInt();
        for (var i = 0; i < maps_size; i++) {
            var item_type = mapsptr.add(4 + i * 0xC).readU16();
            if (item_type === 4096) {
                var map_offset = mapsptr.add(4 + i * 0xC + 8).readUInt();
                if (maps_offset === map_offset) {
                    return true;
                }
            }
        }
        return false;
    }
    
    
    function get_dex_real_size(dexptr, range_base, range_end) {
        var dex_size = dexptr.add(0x20).readUInt();
    
        var maps_address = get_maps_address(dexptr, range_base, range_end);
        if (!maps_address) {
            return dex_size;
        }
    
        var maps_end = get_maps_end(maps_address, range_base, range_end);
        if (!maps_end) {
            return dex_size;
        }
    
        return maps_end - dexptr
    }
    
    function get_maps_address(dexptr, range_base, range_end) {
        var maps_offset = dexptr.add(0x34).readUInt();
        if (maps_offset === 0) {
            return null;
        }
    
        var maps_address = dexptr.add(maps_offset);
        if (maps_address < range_base || maps_address > range_end) {
            return null;
        }
    
        return maps_address;
    }
    
    function get_maps_end(maps, range_base, range_end) {
        var maps_size = maps.readUInt();
        if (maps_size < 2 || maps_size > 50) {
            return null;
        }
        var maps_end = maps.add(maps_size * 0xC + 4);
        if (maps_end < range_base || maps_end > range_end) {
            return null;
        }
    
        return maps_end;
    }
    
    
    function verify(dexptr, range, enable_verify_maps) {
    
        if (range != null) {
            var range_end = range.base.add(range.size);
            // verify header_size
            if (dexptr.add(0x70) > range_end) {
                return false;
            }
    
            // In runtime, the fileSize is can to be clean, so it's not trust.
            // verify file_size
            // var dex_size = dexptr.add(0x20).readUInt();
            // if (dexptr.add(dex_size) > range_end) {
            //     return false;
            // }
    
            if (enable_verify_maps) {
    
                var maps_address = get_maps_address(dexptr, range.base, range_end);
                if (!maps_address) {
                    return false;
                }
    
                var maps_end = get_maps_end(maps_address, range.base, range_end);
                if (!maps_end) {
                    return false;
                }
                return verify_by_maps(dexptr, maps_address)
            } else {
                return dexptr.add(0x3C).readUInt() === 0x70;
            }
        }
    
        return false;
    
    
    }
    
    rpc.exports = {
        memorydump: function memorydump(address, size) {
            return new NativePointer(address).readByteArray(size);
        },
        switchmode: function switchmode(bool) {
            enable_deep_search = bool;
        },
        scandex: function scandex() {
            var result = [];
            Process.enumerateRanges('r--').forEach(function (range) {
                try {
                    Memory.scanSync(range.base, range.size, "64 65 78 0a 30 ?? ?? 00").forEach(function (match) {
    
                        if (range.file && range.file.path
                            && (// range.file.path.startsWith("/data/app/") ||
                                range.file.path.startsWith("/data/dalvik-cache/") ||
                                range.file.path.startsWith("/system/"))) {
                            return;
                        }
    
                        if (verify(match.address, range, false)) {
                            var dex_size = get_dex_real_size(match.address, range.base, range.base.add(range.size));
                            result.push({
                                "addr": match.address,
                                "size": dex_size
                            });
                        }
                    });
    
                    if (enable_deep_search) {
                        Memory.scanSync(range.base, range.size, "70 00 00 00").forEach(function (match) {
                            var dex_base = match.address.sub(0x3C);
                            if (dex_base < range.base) {
                                return
                            }
                            if (dex_base.readCString(4) != "dex
    " && verify(dex_base, range, true)) {
                                var real_dex_size = get_dex_real_size(dex_base, range.base, range.base.add(range.size));
                                result.push({
                                    "addr": dex_base,
                                    "size": real_dex_size
                                });
                            }
                        })
                    } else {
                        if (range.base.readCString(4) != "dex
    " && verify(range.base, range, true)) {
                            // console.log("range.base=" + range.base);
                            var real_dex_size = get_dex_real_size(range.base, range.base, range.base.add(range.size));
                            // console.log("range.base=" + range.base + ", real_dex_size=" + real_dex_size);
                            result.push({
                                "addr": range.base,
                                "size": real_dex_size
                            });
                        }
                    }
    
                } catch (e) {
                }
            });
    
            return result;
        }
    };
    
    

    第四步

    运行脱壳代码

    # Author: hluwa <hluwa888@gmail.com>
    # HomePage: https://github.com/hluwa
    # CreatedTime: 2020/1/7 20:57
    import hashlib
    import os
    import random
    import sys
    
    try:
        from shutil import get_terminal_size as get_terminal_size
    except:
        try:
            from backports.shutil_get_terminal_size import get_terminal_size as get_terminal_size
        except:
            pass
    
    import click
    import frida
    import logging
    import traceback
    
    logging.basicConfig(level=logging.INFO,
                        format="%(asctime)s %(levelname)s %(message)s",
                        datefmt='%m-%d/%H:%M:%S')
    
    banner = """
    ----------------------------------------------------------------------------------------
      ____________ ___________  ___        ______ _______   _______                         
      |  ___| ___ \_   _|  _  / _        |  _    ___  / /  _                          
      | |_  | |_/ / | | | | | / /_ \______| | | | |__   V /| | | |_   _ _ __ ___  _ __    
      |  _| |    /  | | | | | |  _  |______| | | |  __| /   | | | | | | | '_ ` _ | '_    
      | |   | |  _| |_| |/ /| | | |      | |/ /| |___/ /^  |/ /| |_| | | | | | | |_) |  
      \_|   \_| \_|\___/|___/ \_| |_/      |___/ \____//   /___/  \__,_|_| |_| |_| .__/   
                                                                                   | |      
                                                                                   |_|      
                          https://github.com/hluwa/FRIDA-DEXDump                            
    ----------------------------------------------------------------------------------------
    """
    
    md5 = lambda bs: hashlib.md5(bs).hexdigest()
    
    
    def show_banner():
        try:
            if get_terminal_size().columns >= len(banner.splitlines()[1]):
                for line in banner.splitlines():
                    click.secho(line, fg=random.choice(['bright_red', 'bright_green', 'bright_blue', 'cyan', 'magenta']))
        except:
            pass
    
    
    def get_all_process(device, pkgname):
        return [process for process in device.enumerate_processes() if pkgname in process.name]
    
    
    def search(api):
        """
        """
    
        matches = api.scandex()
        for info in matches:
            click.secho("[DEXDump] Found: DexAddr={}, DexSize={}"
                        .format(info['addr'], hex(info['size'])), fg='green')
        return matches
    
    
    def dump(pkg_name, api, mds=None):
        """
        """
        if mds is None:
            mds = []
        matches = api.scandex()
        for info in matches:
            try:
                bs = api.memorydump(info['addr'], info['size'])
                md = md5(bs)
                if md in mds:
                    click.secho("[DEXDump]: Skip duplicate dex {}<{}>".format(info['addr'], md), fg="blue")
                    continue
                mds.append(md)
                if not os.path.exists("./" + pkg_name + "/"):
                    os.mkdir("./" + pkg_name + "/")
                if bs[:4] != b"dex
    ":
                    bs = b"dex
    035x00" + bs[8:]
                with open(pkg_name + "/" + info['addr'] + ".dex", 'wb') as out:
                    out.write(bs)
                click.secho("[DEXDump]: DexSize={}, DexMd5={}, SavePath={}/{}/{}.dex"
                            .format(hex(info['size']), md, os.getcwd(), pkg_name, info['addr']), fg='green')
            except Exception as e:
                click.secho("[Except] - {}: {}".format(e, info), bg='yellow')
    
    
    def stop_other(pid, processes):
        try:
            for process in processes:
                if process.pid == pid:
                    os.system("adb shell "su -c 'kill -18 {}'"".format(process.pid))
                else:
                    os.system("adb shell "su -c 'kill -19 {}'"".format(process.pid))
        except:
            pass
    
    
    def choose(pid=None, pkg=None, spawn=False, device=None):
        if pid is None and pkg is None:
            target = device.get_frontmost_application()
            return target.pid, target.identifier
    
        for process in device.enumerate_processes():
            if (pid and process.pid == pid) or (pkg and process.name == pkg):
                if not spawn:
                    return process.pid, process.name
                else:
                    pkg = process.name
                    break
    
        if pkg and spawn and device:
            pid = device.spawn(pkg)
            device.resume(pid)
            return pid, pkg
        raise Exception("Cannot found <{}> process".format(pid))
    
    
    if __name__ == "__main__":
        show_banner()
    
        try:
            device = frida.get_usb_device()
        except:
            device = frida.get_remote_device()
    
        if not device:
            click.secho("[Except] - Unable to connect to device.", bg='red')
            exit()
    
        pid = -1
        pname = ""
        try:
            pid, pname = choose(device=device)
        except Exception as e:
            click.secho("[Except] - Unable to inject into process: {} in 
    {}".format(e, traceback.format_tb(
                sys.exc_info()[2])[-1]), bg='red')
            exit()
        print(pname)
        processes = get_all_process(device, pname)
    
        mds = []
        for process in processes:
            logging.info("[DEXDump]: found target [{}] {}".format(process.pid, process.name))
            stop_other(process.pid, processes)
            session = device.attach(process.pid)
            path = os.path.dirname(sys.argv[0])
            path = path if path else "."
            script = session.create_script(open(path + "/agent.js").read())
            script.load()
            dump(pname, script.exports, mds=mds)
            script.unload()
            session.detach()
        exit()
    
    
  • 相关阅读:
    阿里云nginx创建多站点
    linux 卸载php mysql apache
    centos php环境搭建
    jquery simple modal
    nodejs 安装express
    nodejs fs.open
    nodejs supervisor
    nodejs 运行
    nodejs shell
    PHP array_pad()
  • 原文地址:https://www.cnblogs.com/pythonywy/p/13536130.html
Copyright © 2011-2022 走看看