O acelerômetro - também conhecido como sensor G - é hoje um dos sensores mais comuns. Você pode encontrá-lo em quase todos os gadgets modernos. O acelerômetro executa uma tarefa bastante simples - mede a aceleração do dispositivo. Vamos ver como ele faz isso - vamos analisar os mecanismos dos sensores da API do Android usando o exemplo da tarefa n ° 7 do estágio online do NeoQUEST-2019.
Segundo a lenda, recebemos 2 arquivos:
7.apk e
7.txt . As seguintes conclusões podem ser tiradas do texto da tarefa (e todas as tarefas ainda estão disponíveis
aqui ):
7.apk - um programa de
criptografia que de alguma forma usa as configurações do acelerômetro do dispositivo;
7.txt - criptograma gerado pelo codificador. O seguinte está escrito nele:
[1749054104147639] [2.07154922] [10.001905] [4.5387093] [1749056073889025] [5.7193284] [8.221763] [0.01391537] [1749058029180773] [4.684068] [12,05614] [0,0377285] [1749060105291613] [4,6900544] [6,9307165] [4,7094293] [1749062123327502 ] [4.4682417] [7.512769] [6.037215] [1749067640096818] [1.0396843] [8.798672] [4.9335976] [1749070016073380] [2.3173676] [10.180047] [4.948362] [1749072343679582] [126060] 2.48394698] [10.834006] [6.306282] [1749075827770391] [0.2795044] [13.279829] [0.19391555]Vemos que o texto é um grupo repetitivo de 4 valores, um dos quais é inteiro e os 3 restantes são números de ponto flutuante. Por conveniência, colocamos em linhas separadas:
[1749054104147639] [- 2.07154922] [10.001905] [4.5387093]
[1749056073889025] [5,7193284] [8,221763] [0,01391537]
[1749058029180773] [- 4,684068] [12,05614] [0,0377285]
[1749060105291613] [4,6900544] [6,9307165] [- 4,7094293]
[1749062123327502] [4,4682417] [7,512769] [6,037215]
[1749067640096818] [1,0396843] [8,798672] [- 4,9335976]
[1749070016073380] [- 2.3173676] [10.180047] [4.948362]
[1749072343679582] [- 4,3660607] [12,218135] [0,5312999]
[1749073674459611] [- 2,48394698] [10,834006] [- 6,306282]
[1749075827770391] [0,2795044] [13,279829] [- 0,19391555]O formato do criptograma foi resolvido, mas o que esses valores são não é conhecido. Alguns parâmetros do acelerômetro do dispositivo, sem detalhes específicos. E vamos ao site de desenvolvedores do Android e
ver o que o acelerômetro pode mostrar em geral.
Vemos a seguinte descrição:
Nós descobrimos pelo que os parâmetros de ponto flutuante são responsáveis - essa é a aceleração do dispositivo ao longo dos eixos X, Y e Z. Mas como entender por qual eixo cada um deles é responsável? É hora de iniciar o aplicativo. É assim:
Existem 2 opções para determinar o comportamento do aplicativo: descompilar
.apk e analisar os valores resultantes. A seguir, consideramos o segundo método e fornecemos a inserção do código descompilado responsável pelas ações do aplicativo.
O criptograma contém valores positivos e negativos (sabemos que são acelerações em diferentes eixos), para que possamos assumir: se os vetores de inclinação do dispositivo ao longo do eixo forem opostos, os valores de aceleração serão aproximadamente iguais em valor absoluto, e a diferença estará apenas em sinal.
A seguir, é apresentada uma lista de códigos para armazenar informações de aceleração:
public class MotionSnapshot { public final float angle_alpha; public final float angle_beta; public final float angle_gamma; public final long event_time; ... }
Com base nessas considerações, enfrentamos as seguintes tarefas:
- Determinar qual valor no criptograma corresponde à inclinação do dispositivo
- Definir padrão de desvio
- Para cada dígito para associar um padrão de desvio para descriptografia
As 2 primeiras tarefas serão realizadas em paralelo. No telefone, podemos testar 2 tipos de inclinação:
- De mim / para mim
- Esquerda / direita
O código responsável por manipular eventos do acelerômetro public class SensorListener implements SensorEventListener { private MotionTrace Trace; public SensorListener(MotionTrace trace, MainActivity activity) { Trace = trace; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override public void onSensorChanged(SensorEvent event) { Trace.addSnaphot(new MotionSnapshot(event.values, event.timestamp)); } }
O código responsável por gerar a inclinação do dispositivo com o clique de um botão public class MotionTrace { private ArrayList<MotionSnapshot> Deltas; private long Length; private MotionSnapshot LastSnapshot; public MotionTrace(long len) { LastSnapshot = new MotionSnapshot(0,0,0,0); Deltas = new ArrayList<>(); Length = len; } public void addSnaphot(MotionSnapshot snapshot) { if (Deltas.size() >= Length) { Deltas.remove(0); } MotionSnapshot delta = new MotionSnapshot(0,0,0,0); if (Deltas.size() > 0) { delta = snapshot; } Deltas.add(delta); } public ArrayList<MotionSnapshot> getDeltas() { return new ArrayList<>(Deltas); } }
O código responsável pela geração do criptograma public void SaveCiphertext() { Log.d(Config.MAIN_TAG, "SAVING - {{" + Ciphertext + "}}"); try { File root = new File(Environment.getExternalStorageDirectory(), Config.DIRNAME); if (!root.exists()) { Log.d(Config.MAIN_TAG, "Creating directory - [" + root + "]"); if (!root.mkdirs()) { Log.d(Config.MAIN_TAG, "Error creating directory"); } } File out_file = new File(root, Config.FILENAME); Log.d(Config.MAIN_TAG, "Out - [" + out_file + "]"); PrintWriter writer = new PrintWriter(out_file, "UTF-8"); writer.println(Ciphertext); writer.close(); Toast.makeText(this, "Saved to - [" + out_file + "]", Toast.LENGTH_LONG).show(); } catch (IOException ex) { Toast.makeText(this, "Error saving data", Toast.LENGTH_SHORT).show(); } Ciphertext = ""; }
Vamos começar em ordem. Para testar as inclinações do primeiro tipo, selecionamos os números 2 e 8. Clique em cada 3 vezes com um esforço crescente. Temos o seguinte resultado:
[2687418463227102] [- 0,22300714] [10,764615] [- 0,9759079]
[2687419411042043] [- 3,5834892] [13,591138] [- 1,7036858]
[2687420383026907] [- 5,575793] [13,533228] [- 1,3104248]
[2687421461360546] [0,6850295] [6.0002656] [0,5568123]
[2687422317256542] [4.1720495] [1.8675026] [1.545407]
[2687423250514599] [7,9689393] [- 3,600097] [0,33346742]Bem, as diferenças no parâmetro 2 são visíveis a olho nu. Vamos começar a preencher o modelo.
Representamos o modelo na forma de intervalos de valores dos campos correspondentes na linha de criptograma. Marcamos com um ponto de interrogação o que ainda não sabemos.
[? ]
[(<0) - desvio de si mesmo; (> 0) - auto-rejeição]
[?]
[?]Da mesma forma, realizaremos testes com os botões 4 e 6. Resultados:
[2688019191605386] [1,7270225] [9,541045] [0,0397171]
[2688020247971353] [1,0615791] [9,794326] [4,9135437]
[2688021887957875] [1,0974716] [7,5535636] [7,8307548]
[2688023749896352] [1,3328063] [9,43923] [- 0,27600938]
[2688024849688832] [1.1357567] [9.9313135] [- 2.4410355]
[2688026002520864] [0,30400848] [6,4610033] [- 8,0956335]Atualize o modelo levando em consideração o padrão estudado:
[? ]
[(<0) - desvio de si mesmo; (> 0) - auto-rejeição]
[?]
[(<0) - desvio para a direita; (> 0) - desvio para a esquerda]Obviamente, o terceiro valor é o desvio para cima / para baixo, pois esse é o único vetor restante. E realmente não precisamos verificar, porque para a determinação inequívoca do botão pressionado, já temos o modelo conhecido.
Agora, criaremos um modelo para cada dígito no teclado, com base na posição dos botões e no modelo desenvolvido (* - o parâmetro não nos interessa):
1 - [*] [<0] [*] [> 0]
2 - [*] [<0] [*] [próximo a 0]
3 - [*] [<0] [*] [<0]
4 - [*] [] [*] []
5 - [*] [próximo a 0] [*] [próximo a 0]
6 - [*] [próximo a 0] [*] [<0]
7 - [*] [> 0] [*] [> 0]
8 - [*] [> 0] [*] [próximo a 0]
9 - [*] [> 0] [*] [<0]
0 - [*] [> 0] [*] [próximo a 0]Como pode ser visto na figura, os botões 8 e 0 têm os mesmos parâmetros, portanto, sua descriptografia pode ser ambígua - ao encontrar essa combinação em um criptograma, você deve tentar as duas opções. Agora, aplicamos os modelos obtidos ao criptograma e obtemos 2 respostas: 1029761235 e 1829761235, das quais
1829761235 é
verdadeira . Tarefa concluída!
Muito em breve - em 26 de junho - o NeoQUEST 2019 Face-to-Face Competition acontecerá! Apresse-
se para se
registrar no site do evento. Num futuro próximo, o habrastatya será lançado com o anúncio do programa, não perca!