wikijs/private/asiaircrack/asi-system.md

6.3 KiB
Raw Blame History

title description published date tags editor dateCreated
ASIAIR 系统分析 true 2021-09-06T17:10:20.263Z markdown 2021-09-06T17:10:18.728Z

系统分析

抓包分析

根据tcpdump抓包的结果分析其报文应该是jsonrpc over tcp因为我们可以使用java任何你熟悉的语言基于raw socket写一个最简单的demo。

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class test {
    public static void main( String[] args ) throws Throwable {


        final Socket socket = new Socket( "192.168.1.116", 4700 );
        final InputStream inputStream = socket.getInputStream();
        final OutputStream outputStream = socket.getOutputStream();
        final ObjectMapper mapper = new ObjectMapper();

        new Thread( new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        JsonNode o = mapper.readValue( new NoCloseInputStream( inputStream ), JsonNode.class );
                        System.out.println( o.toPrettyString() );
                    } catch (IOException e) {
                        try {
                            socket.connect( new InetSocketAddress( "192.168.1.116", 4700 ) );
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        } ).start();

        while (true) {
            Map <String, String> val = new HashMap <>();
            val.put( "id", "0" );
//            val.put( "method", "get_current_img" );
            val.put( "method", "get_connected_cameras" );

            try {
                 String s = mapper.writeValueAsString( val );
                s += "\r\n";
                outputStream.write( s.getBytes( StandardCharsets.UTF_8 ) );
                outputStream.flush();
            } catch (IOException e) {
                try {
                    socket.connect( new InetSocketAddress( "192.168.1.116", 4700 ) );
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            TimeUnit.SECONDS.sleep( 10 );

        }


    }


    @SuppressWarnings({"WeakerAccess", "unused"})
    static class NoCloseInputStream extends InputStream {

        private final InputStream input;
        private boolean closeAttempted = false;

        public NoCloseInputStream( InputStream input ) {
            this.input = input;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int read() throws IOException {
            return this.input.read();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int read( byte[] b ) throws IOException {
            return this.input.read( b );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int read( byte[] b, int off, int len ) throws IOException {
            return this.input.read( b, off, len );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public long skip( long n ) throws IOException {
            return this.input.skip( n );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int available() throws IOException {
            return this.input.available();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void close() throws IOException {
            closeAttempted = true;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public synchronized void mark( int readLimit ) {
            this.input.mark( readLimit );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public synchronized void reset() throws IOException {
            this.input.reset();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean markSupported() {
            return this.input.markSupported();
        }

        /**
         * @return the closeAttempted
         */
        public boolean wasCloseAttempted() {
            return closeAttempted;
        }

    }

    @SuppressWarnings({"WeakerAccess", "unused"})
    static class NoCloseOutputStream extends OutputStream {

        private final OutputStream ops;
        private boolean closeAttempted = false;

        public NoCloseOutputStream( OutputStream ops ) {
            this.ops = ops;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void write( int b ) throws IOException {
            this.ops.write( b );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void write( byte[] b ) throws IOException {
            this.ops.write( b );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void write( byte[] b, int off, int len ) throws IOException {
            this.ops.write( b, off, len );
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void flush() throws IOException {
            this.ops.flush();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void close() throws IOException {
            closeAttempted = true;
        }

        /**
         * @return the closeAttempted
         */
        public boolean wasCloseAttempted() {
            return closeAttempted;
        }

    }


}

首先向ASIAIR 4700端口创建tcp连接然后基于jsonrpc协议模拟发送报文此时可以看到控制台已经打印出期望的报文。

{
  "jsonrpc" : "2.0",
  "method" : "get_connected_cameras",
  "result" : [ ],
  "code" : 0,
  "id" : "0"
}

接下来笔者会实战拍摄一个深空天体同时将全流程进行抓包分析其相关API同时结合INDI协议判断ASIAIR是否只是INDI的一个代理后续会专门写一篇分析API的文章。