iOS基于Schema协议实现应用识别(金融风控业务,高风险应用,安装多头等软件识别)

1.schema判断是否安装了某app

①.判断代码

//schema协议前缀
NSString *schema = "wemeet://";
NSURL *url = [NSURL URLWithString:schema];
//判断应用是否安装
bool installed  = [[UIApplication sharedApplication] canOpenURL:url];

②.在info.plist文件新增配置

新增key:LSApplicationQueriesSchemes Type:Array
新增items,配置需要识别的app schema参数。

LSApplicationQueriesSchemes

2.如何获取AppStore上某个App的Schema配置列表

①在Mac OSX中安装Apple Configurator 2软件,打开软件并在apple账号

②准备一台iPhone,该设备上登录的账号和Apple Configurator 2登录的账号保持一致,并手机连接到电脑上。

③打开iPhone设备上的AppStore app,搜索你所需的app,点击安装按钮,等app安装成功后再进行下一步。

④在Apple Configurator 2软件的所有设备面板中双击选中设备,点击添加->在搜索栏输入刚在iPhone设备中下载的App->搜索到后点击选中App->点击添加按钮。

下载APP界面

⑤下载后会询问iPhone中已经存在该app的提示信息,注意这一步非常重要,弹出对话框后不要对对话框做任何操作,进入下一步。

image-20210928144012130

⑥打开finder(访达),按快捷键shift+command+G,在弹出前往文件夹对话框中输入内容~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps,再敲下回车。进入文件夹可以看到刚才下载的app的安装包。

安装包下载目录

⑦解压ipa文件找到info.plist文件并找到schema配置列表

将要.ipa文件的扩展名改成.zip解压文件,然后进入Payload文件夹->右击XXX文件->选择查看包内容->找到info.plist文件,用文本编辑器打开该文件,找到CFBundleURLTypes配置项,配置项下就是schema列表。

我写了一个快速查看.ipaSchema内容的Java程序,如下:

依赖

<dependency>
  <groupId>com.googlecode.plist</groupId>
  <artifactId>dd-plist</artifactId>
  <version>1.23</version>
  <scope>test</scope>
</dependency>

ParseIpaTests.java

public class ParseIpaTests {

    public static void main(String[] args) {
        String path = "/Users/pengjianbo/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps";
        File file = new File(path);
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files == null || files.length == 0) {
                return;
            }
            File dir = files[0];
            File[] files2 = dir.listFiles();
            if (files2 == null || files2.length == 0) {
                return;
            }
            for (File file1 : files2) {
                if(!file1.isDirectory()){
                    continue;
                }
                File[] files3 = file1.listFiles();
                if (files3 == null || files3.length == 0) {
                    return;
                }

                for (File f : files3) {
                    if (!StringUtils.endsWith(f.getAbsolutePath(), ".ipa")) {
                        continue;
                    }

                    IpaService.getIpaInfoMap(f.toString());
                }
            }
        }
    }
}

IpaDao.java

public class IpaDao {

    private static final int buffer = 2048;

    /**
     * 解压Zip文件
     * @param ipaPath 文件目录
     * @throws IOException
     */
    public static File unZip(String ipaPath) throws IOException {
        int count = -1;
        File file = null;
        InputStream is = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        ZipFile zipFile = null;
        File result = null;

        String savepath = "";
        savepath = ipaPath.substring(0, ipaPath.lastIndexOf(".")) + File.separator;
        File existsSavePath = new File(savepath); // 创建保存目录
        if(existsSavePath.exists()){
            existsSavePath.delete();
        }
        existsSavePath.mkdir();

        zipFile = new ZipFile(ipaPath); // 解决中文乱码问题
        Enumeration<?> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            byte buf[] = new byte[buffer];
            ZipEntry entry = (ZipEntry) entries.nextElement();
            String filename = entry.getName();
            boolean ismkdir = false;
            // 检查此文件是否带有文件夹
            if (filename.lastIndexOf("/") != -1) {
                ismkdir = true;
            }
            filename = savepath + filename;
            // 如果是文件夹先创建
            if (entry.isDirectory()) {
                file = new File(filename);
                file.mkdirs();
                continue;
            }
            file = new File(filename);
            // 如果是文件夹先创建
            if (!file.exists()) {
                if (ismkdir) {
                    new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs(); // 目录先创建
                }
            }
            file.createNewFile(); // 创建文件
            //判断文件名字
            if(filename.endsWith(".app/Info.plist")) {
                result = new File(filename);
            }

            is = zipFile.getInputStream(entry);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos, buffer);

            while ((count = is.read(buf)) > -1) {
                bos.write(buf, 0, count);
            }
            bos.flush();
            bos.close();
            fos.close();

            is.close();
        }
        zipFile.close();

        try {
            if (bos != null) {
                bos.close();
            }
            if (fos != null) {
                fos.close();
            }
            if (is != null) {
                is.close();
            }
            if (zipFile != null) {
                zipFile.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

IpaService.java

public class IpaService {
    /**
     * 1.生成info.plist文件的键值对
     *
     * @param ipa 输入api文件的路径
     * @return map Info.plist文件中的信息转为键值对 .api文件---->.zip文件---->返回Info.plist
     */
    public static String getIpaInfoMap(String ipaPath) {
        try {
            File Infofile = IpaDao.unZip(ipaPath);

            // 解析路径中的文件,封装到map集合
            NSDictionary parse = (NSDictionary) PropertyListParser.parse(Infofile);
            try {
                NSString CFBundleDisplayName = (NSString) parse.get("CFBundleDisplayName");
                if(CFBundleDisplayName == null){
                    CFBundleDisplayName = (NSString) parse.get("CFBundleName");
                }
                System.out.println("CFBundleDisplayName=" + CFBundleDisplayName.getContent());
                NSArray urlTypes = (NSArray) parse.get("CFBundleURLTypes");
                if (urlTypes == null) {
                    return null;
                }
                for (NSObject nsObject : urlTypes.getArray()) {
                    NSDictionary dictionary = (NSDictionary) nsObject;
                    NSArray nsArray = (NSArray) dictionary.get("CFBundleURLSchemes");
                    if (nsArray == null) {
                        return null;
                    }
                    for (NSObject object : nsArray.getArray()) {
                        NSString nsStr = (NSString) object;
                        System.out.println("CFBundleURLSchemes=" + nsStr.getContent());
                    }
                }
            }catch (Throwable e){
                e.printStackTrace();
            }

            String infoPlist = digui(parse, -1);
            return infoPlist;
        } catch (Exception e) {
            JPanel panel = new JPanel();
            JOptionPane.showMessageDialog(panel, "文件类型不支持", "提示", JOptionPane.WARNING_MESSAGE);
        }
        return null;
    }

    /**
     * 2.递归方法
     *
     * @param sb
     * @return
     */
    public static String digui(NSDictionary parse, int count) {
        ++count;
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, NSObject> entry : parse.entrySet()) {
            // 获取文档键对应的值
            String object = entry.getValue().toString();
            // 获取文档键
            String key = entry.getKey();
            // 1.判断是否是其他类型
            if (object.contains("NSArray") || object.contains("NSDictionary")) {

                // 1.1数组类型判断
                if (object.contains("NSArray")) {
                    NSObject[] array = ((NSArray) parse.get(key)).getArray();
                    // 1.1.1先添加主键
                    for (int i = 0; i < count; i++) {
                        sb.append("\t");
                    }
                    sb.append(key + ":" + "\r\n");

                    // 1.1.2判断值类型
                    for (int i = 0; i < array.length; i++) {
                        //如果是字典类型,继续递归
                        if (array[i].toString().contains("NSDictionary")) {
                            NSDictionary parse3 = (NSDictionary) array[i];
                            String digui2 = digui(parse3, count);
                            sb.append(digui2);
                        }
                        //如果是数值,直接添加
                        else {
                            for (int j = 0; j < count; j++) {
                                sb.append("\t");
                            }
                            sb.append("\t" + array[i] + "\r\n");
                        }
                    }
                }
                //1.2字典类型判断
                else {
                    for (int i = 0; i < count; i++) {
                        sb.append("\t");
                    }
                    sb.append(key + ":" + "\r\n");
                    NSDictionary parse2 = (NSDictionary) parse.get(key);
                    String digui3 = digui(parse2, count);
                    sb.append(digui3);

                }
            }

            // 2.如果是键值对类型直接添加
            else {
                for (int i = 0; i < count; i++) {
                    sb.append("\t");
                }
                sb.append(key + ":" + parse.get(key) + "\r\n");
            }
        }
        return sb.toString();
    }
}

schema列表(金融借贷、高风险应用)

  • 金融借贷
应用名称Schema应用名称Schema
柚卡hnzycfctqh连连来钱wx12a20f8d38242e27或LSApplicationQueriesSchemes
拍拍贷loan.ppdai.com秒贷款wxed7adf75b1686f8d
榕树贷brbanyanrxq捷信金融capp或capppro
省呗shansmycredit洋钱罐借款zebra
招联金融muapp或mucfcapp小赢分期xyfq
新浪金融sinajr拉卡拉lkl
你我贷jiaxuedai好分期hfqdl
平安好贷pahd哈银消金hrbbapp
有钱花duxiaomanloan幸福花hcfc-url
360借条qihooloan维信闪贷vblotloan
安逸花msxfayh或ayh蒙商消费金融com.baoyin.credit
分期乐fenqile中邮钱包zywallet
小米贷款miloan众安小贷zaloan
中原消费金融hnzycfc虫虫借钱tcfclient
携程金融CtripFinanceIphone或CtripFinancephone戒易花alipay20200908jiyihua
榕易有钱brbanyan喜鹊快贷yddapp
度小满金融duxiaomanwallet或dxmwallet万达普惠wandaph或wandapuhui
够花Gouhua融360贷款R360BigApp
还呗huanbei或eloan大地时贷wx990b73cc7f6f7b58
来分期laifenqi秒借钱包daikuangou
微贷借款CreditLoan金山金融com.kingsoft.finance.ios
时光分期shiguangfenqi功夫贷gongfudai
宜人贷借款dkzs或yrdweb微博钱包weiboqb
小米借条miloanx短借wx8c159bc0ea6b0167
小马花花msxfxmhh或msxfxmhh.msxf.com携程借款CtripJdIphone或CtripJdphone
摇钱花xywallet好来贷com.jinqiao.app.fsb
360信用钱包qihooloanxyqb无域借贷款wx78c5ff4e90635095
万卡wanka运呗yunbei
新浪分期xlfq或XLFQby借钱花mycardpro或cardniu
豆豆钱doudoumoneyschem安逸花极速版ayhlite
备胎信用btcredit融360贷款R360BigApp
人人贷借款rrdloan有钱花极速版duxiaomanloanlite
魔借drm-borrower或dianrong-speedloan苏宁金融SuningEfubao或com.suning.jr
海尔消费金融haiercashhf或haiercashlx极融借款geerong
小闪分期com.weishangtech.kskd随借wx23183233650713f6
省呗smycredit团贷网借款tuandailoan
马上金融msxfapp或msxfFinance晋享钱包jxqb
天星金融mifi顺丰金融sfpay
万达贷wdp或wdsd小花钱包xhqball
360分期贷qihooloanfenqidai你我贷niwodai
榕树借条brbanyanrxq杭银金融hyxfapp或HyxfApp
国美金融mylc或gmfinstall苏宁消费金融sncfc或sncfcrxf
还呗-还享借hbcash中银消费金融boccfc
平安普惠PAYiDai平安消费金融pacfc
新橙优品xincheng长银消费金融LoanRouter
花鸭借钱ppxiaodai或leading.huayajieqian.com华融消费金融hrcfc
人品贷极速版en51rpd阳光消费ygxf
民生易贷msyd或MSYiDai金美信金融wx58b7be61ba0c7dee
备好贷btloan尚诚消费金融shangcheng
安心花wx017de833e85e4969盛银消费金融cn.com.syxfjr.ios
平安贷款pinganbankloan好哒白条wx49abd2e0bb9054c6
招联好期贷hqd信而富crfMarket
度小满金融Litebwapp或baiduwallet或dxmwallet鑫梦享wx4dc5cf62862e49d2
分期乐借钱fenqileBorrow易开花bobcfc
国美易卡gomeyk消邦hyxbapp
快易花wdkyhKOO钱包koou
U钱包drm-uloan小鱼福卡fishcard
任意花easymoney融易分期ryfq
羊小咩xyqb空手到icfapp
宜享花yixianghua易启分期hengshenhuo
维信卡卡贷kkcreditSchem嗨袋hubeicfcApp
浪小花wb898990797畅行花comchangxinghuacxh
榕树贷款brbanyan桔多多juzifenqi
58好借JRHaoJie云联掌柜ylzg
百信银行bxbank分期易qmwalle1Enterprise
  • 高风险(VPN/赌博/改机/等)
应用名称Schema应用名称Schema
dream gamingdgcomCydiacydia
轻蜂QingFengMelon VPNmvpn
蓝鲸LanJingVPNfb2402988699750088
快滚加速器wx3fc209ff51356358VPN Masterfb198196255460714
豌豆代理peaSchemeVPNvpn
羚羊加速器lingyangAlohaalohabrowser
SpeedCNwx8e8fc8f4aacfc4acProtonVPNprotonvpn
雷霆加速器ixfPowerVPNfb2497899243660498
雄鹰加速器XiongYingSkyBlueVPNfb1125906797743109
Ad BlockerVRNGuardUltraVPNhexatech
爱加速wx3405e18bc8a44f32Kiwi VPNfb496564300896313
PandaVPNPandaProSchemesVPN-Speedvpnspeed
VPN VaultavvpnVPNfb565441297335453
VPN MastermasterVPNVPN Pointfb460872174508891
Turbo VPNturboVPNDaily VPNopen-dailyvpn
VPN – Super Unlimited Proxyfb828149437372042SkyVPNskyvpn
BetternetbetternetVPNHUBcom.appatomic.vpnhub
Free VPNfb1075780229101015VPN – Unlimited Best VPN Proxyfb365179700576422
NordVPNnordvpnSillyDuckVPNshayavpn
X-VPNfb314076509753471Hotspot VPN - VPN Proxy Masterfb1556715627872273
ArmorVPNfb2802590519990758PandaVPNPandaLiteSchemes
ExpressVPNexpressvpnWindscribecom.windscribe
Quark VPNssStorm Vpnfb2805514809729562
Atlas VPNATLASVPNiTopVpnfb5467826609957522
VPN 360vpn360VPNfb716550731879004
PsiphonpsiphonVPNfb424636185280544
Secure VPNfb1035581440282875VyprVPNvyprvpn
Jet VPNjetvpnRayVPNvpnext
VPN Pantherfb2512983252125630TorVPNvpntorbrowser
如果觉得我的文章对你有用,请随意赞赏