手机管家wifi管理ARP模块分析

分析记录


框架分析

APR模块的使用方式(API)接口

//创建服务
public void onCreate(PluginContext pluginContext) {
    AntiMITMServer.getInstance().startServerIfNeed();
}
//服务的回调接口
public interface IMITMListener {
    public void onScaned(boolean withRoot, boolean isDanger);
}
public static class MITMPluginCallback implements IMITMListener {

    PluginCallback mPluginCallback;
    
    public MITMPluginCallback(PluginCallback piCallback) {
        mPluginCallback = piCallback;
    }
    

    public void onScaned(boolean withRoot, boolean isDanger) {
        Message msg = Message.obtain();
        Bundle data = new Bundle();
        data.putInt(SessionManagerConst.ArgKey.KEY_SCAN_RESULT, isDanger ? SessionManagerConst.SCAN_RESULT.NOT_PASS : SessionManagerConst.SCAN_RESULT.SAFE);
        msg.setData(data);
        mPluginCallback.handleMessage(msg);
    }
}
//注册回调接口并扫描
public int handleMyForeCallback(int callbackAction, final PluginCallback callback) {
    Bundle inBundle = callback.getBundle();
    switch(inBundle.getInt(PluginConst.Key.TODO)) {
    case PluginConst.Callback.CALLBACK_FOR_MITM_DETECT:
        if (callbackAction == CallbackAction.ADD_CALLBACK) {
            AntiMITMServer server = AntiMITMServer.getInstance();
            server.registerListener(new MITMPluginCallback(callback));
            server.checkArp();
        } else if (callbackAction == CallbackAction.REMOVE_CALLBACK) {
            AntiMITMServer server = AntiMITMServer.getInstance();
            server.unregisterListener();
        }
        break;
}
//销毁
public void onDestroy() {
    AntiMITMServer.getInstance().stopServer();
}

内部实现方式

static final String SOCKET_SERVER = "socket_server_path";
public void startServerIfNeed() {
    //检查root,如果有root继续
    //创建一个socket服务,等待native进程连接
    mServer = new LocalServerSocket(SOCKET_SERVER);
    while (!mIsStop) {
    LocalSocket receiver = mServer.accept();
    //Closing the connection at the end of the message
    InputStream input = receiver.getInputStream();
    //读取native进程通过socket发过来的消息
    static final String TIME_OUT_AUTO_EXIT = "auto exit...";
    static final String ARP_PACKET_COMING = "arp packet coming...";
    static final String FOUND_DANGER = "found danger";
    if (!ARP_PACKET_COMING.equals(rececivedMsg)) {
        QDebugToast.ShowShortToast(mContext, "" + rececivedMsg);
        
        if (FOUND_DANGER.equals(rececivedMsg)) {
            mStatus = SessionManagerConst.SCAN_RESULT.NOT_PASS;
        } else if (TIME_OUT_AUTO_EXIT.equals(rececivedMsg)) {
            mStatus = SessionManagerConst.SCAN_RESULT.SAFE;
        }
        if (mListener != null) {
            mListener.onScaned(true, mStatus == SessionManagerConst.SCAN_RESULT.NOT_PASS);
        }
        // break;
    }
}
public static final int DETECT_TIME_IN_SECONDS = 5;
public void checkArp() {
    //起一个新的线程
    //判断wifi是否打开
    startServerIfNeed();
    if (binaryFile.exists()) {
        List<String> cmds = new ArrayList<String>();
        cmds.add("chmod 0755 " + binaryPath + "\n");
        cmds.add(binaryPath + " " + DETECT_TIME_IN_SECONDS);
        String ret = rs.runScript(-1, cmds);
        FLog.vk(TAG, "runScript ret:"+ret);
    }
}

补充一些关于sockets进程间通信的一些知识

APUE 17.3. UNIX Domain Sockets

使用socket一般会创建文件代表socket的路径,linux支持abstract socket,通过这种方式可以避免创建物理文件。这种中abstract的socket可以通过lsof查看, 其特点是文件名前有@。 嗅探或者调试方法,可以通过示例里的一些手段来嗅探或者工具来查看socket的情况.

代码示例

socket通信的读写可以使用read write也可以使用recv send后者更专业一些

对于client bind不是必须的

socket连接示例

wikipedia

wikipedia示例

#include &lt;stddef.h&gt;
//#define offsetof(TYPE, MEMBER) ((int)&((TYPE *)0)->MEMBER)
#include &lt;sys/socket.h&gt;
#include &lt;sys/un.h&gt;
//struct sockaddr_un {
//  sa_family_t sun_family;      /* AF_UNIX */
//  char        sun_path[108];   /* pathname */
//};
int
main(void)
{
    int fd, size;
    struct sockaddr_un un;
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path, "foo.socket");
    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        err_sys("socket failed");
    size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
    if (bind(fd, (struct sockaddr *)&un, size) < 0)
        err_sys("bind failed");
    printf("UNIX domain socket bound\n");
    exit(0);
}

Copyright © FengGuangtu 2017