berkus / smali

Automatically exported from code.google.com/p/smali
0 stars 0 forks source link

Error occurred while disassembling class Landroid.support Invalid method index: 35 #222

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What seems to be the problem?
I'am trying to deodex Mms.apk from a Chinese rom for Jiayu G4s phone, because 
it has a bug related to incorrect Caller ID
matching. When trying to deodex de apk everything is fine, but when trying to 
deodex de odex file, I receive an error.

What is the exact smali/baksmali command that you ran?
java -jar baksmali-2.0.3.jar -a 19 -d \framework -c 
\framework\core.jar:\framework\conscrypt.jar:\framework\okhttp.jar:\framework\co
re-junit.jar:\framework\bouncycastle.jar:\framework\ext.jar:\framework\framework
.jar:\framework\framework2.jar:\framework\telephony-common.jar:\framework\voip-c
ommon.jar:\framework\mms-common.jar:\framework\android.policy.jar:\framework\ser
vices.jar:\framework\apache-xml.jar:\framework\webviewchromium.jar:\framework\me
diatek-common.jar:\framework\mediatek-framework.jar:\framework\CustomProperties.
jar:\framework\mediatek-telephony-common.jar:\framework\mediatek-tablet.jar -x 
nou\Mms.apk -o nou\MMS

What version of smali/baksmali are you using? What rom are you working
from?
smali-2.0.3.jar and baksmali-2.0.3.jar
G4S-20140927-1826499 (Android 4.4.2)
The rom can be found here:
http://pan.baidu.com/share/link?shareid=187936476&uk=1680007479

What is the airspeed velocity of an unladen swallow?

Please provide any additional information below: error messages, symptoms,
etc.
The error message is:
Error occurred while disassembling class 
Landroid.support.v4.accessibilityservice.AccessibilityServiceInfoCompat; - 
skipping class
java.lang.RuntimeException: Invalid method index: 35
at 
org.jf.dexlib2.analysis.InlineMethodResolver$InlineMethodResolver_version36.reso
lveExecuteInline(InlineMethodResolver.java:175)
at 
org.jf.dexlib2.analysis.MethodAnalyzer.analyzeExecuteInline(MethodAnalyzer.java:
1422)
at 
org.jf.dexlib2.analysis.MethodAnalyzer.analyzeInstruction(MethodAnalyzer.java:94
1)
at org.jf.dexlib2.analysis.MethodAnalyzer.analyze(MethodAnalyzer.java:202)
at org.jf.dexlib2.analysis.MethodAnalyzer.<init>(MethodAnalyzer.java:137)
at 
org.jf.baksmali.Adaptors.MethodDefinition.addAnalyzedInstructionMethodItems(Meth
odDefinition.java:387)
at 
org.jf.baksmali.Adaptors.MethodDefinition.getMethodItems(MethodDefinition.java:2
96)
at org.jf.baksmali.Adaptors.MethodDefinition.writeTo(MethodDefinition.java:198)
at 
org.jf.baksmali.Adaptors.ClassDefinition.writeDirectMethods(ClassDefinition.java
:277)
at org.jf.baksmali.Adaptors.ClassDefinition.writeTo(ClassDefinition.java:112)
at org.jf.baksmali.baksmali.disassembleClass(baksmali.java:220)
at org.jf.baksmali.baksmali.access$000(baksmali.java:55)
at org.jf.baksmali.baksmali$1.call(baksmali.java:144)
at org.jf.baksmali.baksmali$1.call(baksmali.java:142)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

Error occurred while disassembling class 
Landroid.support.v4.view.accessibility.AccessibilityNodeInfoCompat; - skipping 
class
java.lang.RuntimeException: Invalid method index: 35
at 
org.jf.dexlib2.analysis.InlineMethodResolver$InlineMethodResolver_version36.reso
lveExecuteInline(InlineMethodResolver.java:175)
at 
org.jf.dexlib2.analysis.MethodAnalyzer.analyzeExecuteInline(MethodAnalyzer.java:
1422)
at 
org.jf.dexlib2.analysis.MethodAnalyzer.analyzeInstruction(MethodAnalyzer.java:94
1)
at org.jf.dexlib2.analysis.MethodAnalyzer.analyze(MethodAnalyzer.java:202)
at org.jf.dexlib2.analysis.MethodAnalyzer.<init>(MethodAnalyzer.java:137)
at 
org.jf.baksmali.Adaptors.MethodDefinition.addAnalyzedInstructionMethodItems(Meth
odDefinition.java:387)
at 
org.jf.baksmali.Adaptors.MethodDefinition.getMethodItems(MethodDefinition.java:2
96)
at org.jf.baksmali.Adaptors.MethodDefinition.writeTo(MethodDefinition.java:198)
at 
org.jf.baksmali.Adaptors.ClassDefinition.writeVirtualMethods(ClassDefinition.jav
a:322)
at org.jf.baksmali.Adaptors.ClassDefinition.writeTo(ClassDefinition.java:113)
at org.jf.baksmali.baksmali.disassembleClass(baksmali.java:220)
at org.jf.baksmali.baksmali.access$000(baksmali.java:55)
at org.jf.baksmali.baksmali$1.call(baksmali.java:144)
at org.jf.baksmali.baksmali$1.call(baksmali.java:142)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

Error occurred while disassembling class 
Lcom.android.mms.util.ThumbnailManager$ThumbnailTask; - skipping class
java.lang.RuntimeException: Invalid method index: 32
at 
org.jf.dexlib2.analysis.InlineMethodResolver$InlineMethodResolver_version36.reso
lveExecuteInline(InlineMethodResolver.java:175)
at 
org.jf.dexlib2.analysis.MethodAnalyzer.analyzeExecuteInline(MethodAnalyzer.java:
1422)
at 
org.jf.dexlib2.analysis.MethodAnalyzer.analyzeInstruction(MethodAnalyzer.java:94
1)
at org.jf.dexlib2.analysis.MethodAnalyzer.analyze(MethodAnalyzer.java:202)
at org.jf.dexlib2.analysis.MethodAnalyzer.<init>(MethodAnalyzer.java:137)
at 
org.jf.baksmali.Adaptors.MethodDefinition.addAnalyzedInstructionMethodItems(Meth
odDefinition.java:387)
at 
org.jf.baksmali.Adaptors.MethodDefinition.getMethodItems(MethodDefinition.java:2
96)
at org.jf.baksmali.Adaptors.MethodDefinition.writeTo(MethodDefinition.java:198)
at 
org.jf.baksmali.Adaptors.ClassDefinition.writeDirectMethods(ClassDefinition.java
:277)
at org.jf.baksmali.Adaptors.ClassDefinition.writeTo(ClassDefinition.java:112)
at org.jf.baksmali.baksmali.disassembleClass(baksmali.java:220)
at org.jf.baksmali.baksmali.access$000(baksmali.java:55)
at org.jf.baksmali.baksmali$1.call(baksmali.java:144)
at org.jf.baksmali.baksmali$1.call(baksmali.java:142)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

I've tested also with simplfied command line:
java -jar baksmali-2.0.3.jar -d \framework -x nou\Mms.apk -o nou\MMS
But I still receive the same error.

I've also tried to deodex framework.odex and the errors are similar.

Original issue reported on code.google.com by catalin....@gmail.com on 6 Oct 2014 at 6:30

GoogleCodeExporter commented 9 years ago
You'll need to dump the inline method table for your device, and then provide 
that file via the -T option to baksmali. see baksmali -??  (yes, -?? not -?) 
for more info on that option.

Original comment by jesusfreke@jesusfreke.com on 6 Oct 2014 at 6:34

GoogleCodeExporter commented 9 years ago
I forgot to mention: see 
https://github.com/JesusFreke/smali/tree/master/deodexerant for dumping the 
inline method table.

Original comment by jesusfreke@jesusfreke.com on 6 Oct 2014 at 6:35

GoogleCodeExporter commented 9 years ago
Hi jesusfreke,

I've had a small adventure with deodexerant yestarday and today. I made a 
virtual pc with ubuntu and prepared the AOSP android 4.4.2 and compiled 
deodexerant (is the first time I do this). I put it in my device.. I run it 
just like in the tutorial but into the inline.txt I receive only Failed to load 
dvmGetInlineOpsTable :(
Is there some solution to this?

Original comment by catalin....@gmail.com on 8 Oct 2014 at 7:52

GoogleCodeExporter commented 9 years ago
You might try something like

adb pull /system/lib/libdvm.so /tmp/libdvm.so
strings /tmp/libdvm.so | grep dvmGetInlineOpsTable

If that finds something, but it's different than the symbol name that 
deodexerant looks for (lines 55 and 58 in deodexerant.cc), you can try 
replacing the symbol name there.

Original comment by jesusfreke@jesusfreke.com on 8 Oct 2014 at 8:11

GoogleCodeExporter commented 9 years ago
The result of grep is:
gDvmInlineOpsTable
_Z20dvmGetInlineOpsTablev
_Z26dvmGetInlineOpsTableLengthv

I guess gDvmInlineOpsTable won't work..

Is possible to exist a incompatiblity between the AOSP Android 4.4.2 that I 
build deodexerant with.. and the chinese made one? Or perhaps some core app is 
not running..

I don't know if is relevant but before compiling deodexerant I did played a 
little with Titanium backup pro and tried Integrate sys Dalvik into ROM and 
Undo sys Dalvik integration.

Many thanks for your help! Even if is not working I've learned some new stuff 
these days.

Original comment by catalin....@gmail.com on 8 Oct 2014 at 8:35

GoogleCodeExporter commented 9 years ago
Based on that, it looks like it should be working. I'm not sure why it wouldn't 
be.

I don't understand what you said about integrating/undo dalvik integration.

Original comment by jesusfreke@jesusfreke.com on 8 Oct 2014 at 8:39

GoogleCodeExporter commented 9 years ago
Regarding integrating and undo dalvik integration, I've tried these functions 
of Titanium Backup Pro on my device because I've read on some various blogs 
that is automatically deodexing the apps on the device.
Actually in my system/apps , there is no more odex files. But I don't think it 
did actually deodexed the apps or it just moved them somewhere else. I will try 
to do a factory reset and see if it helps to make the inline.txt file.

Original comment by catalin....@gmail.com on 8 Oct 2014 at 9:15

GoogleCodeExporter commented 9 years ago
You can also load up libdvm.so in a hex editor, and try to find the inline 
method table manually. You'll want to look for the methods mentioned in 
https://github.com/JesusFreke/smali/blob/master/dexlib2/src/main/java/org/jf/dex
lib2/analysis/InlineMethodResolver.java. There will likely be a handful of new 
methods at the end of the table, or possibly even in the middle of the table.

Once you find the table, you could manually create an inline.txt to give to 
baksmali.

Some background: one of the optimizations in an odex file is to replace some 
invoke instructions with an invoke-inline instruction, with an index into the 
inline table. So baksmali has to know the contents of the inline table in order 
to be able to "reverse" this, and replace the invoke-inline instruction with 
the original invoke instruction.

By default, baksmali knows about the inline table from "stock" dalvik, but some 
OEMs choose to add or modify the inline table, in which case you have to give 
the new inline table to baksmali via the inline.txt file.

What you'll be looking for in libdvm.so is the compiled gDvmInlineOpsTable 
struct, which is defined in dalvik/vm/InlineNative.cpp.

Original comment by jesusfreke@jesusfreke.com on 8 Oct 2014 at 9:40

GoogleCodeExporter commented 9 years ago
Hi,

I think I finally extrated the table from libdvm.so.
I've used IDA Pro, it makes everything much clearer :)

But unfortunately for me, when I try do use baksmali, I receive an error:
Exception in thread "main" java.lang.NullPointerException
ineMethod<CustomInLineMethodResolver.java:120>  .. screenshot attached.

Also I noticed that if I change de encoding of the file from UTF8-without BOM 
to UTF8, the error is located in CustomInLineMethodResolver.java:107. It is 
possible that the file could contain invalid characters?

The command line:
java -jar baksmali-2.0.3.jar -a 19 -d framework -T inline.txt -c 
\framework\core.jar:\framework\conscrypt.jar:\framework\okhttp.jar:\framework\co
re-junit.jar:\framework\bouncycastle.jar:\framework\ext.jar:\framework\framework
.jar:\framework\framework2.jar:\framework\telephony-common.jar:\framework\voip-c
ommon.jar:\framework\mms-common.jar:\framework\android.policy.jar:\framework\ser
vices.jar:\framework\apache-xml.jar:\framework\webviewchromium.jar:\framework\me
diatek-common.jar:\framework\mediatek-framework.jar:\framework\CustomProperties.
jar:\framework\mediatek-telephony-common.jar:\framework\mediatek-tablet.jar -x 
lucru\Mms.odex -o lucru\MMS
pause

Inline.txt also attached.
tableIDA.jpg is a screenshot of IDA at the location of the table :)

Original comment by catalin....@gmail.com on 9 Oct 2014 at 7:05

Attachments:

GoogleCodeExporter commented 9 years ago
Actually now I see if I save it to UTF8 the error is:
Invalid method descriptor: 
?Lorg/apache/harmony/dalvik/NativeTestTarget;->emptyInlineMethod()V     line 
107 in CustomInLineMethodResolver.

Original comment by catalin....@gmail.com on 9 Oct 2014 at 7:11

GoogleCodeExporter commented 9 years ago
It looks like it might be a newline problem.. does it work if you use 
unix-style newlines?

Original comment by jesusfreke@jesusfreke.com on 9 Oct 2014 at 7:14

GoogleCodeExporter commented 9 years ago
Oh, nevermind. The initial '?' is likely just the BOM. (don't save with BOM :)).

Let me look at the NPE, and see if I can figure out what's going on there

Original comment by jesusfreke@jesusfreke.com on 9 Oct 2014 at 7:16

GoogleCodeExporter commented 9 years ago
I did that now and the error is back to the line 120 which is my first error 
received.

Original comment by catalin....@gmail.com on 9 Oct 2014 at 7:19

GoogleCodeExporter commented 9 years ago
Yeah, I still think the NPE might be related to the newlines anyway. Can you 
try with unix-style newlines?

The inline.txt is typically generated by deodexerant on the device, and so it 
normally has unix-style newlines.

Original comment by jesusfreke@jesusfreke.com on 9 Oct 2014 at 7:27

GoogleCodeExporter commented 9 years ago
Oh! Nevermind. This is a known (and fixed) issue.  
https://github.com/JesusFreke/smali/commit/dd2079cd53c94056436d8c7c26df801fb210d
f4d

The fix just isn't in 2.0.3, so you'll need to build a fresh baksmali from the 
current source. Sorry for the trouble! I should probably do a new release soon 
:)

Original comment by jesusfreke@jesusfreke.com on 9 Oct 2014 at 7:37

GoogleCodeExporter commented 9 years ago
Wooooow it worked!!! :) OMG :)
Many thanks for your help! I felt like all the technology is against me, 
nothing worked as expected but finally made it!

I think I should make a tutorial of how to extract the table from the 
libdvm.so, but without IDA I don't think there is a chance to spot all of the 
entries. I tried first without IDA, using a hexeditor, but after the first 
lines in the table it started to don't make any sense.

Again! Many thanks and you did a perfect job creating these tools! Congrats!

Original comment by catalin....@gmail.com on 9 Oct 2014 at 7:53

GoogleCodeExporter commented 9 years ago
Great! I'm still curious why it wasn't able to load the dvmGetInlineOpsTable 
method from the .so, but oh well.

Original comment by jesusfreke@jesusfreke.com on 9 Oct 2014 at 8:00

GoogleCodeExporter commented 9 years ago
Hi!

I was also curious about why deodexerant wasn't giving the tables and I started 
to do some tests.
I've searched on google for dlsym() and I found out this:
http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html

And from here I come with the ideea to include some dlerror() to see what kind 
of error I receive to see if I cand find something relevant.
http://pubs.opengroup.org/onlinepubs/009695399/functions/dlerror.html

After I included two error checks, suprisingly it started working!
You can see the changes in the attached deodexerant.c

So when I'm running deodexerant on the device I receive the attached inline.txt

So the first line is the first error occoured: A dynamic linking error 
occurred: (undefined symbol: dvmGetInlineOpsTable)

After the error I have the table.
I can't explain why is doing this and why is not executing the second dlsym.. 
but I see that checking for errors with dlerror(); helped!

Original comment by catalin....@gmail.com on 10 Oct 2014 at 6:55

Attachments:

GoogleCodeExporter commented 9 years ago
Huh, weird. I have no idea why adding the error checking would help. It's 
probably a good idea to add the error check anyway, so that deodexerant can 
print a better error message when it doesn't work.

Anyway, thanks for looking into this, I'm glad you were able to get it working 
:)

Original comment by jesusfreke@jesusfreke.com on 10 Oct 2014 at 7:03

GoogleCodeExporter commented 9 years ago
Now I read in more detail and they say:

The function dlsym() takes a "handle" of a dynamic library returned by dlopen() 
and the null-terminated symbol name, returning the address where that symbol is 
loaded into memory. If the symbol is not found, in the specified library or any 
of the libraries that were automatically loaded by dlopen() when that library 
was loaded, dlsym() returns NULL. (The search performed by dlsym() is breadth 
first through the dependency tree of these libraries.) Since the value of the 
symbol could actually be NULL (so that a NULL return from dlsym() need not 
indicate an error), the correct way to test for an error is to call dlerror() 
to clear any old error conditions, then call dlsym(), and then call dlerror() 
again, saving its return value into a variable, and check whether this saved 
value is not NULL. 

Original comment by catalin....@gmail.com on 10 Oct 2014 at 7:07

GoogleCodeExporter commented 9 years ago
I found what the problem is.

I modified the code and included some printf to see if is executing the second 
dlsym() call.

And I found out that the second dlsym() is not executing if the error is not 
cleared before.

I guess this is how dlsym is working. I also found in the official examples 
this line
 dlerror();    /* Clear any existing error */

So I guess is not mandatory to check for errors but is mandatory to clear the 
previous errors before executing another dlsym() call.

I hope this help :)

Original comment by catalin....@gmail.com on 10 Oct 2014 at 7:29

Attachments: