精华内容
下载资源
问答
  • 本软件让手机麦克风持续保持静音,使录音机程序无法录到声音,达到本机窃听的目的。第二种可能性,当手机监听到用户从浅睡进入深睡状态时,立即播放短促躁音,使退回浅睡,达到睡眠破坏的目的;对于这种木马程序,...
  • 本软件让手机麦克风持续保持静音,使录音机程序无法录到声音,达到本机窃听的目的。第二种可能性, 当手机监听到用户从浅睡进入深睡状态时,立即播放短促躁音,使退回浅睡,达到睡眠破坏的目的; 对于这种木马...
  • 本软件让手机麦克风持续保持静音,使录音机程序无法录到声音,达到本机窃听的目的。第二种可能性,当手机监听到用户从浅睡进入深睡状态时,立即播放短促躁音,使退回浅睡,达到睡眠破坏的目的;对于这种木马程序,...
  • 最近公司需要做个APP下载的功能,并且监听下载状态以及判断是否安装成功。 --可用于应用更新 --可用于广告下载类 本来想使用okdownload,但是想想既然android提供了api我又何必依赖一个三方库呢。 -----------...

    最近公司需要做个APP下载的功能,并且监听下载状态以及判断是否安装成功。

    --可用于应用更新

    --可用于广告下载类

    本来想使用okdownload,但是想想既然android提供了api我又何必依赖一个三方库呢。

    -----------用于记录download manager的简单使用,方便以后ctrl  +c/v--------------------

     

    直接上代码,我会注释清楚的

    使用:

     new DownloadUtils(context,url,"test.apk").startDownloadWithNoReport();
     //或者
     new DownloadUtils(context,url,"test.apk").startDownloadWithReport([此处是上报链接参数]...);

    源码:

    package com.xmiles.hytechad.utils;
    
    import android.app.Activity;
    import android.app.DownloadManager;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Environment;
    
    import androidx.annotation.NonNull;
    import androidx.core.content.FileProvider;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class DownloadUtils {
        //下载器
        private DownloadManager downloadManager;
        private Context mContext;
        //下载的ID
        private long downloadId;
        private String name;
        private String pathstr;
        private String url;
        private boolean isNeedReport;
        //通知相关
        private String notifyTitle = "正在下载", notifyContent = "请稍等";
        //上报相关地址
        private ArrayList<String> mAdBeginDownUrl;
        private ArrayList<String> mAdEndDownUrl;
        private ArrayList<String> mAdBeginInstallUrl;
        private ArrayList<String> mAdEndInstallUrl;
    
    
        public DownloadUtils(@NonNull Context context, @NonNull String url, @NonNull String name) {
            this.mContext = context;
            this.name = name;
            this.url = url;
        }
    
        public DownloadUtils setNotify(@NonNull String title, @NonNull String content) {
            notifyTitle = title;
            notifyContent = content;
            return this;
        }
    
        public void startDownloadWithNoReport() {
            isNeedReport = false;
            downloadAPK(url, name);
        }
    
        public void startDownloadWithReport(ArrayList<String> appBeginDown, ArrayList<String> appEndDown, ArrayList<String> appBegininstall, ArrayList<String> appEndinstall) {
            isNeedReport = true;
            mAdBeginDownUrl = appBeginDown;
            mAdEndDownUrl = appEndDown;
            mAdBeginInstallUrl = appBegininstall;
            mAdEndInstallUrl = appEndinstall;
    
            downloadAPK(url, name);
        }
    
        //下载apk
        private void downloadAPK(String url, String name) {
            //创建下载任务
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
            //移动网络情况下是否允许漫游
            request.setAllowedOverRoaming(false);
            //在通知栏中显示,默认就是显示的
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
            request.setTitle(notifyTitle);
            request.setDescription(notifyContent);
            request.setVisibleInDownloadsUi(true);
    
            //设置下载的路径
            File file = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), name);
            request.setDestinationUri(Uri.fromFile(file));
            pathstr = file.getAbsolutePath();
            //获取DownloadManager
            if (downloadManager == null)
                downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
            //将下载请求加入下载队列,加入下载队列后会给该任务返回一个long型的id,通过该id可以取消任务,重启任务、获取下载的文件等等
            if (downloadManager != null) {
                downloadId = downloadManager.enqueue(request);
            }
            if (isNeedReport) {  //是否需要监听/上报安装状态
                
                //上报开始下载
                ReportUtils.reportAdBeginDownload(mAdBeginDownUrl);
                //需要上报则注册广播
                IntentFilter intentFilter = new IntentFilter();
                intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
                intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
                intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
                intentFilter.addDataScheme("package");
                mContext.registerReceiver(installStatusReceiver, intentFilter);
            }
    
            //注册广播接收者,监听下载状态
            mContext.registerReceiver(downloadStatusReceiver,
                    new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        }
    
        //广播监听下载的各个状态
        private BroadcastReceiver downloadStatusReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                checkStatus();
            }
        };
    
        //广播监听安装的各个状态
        private BroadcastReceiver installStatusReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                /**如果知道包名此处可以判断包名就知道具体是哪个app安装成功*/
                
                //上报安装成功:无论是什么状态,只要是安装完成就上报
                ReportUtils.reportAdEndInstall(mAdEndInstallUrl);
                if (mContext != null && installStatusReceiver != null) {
                    //记得反注册接收器
                    mContext.unregisterReceiver(installStatusReceiver);
                    if (mContext instanceof Activity){
                        ((Activity) mContext).finish();
                    }
                }
    
            }
        };
    
        //检查下载状态
        private void checkStatus() {
            DownloadManager.Query query = new DownloadManager.Query();
            //通过下载的id查找
            query.setFilterById(downloadId);
            Cursor cursor = downloadManager.query(query);
            if (cursor.moveToFirst()) {
                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                switch (status) {
                    //下载暂停
                    case DownloadManager.STATUS_PAUSED:
                        break;
                    //下载延迟
                    case DownloadManager.STATUS_PENDING:
                        break;
                    //正在下载
                    case DownloadManager.STATUS_RUNNING:
                        getDownloadPercent(cursor);
                        break;
                    //下载完成
                    case DownloadManager.STATUS_SUCCESSFUL:
                        //上报下载完成
                        if (isNeedReport) {
                            ReportUtils.reportAdEndDownload(mAdEndDownUrl);
                        }
                        //下载完成安装APK
                        installAPK();
                        cursor.close();
                        if (mContext != null && downloadStatusReceiver != null)
                            mContext.unregisterReceiver(downloadStatusReceiver);
                        break;
                    //下载失败
                    case DownloadManager.STATUS_FAILED:
                        LogUtils.toast(mContext, "下载失败");
                        cursor.close();
                        if (mContext != null && downloadStatusReceiver != null)
                            mContext.unregisterReceiver(downloadStatusReceiver);
                        break;
                }
            }
        }
    
        /*获取下载进度*/
        private int getDownloadPercent(long downloadId){
            DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
            Cursor c =  downloadManager.query(query);
            if(c.moveToFirst()){
                int downloadBytesIdx = c.getColumnIndexOrThrow(
                        DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
                int totalBytesIdx = c.getColumnIndexOrThrow(
                        DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
                long totalBytes = c.getLong(totalBytesIdx);
                long downloadBytes = c.getLong(downloadBytesIdx);
                return (int) (downloadBytes * 100 / totalBytes);
            }
            return 0;
        }
        
        /*获取下载进度*/
        private int getDownloadPercent(Cursor c){
            if(c.moveToFirst()){
                int downloadBytesIdx = c.getColumnIndexOrThrow(
                        DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
                int totalBytesIdx = c.getColumnIndexOrThrow(
                        DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
                long totalBytes = c.getLong(totalBytesIdx);
                long downloadBytes = c.getLong(downloadBytesIdx);
                return (int) (downloadBytes * 100 / totalBytes);
            }
            return 0;
        }
    
        private void installAPK() {
            setPermission(pathstr);
            Intent intent = new Intent(Intent.ACTION_VIEW);
            // 由于没有在Activity环境下启动Activity,设置下面的标签
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //Android 7.0以上要使用FileProvider
            if (Build.VERSION.SDK_INT >= 24) {
                File file = (new File(pathstr));
                //参数1 上下文, 参数2 Provider主机地址 和配置文件中声明保持一致   参数3  共享的文件
                Uri apkUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".hytechad.fileprovider", file);
                //添加这一句表示对目标应用临时授权该Uri所代表的文件
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(new File(Environment.DIRECTORY_DOWNLOADS, name)), "application/vnd.android.package-archive");
            }
            mContext.startActivity(intent);
    
            if (isNeedReport) {
                //上报开始安装
                ReportUtils.reportAdBeginInstall(mAdBeginInstallUrl);
            }
        }
    
        //修改文件权限
        private void setPermission(String absolutePath) {
            String command = "chmod " + "777" + " " + absolutePath;
            Runtime runtime = Runtime.getRuntime();
            try {
                runtime.exec(command);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

     

    展开全文
  • APP全局监听系统Home键

    千次阅读 2016-07-06 11:51:00
    APP全局监听系统Home键通过自定义Application,在Application中有一个registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks a)方法,调用该方法需要重写ActivityLifecycleCallbacks接口的生命周期方法...

    APP全局监听系统Home键

    通过自定义Application,在Application中有一个registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks a)方法,调用该方法需要重写ActivityLifecycleCallbacks接口的生命周期方法(该生命周期方法包含所有的Activity的生命周期),所以在OnActivityResume()和OnActivityPause()方法中监听Home键(注册和反注册系统广播)。


    HomeWatch.java

    封装了Home的系统广播,实现了接口的回调

    public class HomeWatch {
    
        private Context mContext;
        private IntentFilter mFilter;
        private OnHomePressedListener mListener;
        private HomeBroadcastReceiver mRecevier;
    
        public interface OnHomePressedListener {
            void onHomePressed();
    
            void onHomeLongPressed();
        }
    
        public HomeWatch(Context context) {
            mContext = context;
            mRecevier = new HomeBroadcastReceiver();
            mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        }
    
        /**
         * 设置监听
         *
         * @param listener
         */
        public void setOnHomePressedListener(OnHomePressedListener listener) {
            mListener = listener;
        }
    
        /**
         * 开始监听,注册广播
         */
        public void register() {
            if (mRecevier != null) {
                mContext.registerReceiver(mRecevier, mFilter);
            }
        }
    
        /**
         * 停止监听,注销广播
         */
        public void unregister() {
            if (mRecevier != null) {
                mContext.unregisterReceiver(mRecevier);
            }
        }
    
    
        class HomeBroadcastReceiver extends BroadcastReceiver {
    
            final String SYSTEM_DIALOG_REASON_KEY = "reason";
            final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
            final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
    
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                    String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                    if (reason != null) {
                        if (mListener != null) {
                            if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                                // 短按home键
                                mListener.onHomePressed();
                            } else if (reason
                                    .equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                                // 长按home键
                                mListener.onHomeLongPressed();
                            }
                        }
                    }
                }
            }
        }
    }
    

    APP.java

    为避免在APP中重写过多的方法,通过一个类实现Application.ActivityLifecycleCallbacks接口

    public class APP extends Application {
        private HomeWatch mHomeWatcher;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            regisiterActivityLifecycle();
        }
    
        private void regisiterActivityLifecycle() {
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallBack() {
    
                @Override
                public void onActivityResumed(final Activity activity) {
                    super.onActivityResumed(activity);
                    mHomeWatcher = new HomeWatch(activity);
                    mHomeWatcher.setOnHomePressedListener(new HomeWatch.OnHomePressedListener() {
                        @Override
                        public void onHomePressed() {
                           //在此处实现具体逻辑
                        }
    
                        @Override
                        public void onHomeLongPressed() {
                            //在此处实现具体逻辑
                        }
                    });
                    mHomeWatcher.register();
                }
    
                @Override
                public void onActivityPaused(Activity activity) {
                    super.onActivityPaused(activity);
                    mHomeWatcher.setOnHomePressedListener(null);
                    mHomeWatcher.unregister();
                }
    
            });
        }
    }
    

    ActivityLifecycleCallBack.java

    自定义了一个类实现Application.ActivityLifecycleCallbacks的接口

    public class ActivityLifecycleCallBack implements Application.ActivityLifecycleCallbacks {
    
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    
            }
    
            @Override
            public void onActivityStarted(Activity activity) {
    
            }
    
            @Override
            public void onActivityResumed(Activity activity) {
    
            }
    
            @Override
            public void onActivityPaused(Activity activity) {
    
            }
    
            @Override
            public void onActivityStopped(Activity activity) {
    
            }
    
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    
            }
    
            @Override
            public void onActivityDestroyed(Activity activity) {
    
            }
        }

    在AndroidManifest.xml中

     <application
            android:name=".APP"
            ...>
    展开全文
  • 教你如何动态调试 iOS App(编译App)

    千次阅读 2018-04-18 11:41:31
    开篇通过本文你能了解 iOS 逆向的基本知识,对 iOS App 的安全有一定了解。然后能举一反三,在自家 App 找到危险漏洞加以预防,保证用户数据安全。在安全领域,攻与防永远存在。哪怕是 iPhone 有着强大的安全防护...


    开篇


    通过本文你能了解 iOS 逆向的基本知识,对 iOS App 的安全有一定了解。然后能举一反三,在自家 App 找到危险漏洞加以预防,保证用户数据安全。

    在安全领域,攻与防永远存在。哪怕是 iPhone 有着强大的安全防护机制,也挡不住那些极客们一次又一次的好奇,开发了很多强大且便利的工具。本文就是在这些极客们提供的工具的基础上完成的!

    准备工具


    HTTP(S) 抓包


    HTTP 抓包

    第一步:获取 MAC IP

    按下Option键,同时点击 Mac 菜单栏上的无线网 Icon,能看到当前电脑的 IP 地址。 或在终端输入 ifconfig en0 也可查看。

    第二步:设置代理

    保证手机和电脑在同一 WIFI 下,在手机上,点击“设置->无线局域网->连接的WiFi”,设置HTTP代理:

    服务器:为 Mac 电脑 IP 地址(如192.168.1.122)

    端口:8888

    第三步:抓包

    在电脑端,打开 Charles。使手机发生网络请求,Charles 会弹出一个询问的对话框

    点击“Allow”允许,Charles 会出现手机的 HTTP 请求记录列表。

    HTTPS 抓包

    第一步: 获取证书安装地址

    安装 SSL 证书到手机设备。点击 Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device

    出现弹窗得到地址 chls.pro/ssl

    第二步:iPhone 安装证书

    在手机 Safari 浏览器输入地址 chls.pro/ssl,出现证书安装页面,点击安装,手机设置有密码的输入密码进行安装

    第三步:配置代理 host

    Charles 设置 Proxy。选择 Proxy -> SSL Proxying Settings...

    勾选 Enable SSL Proxying,点击 Add

    Host 设置要抓取的 HTTPS 接口,Port 填写 443。

    让手机重新发送 HTTPS 请求,可看到抓包。

    注意:不抓包请关闭手机 HTTP 代理,否则断开与电脑连接后会连不上网! 

    拿到 .h 头文件

    从 AppStore 直接下载的 ipa, 苹果公司对其做了 FairPlay DRM 技术进行加密保护,无法直接使用 class-dump 工具获取头文件。但是如果是通过 development 打包出来的话的 App 的话,是可以直接使用 class-dump 查看所有头文件的,此部分介绍就是通过此情况来说明如何获取 .h 文件的。

    此处不再介绍 class-dump 工具的安装过程,具体步骤请直接百度。

    进入到 appName.ipa 所在目录,修改扩展名为 .zip,然后解压文件,得到 appName.app。

    然后执行:

    class-dump -H appName.app -o ./headers/

    命令执行完成后,会在当前目录下的 headers 目录里看到 app 所有头文件。

    如果添加参数 -A -S 会在头文件里标记处类方法和属性的 IMP 地址(模块偏移前基地址)。

    class-dump -H -A -S appName.app -o ./headers/

    SSH 访问手机文件目录


    在你的越狱手机上使用 Cydia 应用市场安装 OpenSSH,并保证 Mac 和 iPhone 处于同一个WIFI下,在 MAC 终端输入:

    ssh root@IP ,IP 替换为 iPhone 的 IP 地址

    输入默认密码:alpine

    即可进入 iPhone 终端。

    使用 Clutch 反编译 App


    第一步:重新签名 debugserver

    取得 debugserver 有两种方式。

    第一种是在 Mac 电脑中拿到

    进入路径 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/8.3/DeveloperDiskImage.dmg(其中路径里 8.3,代表 iOS 系统版本,需与准备的越狱手机系统版本保持一致)。双击 DeveloperDiskImage.dmg,将目录里的 usr/bin/debugserver 复制到指定文件夹中。

    第二种是在越狱手机里拿到

    如果手机连接过手机并通过 XCode 调试过 app,会在手机里的 /Developer/usr/bin/ 目录下生成一个 debugserver 文件。通过 iFunbox 导出至 Mac 桌面。或使用 scp 命令 cpoy 出来。

    重签名 debugserver

    即给 debugserver 添加 task_for_pid 权限

    创建 entitlements.plist,添加如下四个 key:

    key 对应的 value 都设为设为 ture

    将 entitlements.plist 和 debugserver 放在同一个目录下,执行以下命令:

    codesign -s - --entitlements entitlements.plist -f debugserver

    此命令会重新签名 debugserver,将签名后的 debugserver 拷贝至手机系统的 /usr/bin/ 目录下。

    注意:不要将 debugserver 拷贝至 /Developer/usr/bin/ 路径下

    第二步: 通过 Clutch 拿到反编译后的 App 可执行文件

    将下载好的 Clutch 放入手机的 /usr/bin/ 路径下。然后,给 Clutch 赋予权限,通过 SSH 登录到手机,进入 /usr/bin/ 执行 chmod a+x ./Clutch

    通过命令 Clutch -i,列出所有的可被 Clutch 的应用。

    对指定序号的应用进行脱壳,如企业微信,序号是1,命令是 Clutch -d 1。执行完成后,会得到脱壳后的 ipa。

    第三步:使用 class-dump 拿到 .h 头文件

    使用上文 【拿到.h头文件】 介绍的方法拿到脱壳后的 App 头文件和并记下要打断点的方法的 IMP 地址。

    动态调试 App

    本文动态调试用到的调试器是 lldb。

    第一步:使 iPhone 进入等待挂载状态

    SSH 登录到手机,执行 ps -e 命令得到 App PID 或项目名称。

    进入 /usr/bin/ 执行 ./debugserver IP:port -a PID|appProjectName。 其中第一个参数 IP 可以替换为 Mac 电脑 IP地址,或者使用 * 通配符,允许所有 IP 调试;第二个参数 port 随便写一个就行。第四个参数 可以指定要调试 App 的 PID 或项目名称。比如要调试的 PID 为 6019 的搜狗输入法项目名称为SogouInput,则命令即为:

    ./debugserver *:1234 -a 6019 或 ./debugserver *:1234 -a ‘SogouInput’

    此命令执行完成后,app会进入等到挂载状态,app会被卡住点击无反应。正常现象!

    如果此命令报错,如出现 Segmentation fault: 11 等情况,说明 App 做了反动态调试保护。遇到此种情况,需先确定 App 采用了哪种保护方案,然后进一步找到对应措施,干掉它的反动态调试保护。

    第二步:监听进程,进入挂载状态

    重新打开一个 Mac 终端执行 lldb 进入 lldb 调试状态。然后输入

    process connect connect://iPhoneIP:port

    iPhoneIP 替换为 iPhone 的 IP 地址;port 改为刚才指定的端口,即 1234。

    待命令执行完成后,App 即进入挂载状态。

    第三步:获取 App 的 ASLR 偏移量

    ASLR偏移量其实就是虚拟内存的地址相对于模块基地址的偏移量。有两个概念需要熟悉一下:

    • 模块在内存中的起始地址 ---- 模块基地址
    • ASLR偏移 ---- 虚拟内存起始地址与模块基地址的偏移量

    在 lldb 调试器模式下,执行 imge list -o -f

    模块偏移后的基地址 = ASLR 偏移量 + 模块偏移前基地址(方法的 IMP 地址)

    上面这个公式是尤为重要的,因为 Class-dump 中显示的都是“模块偏移前基地址”,而 lldb 要操作的都是“模块偏移后的基地址”。所以从 Class-dump 到 lldb 要做一个地址偏移量的转换。

    至此,已得到了 App 的 ASLR 偏移量和方法的 IMP 地址。

    第四步:打断点,调试

    在 lldb 模式下执行,br s -a 'ASLR 偏移量+ IMP',然后执行 c,使 App 跑起来,触发一个方法调用,就会进入断点模式。输入 po $arg1 打印第一个参数。

    然后,配合着抓包工具 Charles(比如分析网络请求加密逻辑) 和 Class-dump(比如修改某个类的方法返回值)等工具,你就可以随意动态调试 App 了,就像在 XCode 里调试一样!

    br 命令说明

    br dis 1 -- 禁用(disable)编号为1的断点

    br en 1 -- 启用(enable)编号为1的断点

    br dis -- 禁用所有断点

    br en -- 启用所有断点

    br del 1 -- 删除(delete)编号为1的断点

    br del -- 删除所有断点

    br list -- 列出所有断点

    使用 dumpdecrypted 破壳 App


    dumpdecrypted 脱壳工具的原理是:将应用程序运行起来(iOS 系统会先解密程序再启动),然后将内存中的解密结果 dump 写入文件中,得到一个新的可执行程序。

    第一步:生成 .dylib 文件

    在终端进入到下载后的目录中,cd dumpdecrypted-master,然后执行 make,即可生成 dumpdecrypted.dylib

    第二步:找到 App 的 Documents 文件夹路径

    通过 SSH 登录到 iPhone,然后执行 ps -e 查看进程,获取要破壳的进程 PID。然后执行 cycript -p PID 附加到 PID 进程上。最后执行 [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]得到 Documents 文件夹路径。

    第三步:开始破壳

    将第一步生成的 dumpdecrypted.dylib 拷贝到第二步得到的 .../Documents/ 路径下,命令如下:scp ~/dumpdecrypted.dylib root@IP:/var/mobile/Containers/Data/Application/2B4C6281-C015-4FF3-A8EC-5E5C7554D447/Documents(将路径里的 UDID 替换为你的要破壳的 App 的 UDID)

    进入 Documents 目录下,执行DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/ Application/BFED82A3-3238-4F41-B797-C1CB584CBE05/appProjectName.app/appProjectName(将路径里的 UDID 替换为你的要破壳的 App 的 UDID;将 appProjectName 替换为要破壳 App 的项目名称)

    待命令执行完,会在当前目录生成一个名为 appProject.decrypted 的文件,这个就是破壳后的 App 可执行文件,要的就是它!使用 Class-dump 即可得到头文件。或使用 Hopper 或 IDA Pro 进行反编译。

    给你的 App 添加反动态调试机制


    ptrace

    为了方便应用软件的开发和调试,从Unix的早期版本开始就提供了一种对运行中的进程进行跟踪和控制的手段,那就是系统调用 ptrace()。 通过 ptrace 可以对另一个进程实现调试跟踪,同时 ptrace 还提供了一个非常有用的参数那就是 PTDENYATTACH,这个参数用来告诉系统,阻止调试器依附。

    所以最常用的反调试方案就是通过调用ptrace来实现反调试。

    sysctl

    当一个进程被调试的时候,该进程会有一个标记来标记自己正在被调试,所以可以通过 sysctl 去查看当前进程的信息,看有没有这个标记位即可检查当前调试状态。

    检测到调试器就退出,或者制造崩溃,或者隐藏工程,当然也可以定时去查看有没有这个标记。

    syscall

    为从实现从用户态切换到内核态,系统提供了一个系统调用函数 syscall,上面讲到的 ptrace 也是通过系统调用去实现的。

    在Kernel Syscalls27这里可以找到 ptrace 对应的编号。

    26. ptrace 801e812c T

    所以如下的调用等同于调用 ptrace:

    syscall(26,31,0,0,0);

    arm 

    syscall 是通过软中断来实现从用户态到内核态,也可以通过汇编 svc 调用来实现。

    觉得不错的话,欢迎关注我的公众号哦!

    展开全文
  • 使用Fiddler监听手机App访问的API

    千次阅读 2013-12-05 20:41:24
    在开发App的时候有时候需要看看类似的App是怎样开发的,这个时候去看看别人的app的数据接口是怎样的,都有些什么字段,可以帮助我们开发。 推荐使用Fiddler工具。 1.在Fiddler工具上找到Tools,点击Fiddler Options...

    在开发App的时候有时候需要看看类似的App是怎样开发的,这个时候去看看别人的app的数据接口是怎样的,都有些什么字段,可以帮助我们开发。

    推荐使用Fiddler工具。

    1.在Fiddler工具上找到Tools,点击Fiddler Options选择Connections,修改一下Fiddler listens on port,比如填写8765

    2.安装Connectify,手机通过Connectify虚拟出来的wifi连接到电脑上。设置手机的wifi选项,显示高级选项,代理设置选择手动,代理的hostname填写主机的,将鼠标移动到Connectify在桌面右下角的图标,即可显示出来,比如我的:192.168.238.1,在手机上填写上这个,端口号填写刚才在Fiddler中的那个,8765.

    这个时候,在手机上做一些访问网络的操作,比如打开某些App访问网络,就可以拦截到当前请求的url了,header,请求参数,返回字段都有。在Fiddler的左侧都有显示,点击左侧的list,在右侧的Inspectors中查看,Inspectors中上部分是request请求信息,下面的部分是response响应信息。

    展开全文
  • App统一监听网络状态切换

    千次阅读 2014-08-21 17:40:09
    App开发中, 我们常常遇到网络不稳定的情况, 这时候要及时做一些事情, 防止App的崩溃.我们往往使用BroadCastReceiver来实现这个功能, 但是他有个问题, 用到网络监听的地方都需要注册一个, 造成了资源的浪费,于是. ...
  • APP加固各种调试

    千次阅读 2018-08-23 10:33:03
    原文地址:... ... 0x00 时间相关调试 通过计算某部分代码的执行时间差来判断是否被调试,在Linux内核下可以通过time、gettimeofday,或者直接通过sys call来获取当前时间。另外,...
  • APP逆向5*burp高级用法透明代理抓包(不用设置代理,不用安装证书) 工具:burp 前言:最近项目太多,空余时间不是很多,像前面文章过于基础,后面我会抽空补上。 概述:既然要对抗抓包手段先说下常见的抓包手段...
  • 配置文件 配置文件是一个命名为config.json的文件,配置应用的一些信息 { "app": { "bundleName": "com.example.helloworld", "vendor": "example", "version": { "code": 1, "name": "1.0" }, "apiVersion": { ...
  • Charles进行App抓包

    千次阅读 2019-10-06 20:02:49
    Charles是一个网络抓包工具,我们可以用它来做App的抓包分析,得到App运行过程中发生的所有网络请求和响应内容,这就和Web端浏览器的开发者工具Network部分看到的结果一致。 相比Fiddler来说,Charles的功能更强大...
  • Android scheme呼起App

    2021-05-26 11:17:01
    可以跳向钓鱼页面(确实是在App里打开的页面,但它是第三方做的假的) …其它风险 一般自定义scheme都是不公开的,但难免会泄漏出去(编译App等方式),scheme接口本身要做好防范,接收intent时可以这样做: // ...
  • 在 api 28之前, 使用 android.app.Application.ActivityLifecycleCallbacks 监听 Activity 的生命周期。它始于 api 14(android 4.0)。从它的包名可以看出,它是 Application 级的监听接口。需要在 Application 中...
  • Xposed的大名相信很多同学都不陌生,它提供了一种能力,可以在不修改原apk的情况下,以插件的方式改变目标App的某些行为。 但随着Android系统版本的迭代,原来的Xposed已经不适合在高版本的系统上运行了,原Xposed...
  • Java 监听器,国际化

    2021-03-13 17:54:22
    1.监听器1.1概述监听器: 主要是用来监听特定对象的创建或销毁、属性的变化的!是一个实现特定接口的普通java类!对象:自己创建自己用 (不用监听)别人创建自己用 (需要监听)Servlet中哪些对象需要监听?request / ...
  • 时间 2015-03-03 08:00:00 张明云的博客...当我在使用音乐播放器和各种小说APP的过程中,感觉非常不好的一个体验就是你需要通过手动点击全盘检索后,新下载的数据、从磁盘拷贝的数据才会更新显示在列表上,这对于我们
  • 前言项目中用到了BroadcastReceiver监听网络状态的改变用以控制下载任务的暂停或继续,原来是在AndroidManifest中注册了一个Receiver,然后在Receiver中通过逻辑判断执行不同操作,本来是没有问题的,但这两天在看...
  • runApp(new MaterialApp( routes: { '/':(_) => new WebviewScaffold( url: "http://www.baidu.com/", appBar: new AppBar( title: new Text("webview"), ), ), }, )); } 运行效果如下: 这里还...
  • python 手机app数据爬取

    2020-12-04 00:39:24
    @一:爬取主要流程简述1.APP的爬取比Web爬取更加容易,爬虫没有那么强,且大部分数据是以JSON形式传输的,解析简单。2.在APP中想要查看请求与响应(类似浏览器的开发者工具监听到的各个网络请求和响应),就需要借助...
  • iOS之深入解析App的架构设计

    千次阅读 2021-07-20 15:46:34
    App 架构是软件设计的一个分支,它关心的是如何设计一个 App 的结构。具体来说,它关注于两个方面:如何将 App 分解为不同的接口和概念层次部件,以及这些部件之间和自身的不同操作中 所使用的控制流和数据流路径。 ...
  • AntiDebugandroid apk调试工具,hook、xposed、virtual xposed、substrate该项目主要实现android app反第三方调试功能,主要功能用c++实现,因为考虑到用java实现会被xposed等功能拦截,导致调试功能...
  • show 控制元素的显示、隐藏v-if 条件判断v-for 遍历数组、对象v-bind、v-model 数据绑定v-on 事件绑定过滤器组件内过滤器 只能在对应组件中使用全局过滤器 全局可用数据监听watch 监听单个变量值的变化watch...
  • 微信小程序编译整理,wxss不成功

    千次阅读 2020-08-17 16:19:01
    微信小程序编译搞了一下午,终于搞成,简单做个整理。 网上大部分资料可参考。 1.安装好node (大部分人应该早装了)。 2.网上大部分推荐的 夜神模拟器 。 3.可以电脑上 下载个 RE资源管理器安装包 ,微信app安装包...
  • android 应用内页面,截屏监听

    千次阅读 2016-05-20 19:03:10
    公司的项目由于安全需要,对某一特定的页面需要监听是否被用户截屏了。 简单搜了一下,很少有这方面的问题,没办法,只能自己折腾了。 目前想到两种思路: 1、监听广播 当然,前提是系统在截屏的时候发送某一广播...
  • 工程师必备APP抓包技能

    千次阅读 多人点赞 2020-11-30 20:22:22
    奇技 · 指南一台上网电脑就能完成 APP 抓包分析一条龙服务。这是一篇 APP 抓包分析总结性文章,采用 APP 模拟器与 Web 调试代理工具组合玩法。从此 APP 抓包分析能力变得...
  • 有的时候我们的项目需要监听手机亮屏灭屏锁屏等状态,来做一些自己的事,比如解锁后要求用户输入app密码等。 由于屏幕状态变化时,系统会发出对应的广播,这时候我们可以定义一个监听器来接收广播,然后做一些对应...
  • Java Web中过滤器和监听器重点总结

    千次阅读 2019-01-29 23:42:14
    2. 活化就是通过序列化将session对象从存储设备上进行恢复 3. 可能用到钝化与活化的情况 服务器资源不足 重启服务器 Web应用被重新加载 4. session作用域中的变量只有实现了java.io. Serializable...
  • h5+App移动端返回

    千次阅读 2020-03-16 10:27:24
    // 移动端返回键监听 window.history.pushState(null, null, "#"); this.onPlusReady(() => { window.plus.key.addEventListener( "backbutton", () => { let hashArr = ['#/...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,926
精华内容 8,370
关键字:

反监听app