sigalor / whatsapp-web-reveng

Reverse engineering WhatsApp Web.
MIT License
6.15k stars 807 forks source link

WhatsApp APK not working after recompilation #53

Closed infahash closed 5 years ago

infahash commented 6 years ago

This issue came from #45. I have recompiled the WhatsApp APK without changing its source code, but it's not working after the recompilation process, because they are validating their APK signature. I have also tried the same with GBWhatAapp; here, I don't get any errors and generally, it's working fine, but there is an issue with the network connection. So I asked how to bypass this signature validation and @sigalor commented as he has already recompiled the WhatsApp APK and it's working fine. I'd appreciate if he would share how he did it.

EDIT: I have enabled logs for WhatsApp APK and I'm getting a bad-token error when I try to do registration or request-sms.

coolnickname commented 6 years ago

I think you can circumvent the bad-token error by hardcoding a hash key.

Also @sigalor wouldn't it be smarter to just make a wiki for this sort of stuff?

sigalor commented 6 years ago

You're absolutely right, @coolnickname. I hope I'll find some time on the weekend to finally restructure the readme and collect all information spread out over all these issues. But for now, let me write it down here.

First, let's assemble our toolbox. The only programs really needed are these:

Yet, there are some programs used for convenience, mainly to decompile the APK file into Java code (which is not recompilable by itself):

Before being able to start, the WhatsApp APK is needed of course. Call this file com.whatsapp.apk and put it into a new directory.

We're now ready to start the decompilation/disassembling process. Make sure to change the path to ApkTool according to the directory structure. Execute the following commands in the directory with the com.whatsapp.apk file (as stated before, only the first command is absolutely necessary):

  1. java -jar ../apktool_2.3.1.jar d com.whatsapp.apk
  2. ../dex2jar-2.0/d2j-dex2jar.sh com.whatsapp.apk
  3. Open JDGUI, select the newly created com.whatsapp-dex2jar.jar file, save its sources as a ZIP file and decompress it.

Next, create a rebuild/ subdirectory in the directory where com.whatsapp.apk is located. In there, create two files:

Please read through rebuild.sh carefully, to be sure to know what it does and adjust it according to your needs. As you can see, it automatically installs the rebuild WhatsApp APK file to your phone. I'll add some detail on how this script works later.

I cannot really remember anymore whether this is already enough to make the app work and not report a bad-token error or something like that. I'll try it out later and would be happy if someone else could review these instructions as well.

coolnickname commented 6 years ago

I might have some spare time to help with the wiki too

As for the bad-token error, from my days with Yowsup I believe it meant the hardcoded version data was outdated. I believe this consisted of the version number and 2 hashes, all of which were easily accessable on some site. Since in this case it can't be caused by the version being outdated since I assume you use a recent version of Whatsapp, it must be the hashes. If we could find where it checks for these hasheh we could prevent that and hardcode the correct ones 😄.

We could also reach out to developers of custom WA client apps like GBwhatsapp and YoWhatsapp, however I already once tried to reach out to the developer of YoWhatsapp (Yousef Al Basha) to no response.

If I find myself with some time on my hands I'll head back over to the Yowsup repo and do some digging, however it shouldn't be too hard since most likely all recent issues are related to the version being outdated and by some browsing you should find yourself on the site with the hashes. I remember it being just a simple JSON output with with about 4 hashes and 2 version numbers if anyone would like to try themselves.

infahash commented 6 years ago

@sigalor I have already tried these steps (On windows 10 64x / Java 1.8.0_65 ). and again after your comment. but same error message getting when try to get verification sms. actually I have no much knowledge about digital signatures. in decompiled whatsapp code I found they are getting signature via package manager.

coolnickname commented 6 years ago

Can you remove the call and instead return a hardcoded String object?

infahash commented 6 years ago

@coolnickname I'm finding where I can do it.

    public static String a(PackageInfo packageInfo) {
        if (packageInfo.signatures == null || packageInfo.signatures.length != 1) {
            return null;
        }
        try {
            return Base64.encodeToString(MessageDigest.getInstance("SHA-1").digest(packageInfo.signatures[0].toByteArray()), 11);
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }

can you understand this. I thing this is the point.

coolnickname commented 6 years ago

You should change it to

public static String a(PackageInfo packageInfo) {
String currentHash = "";
return Base64.encodeToString(MessageDigest.getInstance("SHA-1").digest(currentHash.getBytes()), 11);
}

In which currentHash is the public key with which Whatsapp was signed. What version of Whatsapp are you using?

infahash commented 6 years ago

@coolnickname I'm using the whatsapp 2.18.46 and I have below details

**_Certificate fingerprints:_**
SHA-1: 38a0f7d505fe18fec64fbf343ecaaaf310dbd799
SHA-256: 3987d043d10aefaf5a8710b3671418fe57e0e19b653c9df82558feb5ffce5d44

**_File hashes:_**
MD5: 52a2f51499935052bc647a17826bbae9
SHA-1: 71a7110765ba8869b91ed24c29e2dfaacfd204d1
SHA-256: d27af2199d83be287e6bef20708c4319c450da402b86826c6255d4691b755d25

which one should I use?

coolnickname commented 6 years ago

I think you should try with the currentHash being 38a0f7d505fe18fec64fbf343ecaaaf310dbd799 first. If it doesn't work I recommend you'd try with 71a7110765ba8869b91ed24c29e2dfaacfd204d1.

But be aware that the error doesn't change to not_authorized because that might mean Whatsapp has banned your IP adress for too many failed attempts.

infahash commented 6 years ago

@coolnickname Ok I will try it. Thank you!

infahash commented 6 years ago

@coolnickname I have changed above method. but it's not working. I found below method when debugging. It's returning a android.content.pm.Signature[] and that method not decompiling to java. how to return an array of android.content.pm.Signature from this string. Is it can do? If yes. give me a sample java code please. the method's smali code given below.

.method public static j(Landroid/content/Context;)[Landroid/content/pm/Signature;
    .locals 4

    .prologue
    .line 8425
    invoke-virtual {p0}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v3

    const/4 v2, 0x0

    .line 8426
    invoke-virtual {p0}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;

    move-result-object v0

    .line 8427
    if-nez v0, :cond_0

    .line 8428
    :goto_0
    return-object v2

    .line 8429
    :cond_0
    :try_start_0
    invoke-virtual {p0}, Landroid/content/Context;->getPackageManager()Landroid/content/pm/PackageManager;

    move-result-object v1

    const/16 v0, 0x40

    invoke-virtual {v1, v3, v0}, Landroid/content/pm/PackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
    :try_end_0
    .catch Landroid/content/pm/PackageManager$NameNotFoundException; {:try_start_0 .. :try_end_0} :catch_0

    move-result-object v0

    .line 8430
    iget-object v2, v0, Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature;

    goto :goto_0

    .line 8431
    :catch_0
    goto :goto_0
.end method
coolnickname commented 6 years ago

You could try

public static Signature j(Context context){
    return new Signature("38a0f7d505fe18fec64fbf343ecaaaf310dbd799");
}

If this doesn't work please try

public static Signature j(Context context){
    return new Signature("38a0f7d505fe18fec64fbf343ecaaaf310dbd799".getBytes());
}

But also remember to also change the method we talked about yesterday to this hash, as I gave you 2 to try but I'm pretty sure the second won't work.

infahash commented 6 years ago

@coolnickname @sigalor Finally I have successfully recompiled whatsapp. I have to made few changes on smali code and add few methods. Thanks for everyone.

coolnickname commented 6 years ago

Please document what you changed here for others to see.

infahash commented 6 years ago

@coolnickname sure. I will do it soon on some free time.

infahash commented 6 years ago

Here is the complete guide for decompilation process of whatsapp (apk).

I have tested this on whatsapp version 2.18.46 NOTE : Hardcoded md5 hash only valid for version 2.18.46 here is the tools we need.

After recompilation of whatsapp it will show error on registration because they are validating their apk signature form server. So we have to replace it with hard coded string.

first decompile whatsapp.apk with ApkTool

java -jar apktool d whatsapp.apk

then you will get a folder with same name of your apk file (whatsapp or something). The source code of whatsapp apk available in whatsapp/smali folder. after here all paths I provide relative to source folder.

To handle whatsapp signature verification process I have created few methods in java and convert that file to smali.

so first open com/whatsapp/registration/bl.smali file on text editor and add below methods to the end of file.

.method public static HexToByte(Ljava/lang/String;)[B
    .registers 8
    .param p0, "s"    # Ljava/lang/String;

    .prologue
    const/16 v6, 0x10

    .line 26
    invoke-virtual {p0}, Ljava/lang/String;->length()I

    move-result v2

    .line 27
    .local v2, "len":I
    div-int/lit8 v3, v2, 0x2

    new-array v0, v3, [B

    .line 28
    .local v0, "data":[B
    const/4 v1, 0x0

    .local v1, "i":I
    :goto_b
    if-ge v1, v2, :cond_2a

    .line 29
    div-int/lit8 v3, v1, 0x2

    invoke-virtual {p0, v1}, Ljava/lang/String;->charAt(I)C

    move-result v4

    invoke-static {v4, v6}, Ljava/lang/Character;->digit(CI)I

    move-result v4

    shl-int/lit8 v4, v4, 0x4

    add-int/lit8 v5, v1, 0x1

    invoke-virtual {p0, v5}, Ljava/lang/String;->charAt(I)C

    move-result v5

    invoke-static {v5, v6}, Ljava/lang/Character;->digit(CI)I

    move-result v5

    add-int/2addr v4, v5

    int-to-byte v4, v4

    aput-byte v4, v0, v3

    .line 28
    add-int/lit8 v1, v1, 0x2

    goto :goto_b

    .line 31
    :cond_2a
    return-object v0
.end method

.method public static a()Ljavax/crypto/SecretKey;
    .registers 5

    .prologue
    .line 13
    const-string v1, "7905796AAFC283ADC6B2AD6CB2137D4F7821F94529D30230D31807613D5B9C28C4A8E25028246B5B17407B6CAFB0378224BF98E06DCF443D87505EE8520886A3"

    invoke-static {v1}, Lcom/whatsapp/registration/bl;->HexToByte(Ljava/lang/String;)[B

    move-result-object v0

    .line 14
    .local v0, "data":[B
    new-instance v1, Ljavax/crypto/spec/SecretKeySpec;

    const/4 v2, 0x0

    array-length v3, v0

    const-string v4, "PBKDF2WithHmacSHA1And8BIT"

    invoke-direct {v1, v0, v2, v3, v4}, Ljavax/crypto/spec/SecretKeySpec;-><init>([BIILjava/lang/String;)V

    return-object v1
.end method

.method public static b()[B
    .registers 1

    .prologue
    .line 22
    const-string v0, "30820332308202F0A00302010202044C2536A4300B06072A8648CE3804030500307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E301E170D3130303632353233303731365A170D3434303231353233303731365A307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E308201B83082012C06072A8648CE3804013082011F02818100FD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C70215009760508F15230BCCB292B982A2EB840BF0581CF502818100F7E1A085D69B3DDECBBCAB5C36B857B97994AFBBFA3AEA82F9574C0B3D0782675159578EBAD4594FE67107108180B449167123E84C281613B7CF09328CC8A6E13C167A8B547C8D28E0A3AE1E2BB3A675916EA37F0BFA213562F1FB627A01243BCCA4F1BEA8519089A883DFE15AE59F06928B665E807B552564014C3BFECF492A0381850002818100D1198B4B81687BCF246D41A8A725F0A989A51BCE326E84C828E1F556648BD71DA487054D6DE70FFF4B49432B6862AA48FC2A93161B2C15A2FF5E671672DFB576E9D12AAFF7369B9A99D04FB29D2BBBB2A503EE41B1FF37887064F41FE2805609063500A8E547349282D15981CDB58A08BEDE51DD7E9867295B3DFB45FFC6B259300B06072A8648CE3804030500032F00302C021400A602A7477ACF841077237BE090DF436582CA2F0214350CE0268D07E71E55774AB4EACD4D071CD1EFAD"

    invoke-static {v0}, Lcom/whatsapp/registration/bl;->HexToByte(Ljava/lang/String;)[B

    move-result-object v0

    return-object v0
.end method

.method public static m482a()[B
    .registers 1

    .prologue
    .line 18
    const-string v0, "64B036BEECE7C96410B04861E0904BB3"

    invoke-static {v0}, Lcom/whatsapp/registration/bl;->HexToByte(Ljava/lang/String;)[B

    move-result-object v0

    return-object v0
.end method

Then on the same file find the method, .method public static a(Landroid/content/Context;Ljava/lang/String;)Lcom/whatsapp/registration/bl; and replace the whole method with below content.

.method public static a(Landroid/content/Context;Ljava/lang/String;)Lcom/whatsapp/registration/bl;
    .locals 7

    .prologue
    const/4 v4, 0x0

    .line 280328
    invoke-static {}, Lcom/whatsapp/c/a;->i()Z

    move-result v0

    if-eqz v0, :cond_0

    .line 280329
    new-instance v1, Lcom/whatsapp/registration/bl;

    const/16 v0, 0x14

    new-array v0, v0, [B

    invoke-direct {v1, v0}, Lcom/whatsapp/registration/bl;-><init>([B)V

    .line 280330
    :goto_0
    return-object v1

    .line 280331
    :cond_0
    new-instance v5, Ljava/io/ByteArrayOutputStream;

    invoke-direct {v5}, Ljava/io/ByteArrayOutputStream;-><init>()V

    .line 280332
    invoke-virtual {p0}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v1

    .line 280333
    sget-object v0, La/a/a/a/d;->dH:Ljava/lang/String;

    .line 280334
    if-eqz v1, :cond_1

    invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v0

    if-nez v0, :cond_2

    .line 280335
    :cond_1
    new-instance v0, Ljava/lang/AssertionError;

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

    throw v0

    .line 280336
    :cond_2
    :try_start_0
    const-string v0, "UTF-8"

    invoke-virtual {v1, v0}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B

    move-result-object v0

    invoke-virtual {v5, v0}, Ljava/io/ByteArrayOutputStream;->write([B)V
    :try_end_0
    .catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0

    .line 280337
    const-class v1, Lcom/whatsapp/registration/bl;

    const-string v0, "/res/drawable-hdpi/about_logo.png"

    invoke-virtual {v1, v0}, Ljava/lang/Class;->getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;

    move-result-object v3

    .line 280338
    if-nez v3, :cond_3

    .line 280339
    const-string v0, "/res/drawable-hdpi-v4/about_logo.png"

    invoke-virtual {v1, v0}, Ljava/lang/Class;->getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;

    move-result-object v3

    .line 280340
    :cond_3
    if-nez v3, :cond_4

    invoke-static {}, Lcom/whatsapp/c/a;->c()Z

    move-result v0

    if-nez v0, :cond_4

    .line 280341
    invoke-virtual {p0}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v6

    .line 280342
    new-instance v3, Landroid/util/DisplayMetrics;

    invoke-direct {v3}, Landroid/util/DisplayMetrics;-><init>()V

    .line 280343
    invoke-virtual {v3}, Landroid/util/DisplayMetrics;->setToDefaults()V

    .line 280344
    const/high16 v0, 0x3fc00000    # 1.5f

    iput v0, v3, Landroid/util/DisplayMetrics;->density:F

    .line 280345
    const/16 v0, 0xf0

    iput v0, v3, Landroid/util/DisplayMetrics;->densityDpi:I

    .line 280346
    iget v0, v3, Landroid/util/DisplayMetrics;->density:F

    iput v0, v3, Landroid/util/DisplayMetrics;->scaledDensity:F

    .line 280347
    iget v0, v3, Landroid/util/DisplayMetrics;->densityDpi:I

    int-to-float v0, v0

    iput v0, v3, Landroid/util/DisplayMetrics;->xdpi:F

    .line 280348
    iget v0, v3, Landroid/util/DisplayMetrics;->densityDpi:I

    int-to-float v0, v0

    iput v0, v3, Landroid/util/DisplayMetrics;->ydpi:F

    .line 280349
    new-instance v2, Landroid/content/res/Resources;

    invoke-virtual {v6}, Landroid/content/res/Resources;->getAssets()Landroid/content/res/AssetManager;

    move-result-object v1

    invoke-virtual {v6}, Landroid/content/res/Resources;->getConfiguration()Landroid/content/res/Configuration;

    move-result-object v0

    invoke-direct {v2, v1, v3, v0}, Landroid/content/res/Resources;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;)V

    .line 280350
    sget v0, Landroid/support/design/widget/CoordinatorLayout$1;->d:I

    invoke-virtual {v2, v0}, Landroid/content/res/Resources;->openRawResource(I)Ljava/io/InputStream;

    move-result-object v3

    .line 280351
    :cond_4
    if-nez v3, :cond_b

    invoke-static {}, Lcom/whatsapp/c/a;->c()Z

    move-result v0

    if-eqz v0, :cond_b

    .line 280352
    :try_start_1
    invoke-virtual {p0}, Landroid/content/Context;->getAssets()Landroid/content/res/AssetManager;

    move-result-object v1

    const-string v0, "about_logo.png"

    invoke-virtual {v1, v0}, Landroid/content/res/AssetManager;->open(Ljava/lang/String;)Ljava/io/InputStream;
    :try_end_1
    .catch Ljava/io/IOException; {:try_start_1 .. :try_end_1} :catch_1

    move-result-object v3

    .line 280353
    :goto_1
    if-nez v3, :cond_5

    .line 280354
    new-instance v0, Ljava/lang/AssertionError;

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

    throw v0

    .line 280355
    :catch_0
    move-exception v1

    .line 280356
    new-instance v0, Ljava/lang/Error;

    invoke-direct {v0, v1}, Ljava/lang/Error;-><init>(Ljava/lang/Throwable;)V

    throw v0

    .line 280357
    :catch_1
    move-exception v1

    .line 280358
    new-instance v0, Ljava/lang/AssertionError;

    invoke-direct {v0, v1}, Ljava/lang/AssertionError;-><init>(Ljava/lang/Object;)V

    throw v0

    .line 280359
    :cond_5
    const/16 v0, 0x2000

    new-array v2, v0, [B

    .line 280360
    :try_start_2
    invoke-virtual {v3, v2}, Ljava/io/InputStream;->read([B)I

    move-result v1

    :goto_2
    const/4 v0, -0x1

    if-eq v1, v0, :cond_6

    .line 280361
    const/4 v0, 0x0

    invoke-virtual {v5, v2, v0, v1}, Ljava/io/ByteArrayOutputStream;->write([BII)V

    .line 280362
    invoke-virtual {v3, v2}, Ljava/io/InputStream;->read([B)I
    :try_end_2
    .catch Ljava/io/IOException; {:try_start_2 .. :try_end_2} :catch_2
    .catchall {:try_start_2 .. :try_end_2} :catchall_0

    move-result v1

    goto :goto_2

    .line 280363
    :cond_6
    :try_start_3
    invoke-virtual {v3}, Ljava/io/InputStream;->close()V
    :try_end_3
    .catch Ljava/io/IOException; {:try_start_3 .. :try_end_3} :catch_6

    .line 280364
    :goto_3
    invoke-virtual {v5}, Ljava/io/ByteArrayOutputStream;->toByteArray()[B

    move-result-object v3

    .line 280365
    invoke-static {}, Lcom/whatsapp/registration/bl;->a()Ljavax/crypto/SecretKey;

    move-result-object v1

    .line 280366
    :try_start_4
    const-string v0, "HMACSHA1"

    invoke-static {v0}, Ljavax/crypto/Mac;->getInstance(Ljava/lang/String;)Ljavax/crypto/Mac;
    :try_end_4
    .catch Ljava/security/NoSuchAlgorithmException; {:try_start_4 .. :try_end_4} :catch_3

    move-result-object v3

    .line 280367
    :try_start_5
    invoke-virtual {v3, v1}, Ljavax/crypto/Mac;->init(Ljava/security/Key;)V
    :try_end_5
    .catch Ljava/security/InvalidKeyException; {:try_start_5 .. :try_end_5} :catch_4

    .line 280368
    invoke-static {p0}, La/a/a/a/d;->j(Landroid/content/Context;)[Landroid/content/pm/Signature;

    move-result-object v2

    .line 280369
    if-eqz v2, :cond_7

    array-length v0, v2

    if-nez v0, :cond_8

    .line 280370
    :cond_7
    new-instance v0, Ljava/lang/AssertionError;

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

    throw v0

    .line 280371
    :catch_2
    :try_start_6
    new-instance v0, Ljava/lang/AssertionError;

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

    throw v0
    :try_end_6
    .catchall {:try_start_6 .. :try_end_6} :catchall_0

    .line 280372
    :catchall_0
    move-exception v0

    .line 280373
    :try_start_7
    invoke-virtual {v3}, Ljava/io/InputStream;->close()V
    :try_end_7
    .catch Ljava/io/IOException; {:try_start_7 .. :try_end_7} :catch_7

    .line 280374
    :goto_4
    throw v0

    .line 280375
    :catch_3
    move-exception v1

    .line 280376
    new-instance v0, Ljava/lang/AssertionError;

    invoke-direct {v0, v1}, Ljava/lang/AssertionError;-><init>(Ljava/lang/Object;)V

    throw v0

    .line 280377
    :catch_4
    move-exception v1

    .line 280378
    new-instance v0, Ljava/lang/AssertionError;

    invoke-direct {v0, v1}, Ljava/lang/AssertionError;-><init>(Ljava/lang/Object;)V

    throw v0

    .line 280379
    :cond_8
    array-length v1, v2

    :goto_5
    if-ge v4, v1, :cond_9

    aget-object v0, v2, v4

    .line 280380
    invoke-static {}, Lcom/whatsapp/registration/bl;->b()[B

    move-result-object v0

    .line 280381
    invoke-virtual {v3, v0}, Ljavax/crypto/Mac;->update([B)V

    .line 280382
    add-int/lit8 v4, v4, 0x1

    goto :goto_5

    .line 280383
    :cond_9
    invoke-static {}, Lcom/whatsapp/c/a;->c()Z

    move-result v0

    if-eqz v0, :cond_a

    .line 280384
    const/16 v0, 0x10

    new-array v0, v0, [B

    .line 280385
    :goto_6
    invoke-virtual {v3, v0}, Ljavax/crypto/Mac;->update([B)V

    .line 280386
    :try_start_8
    const-string v0, "UTF-8"

    invoke-virtual {p1, v0}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B
    :try_end_8
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_8 .. :try_end_8} :catch_5

    move-result-object v0

    .line 280387
    invoke-virtual {v3, v0}, Ljavax/crypto/Mac;->update([B)V

    .line 280388
    new-instance v1, Lcom/whatsapp/registration/bl;

    invoke-virtual {v3}, Ljavax/crypto/Mac;->doFinal()[B

    move-result-object v0

    invoke-direct {v1, v0}, Lcom/whatsapp/registration/bl;-><init>([B)V

    goto/16 :goto_0

    .line 280389
    :cond_a
    invoke-static {}, Lcom/whatsapp/registration/bl;->m482a()[B

    move-result-object v0

    goto :goto_6

    .line 280390
    :catch_5
    move-exception v1

    .line 280391
    new-instance v0, Ljava/lang/AssertionError;

    invoke-direct {v0, v1}, Ljava/lang/AssertionError;-><init>(Ljava/lang/Object;)V

    throw v0

    .line 280392
    :catch_6
    goto :goto_3

    :catch_7
    goto :goto_4

    :cond_b
    goto/16 :goto_1
.end method

Finally open a/a/a/a/d.smali file and find for method, .method public static a(Landroid/content/pm/PackageInfo;)Ljava/lang/String; then replace whole method with the content given below.

.method public static a(Landroid/content/pm/PackageInfo;)Ljava/lang/String;
    .registers 5
    .param p0, "packageInfo"    # Landroid/content/pm/PackageInfo;

    .prologue
    .line 16
    const-string v0, "30820332308202F0A00302010202044C2536A4300B06072A8648CE3804030500307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E301E170D3130303632353233303731365A170D3434303231353233303731365A307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E308201B83082012C06072A8648CE3804013082011F02818100FD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C70215009760508F15230BCCB292B982A2EB840BF0581CF502818100F7E1A085D69B3DDECBBCAB5C36B857B97994AFBBFA3AEA82F9574C0B3D0782675159578EBAD4594FE67107108180B449167123E84C281613B7CF09328CC8A6E13C167A8B547C8D28E0A3AE1E2BB3A675916EA37F0BFA213562F1FB627A01243BCCA4F1BEA8519089A883DFE15AE59F06928B665E807B552564014C3BFECF492A0381850002818100D1198B4B81687BCF246D41A8A725F0A989A51BCE326E84C828E1F556648BD71DA487054D6DE70FFF4B49432B6862AA48FC2A93161B2C15A2FF5E671672DFB576E9D12AAFF7369B9A99D04FB29D2BBBB2A503EE41B1FF37887064F41FE2805609063500A8E547349282D15981CDB58A08BEDE51DD7E9867295B3DFB45FFC6B259300B06072A8648CE3804030500032F00302C021400A602A7477ACF841077237BE090DF436582CA2F0214350CE0268D07E71E55774AB4EACD4D071CD1EFAD"

    .line 18
    .local v0, "currentHash":Ljava/lang/String;
    :try_start_2
    const-string v2, "SHA-1"

    invoke-static {v2}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;

    move-result-object v2

    invoke-virtual {v0}, Ljava/lang/String;->getBytes()[B

    move-result-object v3

    invoke-virtual {v2, v3}, Ljava/security/MessageDigest;->digest([B)[B

    move-result-object v2

    const/16 v3, 0xb

    invoke-static {v2, v3}, Landroid/util/Base64;->encodeToString([BI)Ljava/lang/String;
    :try_end_15
    .catch Ljava/security/NoSuchAlgorithmException; {:try_start_2 .. :try_end_15} :catch_17

    move-result-object v2

    .line 22
    :goto_16
    return-object v2

    .line 19
    :catch_17
    move-exception v1

    .line 20
    .local v1, "e":Ljava/security/NoSuchAlgorithmException;
    invoke-virtual {v1}, Ljava/security/NoSuchAlgorithmException;->printStackTrace()V

    .line 22
    const/4 v2, 0x0

    goto :goto_16
.end method

Edit: in the file a/a/a/a/d.smali find for method .method public static j(Landroid/content/Context;)[Landroid/content/pm/Signature; and replace whole method with

.method public static j(Landroid/content/Context;)[Landroid/content/pm/Signature;
    .registers 5
    .param p0, "r4"    # Landroid/content/Context;

    .prologue
    .line 27
    const-string v1, "30820332308202F0A00302010202044C2536A4300B06072A8648CE3804030500307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E301E170D3130303632353233303731365A170D3434303231353233303731365A307C310B3009060355040613025553311330110603550408130A43616C69666F726E6961311430120603550407130B53616E746120436C61726131163014060355040A130D576861747341707020496E632E31143012060355040B130B456E67696E656572696E67311430120603550403130B427269616E204163746F6E308201B83082012C06072A8648CE3804013082011F02818100FD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C70215009760508F15230BCCB292B982A2EB840BF0581CF502818100F7E1A085D69B3DDECBBCAB5C36B857B97994AFBBFA3AEA82F9574C0B3D0782675159578EBAD4594FE67107108180B449167123E84C281613B7CF09328CC8A6E13C167A8B547C8D28E0A3AE1E2BB3A675916EA37F0BFA213562F1FB627A01243BCCA4F1BEA8519089A883DFE15AE59F06928B665E807B552564014C3BFECF492A0381850002818100D1198B4B81687BCF246D41A8A725F0A989A51BCE326E84C828E1F556648BD71DA487054D6DE70FFF4B49432B6862AA48FC2A93161B2C15A2FF5E671672DFB576E9D12AAFF7369B9A99D04FB29D2BBBB2A503EE41B1FF37887064F41FE2805609063500A8E547349282D15981CDB58A08BEDE51DD7E9867295B3DFB45FFC6B259300B06072A8648CE3804030500032F00302C021400A602A7477ACF841077237BE090DF436582CA2F0214350CE0268D07E71E55774AB4EACD4D071CD1EFAD"

    .line 28
    .local v1, "currHash":Ljava/lang/String;
    const/4 v2, 0x1

    new-array v0, v2, [Landroid/content/pm/Signature;

    const/4 v2, 0x0

    new-instance v3, Landroid/content/pm/Signature;

    invoke-direct {v3, v1}, Landroid/content/pm/Signature;-><init>(Ljava/lang/String;)V

    aput-object v3, v0, v2

    .line 29
    .local v0, "arrSig":[Landroid/content/pm/Signature;
    return-object v0
.end method

Now you are done.

compile changed source with java -jar apktool.jar b whatsapp and sign your apk with jarsigner or any method you like.

whatsapp now work as expected.

infahash commented 6 years ago

If you are working on a smali project, this tool will help you to fix class-package conflicts. Antiguard

kiusnga commented 6 years ago

Hello bro infahash , i need your help on the last whatsapp edit.

chuppito commented 6 years ago

Hello I do not know how to contact you but can you help me do the same thing for waze? I modified the application, it works but the fact that is not the same signature, I lose data (android auto, Spotify). Thanks for your help.

infahash commented 6 years ago

@chuppito Contact me through whatsapp

chuppito commented 6 years ago

If someone else can help me? Without asking to be paid Thank you

netfiretec commented 5 years ago

Good night, I'm really having a hard time, I need to reverse engineer (Whisper) Whatsapp.apk (Android client), and obete a source code without obfuscations, that can be used in android studio, could someone help me?

anodox commented 5 years ago

hello bro iam getting "there is something wrong with your whatsapp version" error . does this method help out?

netfiretec commented 5 years ago

Hello, my name is Leandro, I'm looking for someone who has the ability to reverse engineer the official Whatsapp client (whatsapp.apk), latest version.

Possibility 1: maintain the Chat-Api code, updating protocol and protocol encryption, implement the new methods used by Whatsapp.apk.

Possibility 2: Rewrite a new whatsapp client in the form of a .jar bib to run on linux (Whatsapp client in Java), which has all the resources of the last client Whatsapp.apk

Whoever is able to run the project, please contact us by email, skype or Whatsapp.

Leandro de França +5538991026786 Whatsapp / Telegram leandro@netfiretec.com.br netfiretecc@gmail.com Skype: netfiretec

anodox commented 5 years ago

hello @infahash youre "NOTE : Hardcoded md5 hash only valid for version 2.18.46" worked successfully could you please explain me the changes that you have done into the smali's, it worked perfectly on version 2.18.46 only...PS. i want to make a change in the latest one .

ranshalit commented 5 years ago

Does anyone understand the signature issue ?

If the signature of 2.18.46 is actually "38a0f7d505fe18fec64fbf343ecaaaf310dbd799" then why did @infahash used "30820332308202F0A00302010202044C2536A4300B06072A8648CE3804030500307C310B300906035504..." ?

Is there a complete tutorial on decompile and recompile whatsapp ? Thanks

sir-argupta commented 5 years ago

@infahash can you please tell this for what app version 2.19.17 as the mentioned version become obslute...

sir-argupta commented 5 years ago

@infahash please explain process for WhatsApp ver 2.19.17 as above file are not same as given in your description