Closed infahash closed 5 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?
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):
java -jar ../apktool_2.3.1.jar d com.whatsapp.apk
../dex2jar-2.0/d2j-dex2jar.sh com.whatsapp.apk
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:
rebuild.sh
with these contents.combine.sh
as stated in a comment of rebuild.sh
. This one is mainly for aesthetic purposes, i.e. to not make tha Java programs clutter stdout or stderr.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.
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.
@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.
Can you remove the call and instead return a hardcoded String object?
@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.
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?
@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?
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.
@coolnickname Ok I will try it. Thank you!
@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
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.
@coolnickname @sigalor Finally I have successfully recompiled whatsapp. I have to made few changes on smali code and add few methods. Thanks for everyone.
Please document what you changed here for others to see.
@coolnickname sure. I will do it soon on some free time.
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.
If you are working on a smali project, this tool will help you to fix class-package conflicts. Antiguard
Hello bro infahash , i need your help on the last whatsapp edit.
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.
@chuppito Contact me through whatsapp
If someone else can help me? Without asking to be paid Thank you
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?
hello bro iam getting "there is something wrong with your whatsapp version" error . does this method help out?
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
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 .
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
@infahash can you please tell this for what app version 2.19.17 as the mentioned version become obslute...
@infahash please explain process for WhatsApp ver 2.19.17 as above file are not same as given in your description
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.