0

This is original smali code of a classes.dex method before installation

.method public static createAutoMatchCriteria(IIJ)Landroid/os/Bundle;
    .registers 6

    new-instance v0, Landroid/os/Bundle;

    invoke-direct {v0}, Landroid/os/Bundle;-><init>()V

    const-string v1, "min_automatch_players"

    invoke-virtual {v0, v1, p0}, Landroid/os/Bundle;->putInt(Ljava/lang/String;I)V

    const-string p0, "max_automatch_players"

    invoke-virtual {v0, p0, p1}, Landroid/os/Bundle;->putInt(Ljava/lang/String;I)V

    const-string p0, "exclusive_bit_mask"

    invoke-virtual {v0, p0, p2, p3}, Landroid/os/Bundle;->putLong(Ljava/lang/String;J)V

    return-object v0
.end method

This is edited smali code of a classes.dex method before installation

.method public static createAutoMatchCriteria(IIJ)Landroid/os/Bundle;
    .registers 6

    new-instance v0, Landroid/os/Bundle;

    invoke-direct {v0}, Landroid/os/Bundle;-><init>()V

    const-string v1, "min_automatch_players"

    const/4 p0, 0x2

    invoke-virtual {v0, v1, p0}, Landroid/os/Bundle;->putInt(Ljava/lang/String;I)V

    const-string p0, "max_automatch_players"

    const/16 p1, 0x14

    invoke-virtual {v0, p0, p1}, Landroid/os/Bundle;->putInt(Ljava/lang/String;I)V

    const-string p0, "exclusive_bit_mask"

    invoke-virtual {v0, p0, p2, p3}, Landroid/os/Bundle;->putLong(Ljava/lang/String;J)V

    return-object v0
.end method

This is the same method but of the classes.dex extracted from dalvik cache.

.method public static createAutomatchCriteria(IIJ)Landroid/os/Bundle
    .registers 6

new-instance v0 Landroid/os/Bundle;

invoke-direct {v0} Landroid/os/Bundle;-><init>()V

const-string v1 "min_automatch_players"

const/4 v2 0x2 

const-string v2 "max_automatch_players"

const/16 v3 0x14

const-string v2 "exclusive_bit_mask"

return-object v0

Where did the virtual invocations after those integer constants go? Am i missing something? Or does dalvik store those invocations somewhere else?

6
  • i guess you are right. I used the same tool which i had used to convert the original dex file to smali. Sorry but do you know an example of an optimised dex command?
    – Silent
    Sep 8 at 23:31
  • i got the optimised dex file from android 4.4.4
    – Silent
    Sep 10 at 1:06
  • One more question does the oat file of ART runtime have the same smali code as the dex files. I mean since you stated that bytecode before android 6.0 was hard to decode is the smali code the same or similar in the optimised files?
    – Silent
    Sep 11 at 14:02
  • oat file are ELF files. They contain mostly compiled native code. As far as I remember oat files have the original non-optimized DEX file(s) embedded inside but I am not sure if this is still the case for modern Android versions.
    – Robert
    Sep 11 at 14:39
  • Thank you so much you have been of much great help and a source of knowledge for me. I wish i could upvote you comments but i cant see the option.
    – Silent
    Sep 11 at 22:00
2

As far as I know the Dalvik cache does not contain plain dex files, but instead contains optimized (odex) files.

Odex files use an extended op code set and I would assume the dex-to-smali decompiler you have used doe snot support those extended op codes and simply ignores them. That is the reason the virtual invocations are not present in the Smali code generated form the odex file.

You should be able to verify this by viewing the dex file in a Smali decompiler that display the raw dex byte code hex values. You can try e.g. latest unstable version of Jadx (newer than v1.2.0), switch to Smali view for the class and enable "Show Dalvik Bytecode". Then you should be able to see what byte code values were not decoded (not sure how good Jadx handles odex files, but internally it also bases on smali/baksmali library).

In your comments you wrote that the used device is running Android 4.4.4. As documented in the Smali/Baksmali project on Github the odex file and instruction format before Android 6 is not supported by common Smali decompiler, as far as I know because it had not been standardized so every Android device can have it's own variant. The optimized dex files were designed to be used by anything else than the Dalvik VM present on the device itself.

1
  • Actually i just used a normal simpler dex viewer and editor app on android. The app doesnt have the libraries you stated or any i have seen before. I will try another decompiler and see if the same results will occur. Thanks for the answer.
    – Silent
    Sep 28 at 23:52
0

A class i extracted from dalvik cache(classes.dex)

if-ne v0 v9 :label_7
const/4 v0 0 
label_7:
const/4 v1 0 
const/4 v2 -1 
if-ne v0 v2 :label_14
return v1
label_14:
const/4 v3 0 
const/4 v4 -1 
label_16:
if-eq v0 v2 :label_91
if-ge v3 v5 :label_91
aget v5 v5 v0
if-ne v5 v6 :label_81
if-ne v0 v1 :label_41
aget v1 v1 v0
goto :label_47
label_41:
aget v3 v1 v0
aput v3 v1 v4
label_47:
if-eqz v10 :label_54
label_54:
add-int/lit8 v10 v10 -1
add-int/lit8 v9 v9 -1
aput v2 v9 v0
if-eqz v9 :label_76
label_76:
aget v9 v9 v0
return v9
label_81:
aget v4 v4 v0
add-int/lit8 v3 v3 1
move v7 v4
move v4 v0
move v0 v7
goto :label_16
label_91:
return v1

The same exact class extracted from the odex file of the app(not from dalvik cache)

iget-object v0 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->e:Landroidx/constraintlayout/solver/SolverVariable;
if-ne v0 v9 :label_7
const/4 v0 0 
iput-object v0 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->e:Landroidx/constraintlayout/solver/SolverVariable;
label_7:
iget v0 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->i:I
const/4 v1 0 
const/4 v2 -1 
if-ne v0 v2 :label_14
return v1
label_14:
const/4 v3 0 
const/4 v4 -1 
label_16:
if-eq v0 v2 :label_91
iget v5 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->a:I
if-ge v3 v5 :label_91
iget-object v5 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->f:[I
aget v5 v5 v0
iget v6 v9 Landroidx/constraintlayout/solver/SolverVariable;->a:I
if-ne v5 v6 :label_81
iget v1 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->i:I
if-ne v0 v1 :label_41
iget-object v1 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->g:[I
aget v1 v1 v0
iput v1 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->i:I
goto :label_47
label_41:
iget-object v1 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->g:[I
aget v3 v1 v0
aput v3 v1 v4
label_47:
if-eqz v10 :label_54
iget-object v10 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->b:Landroidx/constraintlayout/solver/ArrayRow;
invoke-virtual {v9,v10} Landroidx/constraintlayout/solver/SolverVariable;->b(Landroidx/constraintlayout/solver/ArrayRow;)V
label_54:
iget v10 v9 Landroidx/constraintlayout/solver/SolverVariable;->i:I
add-int/lit8 v10 v10 -1
iput v10 v9 Landroidx/constraintlayout/solver/SolverVariable;->i:I
iget v9 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->a:I
add-int/lit8 v9 v9 -1
iput v9 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->a:I
iget-object v9 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->f:[I
aput v2 v9 v0
iget-boolean v9 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->k:Z
if-eqz v9 :label_76
iput v0 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->j:I
label_76:
iget-object v9 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->h:[F
aget v9 v9 v0
return v9
label_81:
iget-object v4 v8 Landroidx/constraintlayout/solver/ArrayLinkedVariables;->g:[I
aget v4 v4 v0
add-int/lit8 v3 v3 1
move v7 v4
move v4 v0
move v0 v7
goto :label_16
label_91:
return v1

Turns out the app was displaying correctly everything As you can see the odex file contains the invocations i was looking for. It seems like the odex file is identical to the classes.dex in the apk. I also tested and found that when the application used a classes.dex(not odex), a process called dexopt runs before the app opens and in my opinion i think that it fetches those invocations and maybe more data from the classes.dex inside the apk. Thats why i noticed that the odexed app lauched faster than when it was deodexed. From many articles i read, they stated that odex files are like a copy of the app and when launching no further data needs to be extracted from the application. Anyway, maybe this question was irrelevant since DVM is becoming obsolete(or has become) as from android 5 ART has replaced it. By the way this dex file is from a different app from the one i used in the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.