Quando eles voltarem a esta seção, queremos falar sobre sobrecarga de funções, pois esse é um tópico muito
importante.
Se quiser conectar uma função com liberdade, caso esteja fazendo algo errado, Frida é incrivelmente prestativa e nos fornece
todas as informações de que precisamos para corrigir nosso problema.
Portanto, isso não é um grande problema.
Mas, mesmo assim, vamos tentar entender o que está acontecendo.
Se o Frida estiver imprimindo esses erros de sobrecarga de função.
Muito bem.
Ok, vamos lá.
Então, aqui estamos empacotando nossa vm do Ubuntu e temos esse método de lançamento de dados aqui.
Vimos que, se você não fornecer a quantidade correta de argumentos para a disfunção, o Frida imprimirá
esse erro de sobrecarga.
Mas o que é essa sobrecarga?
Erro?
Sobrecarregar uma função significa simplesmente que estamos tendo a mesma função mais uma vez com o mesmo
nome, mas dessa vez com uma quantidade diferente de argumentos, porque o programa precisa saber qual função deve chamar.
Neste ponto.
Nesse caso, estamos lançando os dados com apenas dois parâmetros.
Portanto, não há outro método de dados rodoviários aqui.
Mas se dermos uma olhada nesse próximo int aleatório, veremos na documentação oficial que
há duas definições para essa função.
Podemos chamar essa função sem ter um parâmetro e podemos chamar essa função com um parâmetro.
E isso é muito importante porque a função em si está se comportando de forma um pouco diferente e, portanto,
está livre para imprimirmos esse erro e nos dizer: "Não sei agora qual função você deseja conectar
e, com certeza, algo dará errado nesse momento".
Portanto, prefiro abortar antes que você receba algum resultado estranho aqui.
E Frida também nos diz, bem, eu tenho essa definição de função para esse e esse tipo.
Então, qual deles você quer fisgar?
Anexe essa sobrecarga de ponto e a quantidade correta de argumentos.
Mas antes que isso se torne muito complicado na parte teórica, vamos simplesmente fazer uma abordagem
prática.
Digamos que queiramos conectar essa função em seguida.
Vamos experimentar e ver quais erros encontramos aqui, e então também saberemos como corrigi-los.
Muito bem.
Está bem.
Então, estou abrindo um novo terminal e fazendo minha conexão ADB.
Portanto, a conexão ADB já está conectada.
Muito bem, então estamos usando o ADB Shell e precisamos de privilégios de root.
Em seguida, vamos para data, local temp, e aqui queremos iniciar nosso servidor Frida.
Este aqui.
Tudo bem.
Frida está executando a primeira etapa.
Feito.
Em seguida, precisamos abrir esse aplicativo.
Onde o temos?
Aqui.
Tudo bem.
Também colocamos isso à direita.
Portanto, em segundo plano como o servidor três e aqui temos nosso aplicativo, podemos ver que ele está funcionando bem.
Sim, não há um gancho no momento.
Tudo bem.
Agora, vamos abrir nossos resultados em seu editor de código e, em seguida, vamos tentar conectar essa função aleatória de
próxima entrada.
Então, criamos um novo projeto, porque também temos alguma prática em relação
a esse projeto, protegemos e vamos ver o que acontece em seguida.
Tudo bem.
A primeira coisa que precisamos fazer é amarrar o que está livre.
Anexe ao shader.
Podemos fazer isso com o java dot perform.
Sim, temos a sintaxe JavaScript ativada aqui.
Ok, isso é bom.
Tudo bem.
Isso está na chamada de função.
E, dentro dessa chamada de função, estamos fornecendo uma função anônima e esta aqui, que agora
é o nosso corpo que precisamos fornecer ao nosso gancho.
Vou encerrar este caso rapidamente.
Está bem.
Agora precisamos obter essa referência para a classe aleatória segura.
Portanto, se voltarmos ao nosso código aqui, talvez possamos colocar isso à direita.
E mantemos isso em primeiro plano.
Tudo bem.
Então vamos ver.
Queremos conectar essa função à próxima polegada.
E este está dentro da classe aleatória segura e este está dentro da segurança Java.
Seguro, aleatório.
Está bem.
Portanto, aqui queremos conectar a próxima função final.
Este aqui.
Este é o método e este aqui é o objeto.
E o objeto aleatório é da classe.
Seguro aleatório.
E essa referência de classe está aqui.
A segurança do Java é aleatória se você estiver lidando com uma importação e o front.
Portanto, estamos importando aqui todo o nome da classe.
Portanto, se quisermos obter essa referência a essa classe, podemos simplesmente usar toda essa cadeia
de caracteres aqui.
Esta é a referência à classe aleatória insegura.
Se estivermos usando esse nome de pacote aqui.
Nesse caso, precisamos acrescentar o nome da classe no final.
Portanto, se você voltar ao outro script, neste aqui, podemos ver que temos esse nome de pacote e, no final,
precisamos acrescentar o nome da classe.
Mas se estivermos usando uma instrução de importação e esta já for a referência completa da classe, podemos
simplesmente usar esta aqui.
Tudo bem.
Esqueça o que você viu até agora.
Vamos escrever essa novidade aqui.
Tudo bem.
Portanto, a primeira coisa que precisamos fazer é entrar em referência a este.
Portanto, estamos criando uma nova variável.
Quero dizer, neste caso, é um objeto, mas em JavaScript, é uma variável.
Vejamos, também podemos nomear isso exatamente como vimos aqui.
Portanto, podemos nomear essa variável como aleatória e, então, podemos atribuí-la a essa referência e como podemos
obter essa referência.
Absolutamente correto.
Com o Java, não use o Java tot.
E, em seguida, precisamos fornecer todo o nome da classe aqui.
Tudo bem.
Agora temos uma referência da classe aleatória segura em nosso objeto aleatório aqui.
Muito bem, agora podemos chamar random next int e, por favor, tome cuidado com esse I maiúsculo, que é muito importante, caso
contrário a função não será encontrada.
Ok, próximo int e agora queremos definir uma nova implementação e, portanto, queremos atribuir uma nova função
a essa.
Queremos substituir essa função e, sim, o que queremos fazer?
E digamos que desejamos simplesmente retornar zero.
Isso significa que, agora, toda função segura e aleatória de próximo int, esta aqui, seria substituída
pelo valor zero.
Se estivermos fazendo isso corretamente, nesse caso, não estamos fazendo corretamente.
Mas vamos ver o que acontece.
Que erro recebemos.
Então, pegamos este aqui e precisamos nos conectar ao nosso aplicativo.
Então, isso está abrindo este.
Tudo bem.
Podemos ver que está funcionando.
Agora precisamos anexar um leitor a esse processo de aplicação.
Portanto, precisamos usar dados gratuitos, pedir que você use a conexão ADB e, em seguida,
precisamos ter esse nome de pacote, não esse, esse nome de pacote no manifesto do Android.
E este aqui.
Está bem.
Agora estamos vinculados a este e vamos ver se o script funciona.
Está bem.
Estamos recebendo um erro imediatamente.
E se você der uma olhada neste aplicativo, ele ainda está em execução.
Portanto, a liberdade não executou nada até o momento.
Vamos ver do que se trata essa flecha.
A extremidade seguinte tem mais de uma sobrecarga.
E essa é a parte incrível da liberdade: a liberdade nos diz exatamente o que precisamos fazer.
Usamos a assinatura de sobrecarga para escolher.
E agora o Free Guy também identificou que há dois métodos sobrecarregados em relação a esse.
O próximo int tem duas sobrecargas, sem parâmetro e com um parâmetro com um valor inteiro.
Portanto, esse é o motivo pelo qual precisamos ser mais precisos nessa questão.
Agora temos dois métodos e esses dois métodos estão se comportando de forma diferente.
Portanto, vimos que este aqui está retornando um número e este aqui não está retornando
um número entre zero e este número exclusivo.
Portanto, a funcionalidade é diferente.
Portanto, a liberdade precisa saber qual método queremos esperar e, portanto, precisamos
dizer à Frieda exatamente este ou aquele método.
Vamos ver qual é o nosso caso no momento?
Não temos nenhum parâmetro ou temos um parâmetro no método que queremos enganchar e vamos ver.
Aqui, podemos ver que temos um parâmetro que não é parâmetro dentro do OC, e esse é um valor
inteiro.
Muito bem, agora sabemos que precisamos enganchar esse aqui.
A pergunta pode ser: por que não podemos simplesmente usá-lo dessa forma?
Portanto, se você estiver fornecendo aqui um parâmetro neste, por exemplo, param one, então o Freida deverá saber qual
função ele precisa conectar.
Certo.
Porque estamos tendo apenas uma função com um parâmetro.
Sim e não.
Com relação a esse exemplo, ficaria claro.
Com certeza.
Mas também pode ser o caso de esse método ter sido sobrecarregado mais uma vez com apenas um parâmetro, mas
dessa vez de um tipo diferente.
Por exemplo, podemos ter um método sobrecarregado com um parâmetro inteiro e um método sobrecarregado
com uma string dupla longa e um parâmetro float de um desses tipos.
Então, essa abordagem aqui ainda não funciona tão livremente neste momento, ou pelo menos eu também não sei qual função
está sendo conectada agora ou qual função precisa ser conectada.
Portanto, precisamos fazer essa definição exata em relação a esta aqui.
Queremos conectar o método que tem apenas um parâmetro, esse parâmetro inteiro, como uma sobrecarga.
Tudo bem.
Está bem.
Agora vem a pergunta: como podemos fazer isso e qual é a solução para esse problema?
É incrível.
Quero dizer, eu nunca vi uma ferramenta com essa incrível ajuda de saída aqui.
Portanto, o que precisamos fazer é simplesmente fornecer este aqui e copiar e colar este depois da nossa
próxima função final, e pronto.
Então, se colocarmos isso um pouco de lado, também este.
Agora vamos contar para a Frida, ok?
Entre na classe aleatória segura e espere que a próxima função tenha apenas um parâmetro do tipo
inteiro.
Para isso, defina agora uma nova função.
E este aqui.
Independentemente do que estiver aqui dentro ou do que for calculado nessa função, sempre retorne o número zero
em relação a esse gerador de números aleatórios.
E se você der uma olhada no nosso código, a saída agora estará seguindo esta função aqui.
O próximo int aleatório retornará zero depois do que adicionamos mais um.
E isso significa que todos os dados ou, sim, todos os dados têm agora o nome da fase.
Não tenho certeza da palavra correta.
Qual é o número de nice em inglês?
Mas aqui isso é chamado de face num.
Por isso, fico com este aqui.
Tudo bem.
Portanto, todos os dados agora foram desfigurados em um depois, porque.
Sim, zero mais um é uma matemática rápida.
Certo, vamos testar isso.
Então, vamos colocar isso à direita.
Está bem.
Também manterei isto em primeiro plano e isto.
Agora.
Vejamos.
Copiamos, colamos e rolamos a tela um pouco para cima.
Pressionei Enter e agora vamos ver.
Aqui está.
Parece funcionar.
Quero dizer, pode ser uma grande sorte que esse seja o caso agora.
Mas, sim.
E se você alterar o número de dados aqui, vamos ver.
Sim.
Quero dizer, é claro que isso também afeta este aqui, porque esses números ou dados serão preenchidos por
esse gerador de números aleatórios.
Mas isso está ficando ainda mais empolgante porque não estamos apenas conectando essa função de entrada seguinte, mas agora estamos
conectando todas as funções de entrada seguinte em todo o aplicativo.
Portanto, toda vez que esse aplicativo estiver usando um gerador de números aleatórios inseguro next int com uma
função sobrecarregada de um parâmetro inteiro, estaremos conectando essa função e retornando zero.
Está bem.
Para ser honesto, isso também pode causar muitos problemas, mas aprenderemos mais tarde como lidar
com isso aqui.
Então, por exemplo, vou lhe dar uma prévia rápida.
Está bem.
Portanto, digamos que só queremos conectar essa função seguinte, então podemos tomar uma pequena decisão
aqui.
E, por exemplo, estamos fornecendo um número de fases em parâmetro.
Esse é o parâmetro que está sendo fornecido à nossa função e agora
podemos fazer uma simples declaração if aqui dentro e, por exemplo, se o parâmetro um for igual a seis, então ele deve retornar zero, caso contrário, retorne.
E agora você sabe como podemos voltar à função original em relação ao próximo fim?
E, por favor, pense nisso por um momento, porque sim, agora temos um pequeno exercício
aqui.
Você está absolutamente correto nesse ponto.
Portanto, podemos retornar à declaração original simplesmente usando esse próximo fim e fornecendo nossa placa-mãe.
Tudo bem.
Isso significa que, neste momento, estamos retornando apenas o número zero para a próxima infecção que tiver o
parâmetro integer do valor seis.
Quero dizer, isso também poderia acontecer algumas vezes com todo o aplicativo, mas
agora limitamos um pouco e vamos ver se isso funciona.
Então, vamos experimentar isso aqui.
Está bem.
Nenhum erro.
Isso é bom.
E agora vamos ver.
Número de fases seis.
Portanto, agora devemos retornar o número zero.
Mais um.
Portanto, devemos ter um aqui dentro que esteja funcionando perfeitamente.
Ainda está funcionando perfeitamente.
E agora, se você alterar esse número, vamos ver.
Agora, o método original deve ser chamado.
Aqui está.
Portanto, agora temos uma pequena porta dos fundos.
Toda vez que definimos o número de fases para seis.
Estamos substituindo esse método e, sim, caso contrário, o método original está sendo capturado.
Tudo bem.
Legal.
Quero dizer, este é incrível, certo?
Com certeza.
Mas eu gostaria de lhe mostrar um problema.
Se voltarmos a um número de tamanhos, um número de fases para seis, e depois se estivermos substituindo este
aqui, digamos que queremos retornar outro número, o número estático, sete ou seis.
Nesse caso, digamos que queremos retornar o número seis, mas esse número é adicionado mais um no final.
Portanto, agora estamos retornando o número sete para todos esses dispositivos.
E há um pequeno problema.
Podemos ver isso aqui se você alterar o número de 6 para 7.
O layout muda.
Portanto, agora temos números aqui dentro.
Tudo bem.
Vamos ver qual é o problema.
Se estivermos retornando o número sete para esse tipo de dado.
Vamos copiar e colar essa inserção aqui e jogar os dados.
Bem, o aplicativo trava.
Vejamos.
Qual é o problema?
Podemos ver que o processo foi interrompido porque temos um erro não encontrado.
ID do recurso: este aqui.
Portanto, o smartphone está carregando esses recursos relacionados à diocese e à forma de pensamento.
Mas agora estamos retornando o número sete, que não pode ser representado nesses pontos porque não há nenhum
arquivo de recurso para esse número.
E esse pode ser o motivo pelo qual recebemos essa exceção não encontrada aqui.
Tão livre.
Isso nos dá poder ilimitado para aplicar patches em um aplicativo.
Mas, se formos longe demais, poderemos travar o aplicativo em um determinado ponto.
Portanto, precisamos simplesmente testar se funciona ou não.
E se não funcionar, talvez possamos corrigir os outros exemplos dessa função.
Por exemplo, também poderíamos ter corrigido esse problema mais uma vez.
Vou falar um pouco mais sobre isso.
Aqui está.
Poderíamos ter corrigido essa função de lançamento de dados em relação a esse número de face que estamos fornecendo,
por exemplo, o número de fé sete.
Nesse caso, o aplicativo ainda pode funcionar.
Mas não quero entrar nesse assunto agora, pois isso está tornando todo o processo desnecessariamente complexo.
Só quero lhe mostrar que a aplicação de patches com três é absolutamente incrível.
Mas se você for longe demais, poderá travar seu aplicativo.
Tudo bem.
Então, vamos recapitular um pouco.
Se você voltar ao script, o que aprendemos na seção aqui é o seguinte.
Assim, vimos que precisamos ser precisos quanto ao método que queremos usar.
Precisamos identificar o método exato que queremos usar como gancho.
E também vimos que Frieda é incrivelmente prestativa ao nos fornecer todas as informações necessárias
para realizarmos nossa tarefa aqui.
Também vimos que, se formos muito longe, como no caso do retorno ao número sete, ele não está disponível nesse recurso
referente a essa doença.
Depois do travamento, esse aplicativo gratuito nos dá poder ilimitado, mas precisamos usá-lo com sabedoria.
Tudo bem.
Na próxima seção, examinaremos novamente esse aplicativo de dados.
E este será o último desafio que preparei para você neste momento para este aplicativo.
E a tarefa seria a seguinte.
Se clicarmos neste aqui, queremos retornar os números e um, dois, três, quatro, cinco, seis.
E, por exemplo, não importa quantos dados ou número de faces tenhamos inserido aqui, já vimos um pouco
de uma abordagem como esta.
Nós conectamos a próxima infecção e então podemos substituir todos os dados de uma vez.
Ou seja, também podemos envolver isso em um JavaScript mais complexo para executar essa tarefa.
Mas é claro que há uma maneira mais fácil.
Pense no que aprendemos nos últimos vídeos, como esses números estão sendo preenchidos e talvez pense
em uma solução para este.
Daremos uma olhada nisso na próxima seção, mas sinta-se à vontade para fazer isso por conta própria se
estiver preparado para isso.
Caso contrário, não há problema algum.
Mas talvez você possa se familiarizar um pouco com JavaScript e matrizes.
Portanto, sinta-se à vontade para brincar com este aqui e nos vemos no próximo vídeo.