Vérification de la signature Apprentissage d'une application d'animation

J'ai lancé ollvm récemment, mais après quelques jours de lancer, la compilation n'est pas terminée et je continue de marcher sur le stand, donc je dois la mettre de côté pour le moment.

L'application est une application d'animation. J'ai vu quelqu'un analyser cette application sur Kanxue: https://bbs.pediy.com/thread-258593.htm. J'ai
senti que l'analyse n'était pas très détaillée, je l'ai donc analysée moi-même et l'ai écrite. Un processus d'analyse

Objectif: modifier l'application en tant que membre permanent

Ouvrez d'abord l'apk et jetez un œil:
Insérez la description de l'image ici

Évidemment, si vous souhaitez modifier la date d'adhésion, vous devez trouver l'activité correspondant à l'interface. Il existe de nombreuses façons de modifier, comme la recherche directe de la chaîne d'appartenance, puis vous pouvez localiser l'emplacement approprié. UserInfoActivity
Insérez la description de l'image ici
Afficher getExpire:

Insérez la description de l'image ici
Voir l'ensemble

Insérez la description de l'image ici
On constate que l'objet dateFormat a été converti plusieurs fois en chaîne et comparé à la chaîne "2100-01-01". Tant qu'il est supérieur ou égal à cette valeur, il s'agit d'un membre permanent.

Tant que c'est très simple, utilisez simplement androidKiller pour modifier la valeur de retour de getExpire.

Ensuite, quand j'ai commencé à courir après la décompilation, j'ai constaté que cela ne fonctionnait pas.

Insérez la description de l'image ici

Que dois-je faire? La première chose que j'ai prise en compte a été la chaîne de recherche. Bien sûr, le logiciel n'est pas si simple et ne peut pas être recherché, on estime donc que la vérification est effectuée côté serveur .

Utilisez un violoniste pour saisir un paquet:

Insérez la description de l'image ici

imei a salué mes yeux, cherchez-le :

Insérez la description de l'image ici

Effectivement, je l'ai trouvé, vérifiez getV ():

Insérez la description de l'image ici

Il s'est avéré être une méthode native, le type de retour est String et un horodatage actuel est transmis. Il n'est pas réaliste de modifier directement la valeur de retour. Vous ne pouvez voir que comment le code de contrôle d'analyse du code de la couche secondaire est généré.

Malheureusement, l'utilisation de l'analyse statique ida a révélé que certains paramètres ne montraient pas, mais heureusement trouvé un paramètre de localisation, vous pouvez trouver une valeur spécifique basée sur le débogage dynamique:
Insérez la description de l'image ici
mais Internet, a déclaré jeb, a également été voir si fonctionnel, avec sa vue jugée très claire:
Insérez la description de l'image ici
le Comme on peut le voir sur la figure, il y a un total de trois vérifications et la valeur fixe "dt8re" + "rt9ws" épissée respectivement. Parmi eux, il y a deux paramètres, un hash1 et un hash2, qui sont
calculés

À l'heure actuelle, deux méthodes ont été pensées pour le débogage dynamique: (1) Débogage dynamique pour obtenir la valeur; (2) Utilisez la technologie hook pour prendre l'horodatage de la valeur fixe et imprimer la valeur de retour, et calculer le résultat selon la méthode de la variable de contrôle

Seule la méthode hook est illustrée ci-dessous:

(1) Utilisez d'abord le script frida hook js

Java.perform(function () {
    
    
    var CheckUtils = Java.use("info.zzjian.dididh.util.CheckUtils");
    CheckUtils.getV.overload("long").implementation = function (j) {
    
    
        var ret = this.getV(j);
        console.log(this.getV(0));
        return (ret);
    };
});

Le résultat d'impression est:

33cc6f39fdt8re3af08b80crt9ws3ff2a033f

Selon les résultats, il est divisé en:

(check1)33cc6f39f + dt8re + (check2)3af08b80c + 9ws3f + (check3)f2a033f

Selon la méthode des variables de contrôle

hash1 = -1916912749L;
hash2 = 1344359219L;

Trouvez la chaîne finale comme suit:

String check1 = Long.toHexString(13904573343L + ts * 2);
        String check2 = Long.toHexString(15821486092L + ts);
        String check3 = Long.toHexString(17165845311L + ts);
        return check1 + "dt8re" + check2 + "rt9ws" + check3;

Selon l'algorithme restauré, réécrivez un CheckUtils.java pour lui faire renvoyer la chaîne directement dans la couche java

public class CheckUtils {
    
    
    public CheckUtils() {
    
    
    }
 
    public String getV(long ts) {
    
    
        String check1 = Long.toHexString(13904573343L + ts * 2);
        String check2 = Long.toHexString(15821486092L + ts);
        String check3 = Long.toHexString(17165845311L + ts);
        return check1 + "dt8re" + check2 + "rt9ws" + check3;
    }
}

Utilisez la ligne de commande pour convertir le fichier java écrit en fichier smali. Voici un script écrit qui peut être visualisé et téléchargé dans mon fichier de ressources (le nom du package est modifié en fonction de la situation réelle):

.class public Linfo/zzjian/dididh/util/CheckUtils;
.super Ljava/lang/Object;
.source "CheckUtils.java"


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 3
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    .line 4
    return-void
.end method


# virtual methods
.method public getV(J)Ljava/lang/String;
    .registers 8

    .prologue
    .line 7
    const-wide v0, 0x33cc6f39fL

    const-wide/16 v2, 0x2

    mul-long/2addr v2, p1

    add-long/2addr v0, v2

    invoke-static {v0, v1}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v0

    .line 8
    const-wide v2, 0x3af08b80cL

    add-long/2addr v2, p1

    invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v1

    .line 9
    const-wide v2, 0x3ff2a033fL

    add-long/2addr v2, p1

    invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v2

    .line 10
    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    invoke-virtual {v3, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v3, "dt8re"

    invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v1, "rt9ws"

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v0

    return-object v0
.end method

Ensuite, écrasez la classe
dans androidkiller avec le code écrit, puis obtenez le résultat avec succès après la décompilation:
Insérez la description de l'image ici

Supplément: Bien sûr, parce que cet apk ne détecte pas les hooks, nous pouvons directement utiliser Xposed ou fridahook pour réaliser la fonction de cracking VIP. Quand j'ai vérifié la déclaration de l'auteur, j'ai constaté que l'auteur ne s'opposait pas à l'utilisation de Xposed pour apporter des modifications:
Insérez la description de l'image ici
merci donc à l'auteur de l'avoir donné J'ai cette opportunité d'apprendre, mais la version crackée de l'apk n'est pas fournie ici. Si vous en avez besoin, vous pouvez télécharger la version originale directement depuis le site officiel: http://dddh.pub/

Supplément: Après le débogage dynamique, il s'avère que le programme est un programme 64 bits, donc ida32 ne pourra pas afficher la chaîne, et la chaîne peut être vue normalement avec ida64

Insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43632667/article/details/105778450
conseillé
Classement