diff --git a/private/asiaircrack/asi-system.md b/private/asiaircrack/asi-system.md new file mode 100644 index 0000000..124bc68 --- /dev/null +++ b/private/asiaircrack/asi-system.md @@ -0,0 +1,245 @@ +--- +title: ASIAIR 系统分析 +description: +published: true +date: 2021-09-06T17:10:18.728Z +tags: +editor: markdown +dateCreated: 2021-09-06T17:10:18.728Z +--- + +# 系统分析 +## 抓包分析 +根据tcpdump抓包的结果分析其报文应该是jsonrpc over tcp,因为我们可以使用java(任何你熟悉的语言)基于raw socket写一个最简单的demo。 +```java +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 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协议模拟发送报文,此时可以看到控制台已经打印出期望的报文。 +```json +{ + "jsonrpc" : "2.0", + "method" : "get_connected_cameras", + "result" : [ ], + "code" : 0, + "id" : "0" +} +``` +接下来笔者会实战拍摄一个深空天体,同时将全流程进行抓包,分析其相关API,同时结合INDI协议,判断ASIAIR是否只是INDI的一个代理,后续会专门写一篇分析API的文章。