I recently formatted my hard drive and forgot to save a java project from it. After trying to recover those files with recovery tools found on internet, I got the files back but... the content is unreadable; i.e. my Main.java class looks like :
108b 4424 5085 ff8b 403c 7e10 8b7c 2410
8904 2489 7c24 04e8 74b0 0200 8b74 2428
8d45 07c7 4424 2000 0000 0089 4424 1885
f60f 8e52 0100 0090 8b44 2450 8b7c 2420
8b4c 2410 8b40 1885 c98b 04b8 8944 2424
8b44 2450 8b40 248b 3cb8 8b44 2450 8b40
3c89 4424 1c0f 8e3d 0100 0031 f631 ed89
7c24 2c89 f7eb 0e90 c604 2f00 83c5 013b
6c24 1074 3f39 f57c ef8b 4424 1c8d 7436
0189 7424 0489 0424 e8f3 af02 0089 6c24
0889 7c24 0489 0424 8944 2414 e86f a202
...
What is this exactly? Is there a way I can write like a python script to translate it back to a readable java class ? Simple hexadecimal to ascii doesn't seem to work.
Related
I am trying to analyse dex files, and I want to know if I can get the java code or what a specific bytes from the dex file mean.
Any help will be appreciated!
Getting java code from bytecode is called decompilation, and you will need to use a decompiler. Although I'm not aware of any decompiler that will do partial decompilation of just a snippet of bytecode. There may not even be enough info in that snippet to perform a proper decompilation.
"Or what specific bytes from the dex file mean" - you could try using baksmali's annotated dump functionality. It writes out a format that has the binary bytes on the left side, and a structured text view on the right side corresponding to the bytes on the left side.
e.g.
baksmali dump HelloWorld.dex
...
|-----------------------------
|code_item section
|-----------------------------
|
|[0] code_item: LHelloWorld;->main([Ljava/lang/String
|;)V
0001c4: 0200 | registers_size = 2
0001c6: 0100 | ins_size = 1
0001c8: 0200 | outs_size = 2
0001ca: 0000 | tries_size = 0
0001cc: 0000 0000 | debug_info_off = 0x0
0001d0: 0800 0000 | insns_size = 0x8
| instructions:
0001d4: 6200 0000 | sget-object v0, Ljava/lang/System;->out:Ljava/io
|/PrintStream;
0001d8: 1a01 0000 | const-string v1, "Hello World!"
0001dc: 6e20 0100 1000 | invoke-virtual {v0, v1}, Ljava/io/PrintStream;->
|println(Ljava/lang/String;)V
0001e2: 0e00 | return-void
...
On the left side we have
[offset]: [binary data] and then the right side has the interpreted view. e.g. field name and value, or disassembled instruction, etc.
I'm facing the following exception:
Caused by: java.lang.VerifyError: Bad return type
Exception Details:
Location:
com/company/MyClass.getProperty(Ljava/lang/String;)Ljava/lang/Object; #93: ireturn
Reason:
Type integer (current frame, stack[0]) is not assignable to 'java/lang/Object' (from method signature)
Current Frame:
bci: #93
flags: { }
locals: { 'com/company/MyClass', 'java/lang/String', 'java/lang/String' }
stack: { integer }
Bytecode:
0x0000000: 2b01 a600 0812 8da7 0007 2bb6 0090 4d2c
0x0000010: b600 94ab 0000 0064 0000 0007 9a7f 0d13
0x0000020: 0000 005f 9b27 5edf 0000 004b 0000 fc71
0x0000030: 0000 0041 0023 a6ed 0000 005a 03b3 b10f
0x0000040: 0000 0046 34ad f045 0000 0055 7a92 a99e
0x0000050: 0000 0050 2ab6 0096 b02a b600 98ac 2ab6
0x0000060: 009a b02a b600 9cb0 2ab6 009e b02a b600
0x0000070: a0b0 2ab6 00a2 b0bb 0079 59bb 007b 59b7
0x0000080: 007c 12a4 b600 822c b600 82b6 0086 b700
0x0000090: 88bf
Stackmap Table:
same_frame(#10)
same_locals_1_stack_item_frame(#14,Object[#101])
append_frame(#84,Object[#101])
same_frame(#89)
same_frame(#94)
same_frame(#99)
same_frame(#104)
same_frame(#109)
same_frame(#114)
same_frame(#119)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
What does Bytecode, Stackmap Table sections mean? How can I interpret them ?
Here is a breakdown for the entire message:
Caused by: java.lang.VerifyError: Bad return type
This tells you what the exception is(java.lang.VerifyError) and the error message associated with it(Bad return type). You can use the exception type to determine a basic understanding for what the exception is(for example, if it were a NullPointerException, you can tell there was some sort of null object that was referenced), but you need to use the exception message to get a better understanding of why the exception was thrown. It looks here like you might have been trying to return a type that is different from the type specified by the method definition.
Location:
com/company/MyClass.getProperty(Ljava/lang/String;)Ljava/lang/Object; #93: ireturn
This tells you where the exception occurred. You can tell that it happened in the class at com.company.MyClass at the method getProperty. It also tells you the parameter for the method, being String, and the return type, being Object. The #93: ireturn refers to the Java bytecode, which I will touch on later.
Reason:
Type integer (current frame, stack[0]) is not assignable to 'java/lang/Object' (from method signature)
This gives you a more specific reason for why the exception was thrown, and tells you exactly why. It tells you that an integer cannot be assigned to Object (this is probably because you are trying to return an int primitive, which does not inherit the Object type).
Current Frame:
bci: #93
flags: { }
locals: { 'com/company/MyClass', 'java/lang/String', 'java/lang/String' }
stack: { integer }
This section tells you about the current frame. To go into that, we have to look into how Java actually works. When you compile some code in Java, it turns it into Java bytecode. This is similar to regular assembly, except that it can only run on the JVM, or Java Virtual Machine. On this virtual machine, frames are created, and contain all of the local information. I am not completely experienced in the specifics of this information, but to my knowledge, the bci tag contains the current position in the bytecode. The locals tells Java what classes are loaded to the current scope, and the stack is exactly what it sounds like. It is basically just a list of a bunch of values.
Bytecode:
0x0000000: 2b01 a600 0812 8da7 0007 2bb6 0090 4d2c
0x0000010: b600 94ab 0000 0064 0000 0007 9a7f 0d13
0x0000020: 0000 005f 9b27 5edf 0000 004b 0000 fc71
0x0000030: 0000 0041 0023 a6ed 0000 005a 03b3 b10f
0x0000040: 0000 0046 34ad f045 0000 0055 7a92 a99e
0x0000050: 0000 0050 2ab6 0096 b02a b600 98ac 2ab6
0x0000060: 009a b02a b600 9cb0 2ab6 009e b02a b600
0x0000070: a0b0 2ab6 00a2 b0bb 0079 59bb 007b 59b7
0x0000080: 007c 12a4 b600 822c b600 82b6 0086 b700
0x0000090: 88bf
This tells you the raw bytecode of your program. This is what is being read by the JVM, and is quite closely related to assembly code. You can look at Bytecode Viewer to try and see the bytecode in a more human-readable form.
Stackmap Table:
same_frame(#10)
same_locals_1_stack_item_frame(#14,Object[#101])
append_frame(#84,Object[#101])
same_frame(#89)
same_frame(#94)
same_frame(#99)
same_frame(#104)
same_frame(#109)
same_frame(#114)
same_frame(#119)
The Stackmap table essentially tells Java the expected types of variables and operands of a method during its execution. You can read more about that here.
I hope this information gives you a good explanation of everything you were looking for. Don't hesitate to ask for a better explanation of anything.
I have a file formated .TXT like this :
[Quest]
Name: The Adventure
Creator: Darius
Reward: 0g
[#New Monster]
MonsterID: 100
MonsterHP: 23987
MonsterLv: 11
MonsterDmg: 133
MonsterType: Magic
[#New Monster]
MonsterID: 101
MonsterHP: 21236
MonsterLv: 8
MonsterDmg: 95
MonsterType: Physical
[#New Item]
ItemID: 222
ItemDamage: 88
ItemType: Robe
How can i parse this file so i can get the monsterid,monsterhp etc and itemId,itemdamage etc. There is two [#New Monsters]
I'm having an issue where org.apache.commons.io.FileUtils.copyFile(File, File) is producing slightly different files. When I compare these files with bsdiff or in an editor, I can tell they're different. Certain bytes are being copied as question marks. For example 0200 (octal) is being copied as ? (077 octal).
So, I create a test case to include in a bug report. I make a copy of the executable, and then compare using FileUtils.checksumCRC32(File). Unexpectedly, the files have the same checksum. I then compare them by iterating through a FileInputStream of each file. This also asserts that the files are the same.
The files certainly differ. One runs, the other doesn't. bsdiff produces a diff of the two files. I can tell that certain bytes are being copied wrong by inspecting the files with my eyes.
However, to the JVM these files are the same. Any ideas of why I'm observing this behavior?
System info:
Windows 7, 64 bit; JVM 1.6.0_22, 32 bit
Eh, sorry everyone. Maven was 'filtering' the executable, which changed the encoding before copying it to maven's 'target' directory. Then FileUtils was correctly copying the messed up executable from 'target' to the destination. I was comparing the version in my source directory to the one in the destination.
This program writes every possible byte and reads them back in again. If the files were being corrupted how would Java turn those bytes back into their original values. i.e. how could it tell that 077 is 0200 and not 077.
byte[] bytes = new byte[256];
for(int i=0;i<256;i++)
bytes[i] = (byte) i;
FileUtils.writeByteArrayToFile(new File("tmp.dat"), bytes);
byte[] bytes2 = FileUtils.readFileToByteArray(new File("tmp.dat"));
System.out.println("equals "+Arrays.equals(bytes, bytes2));
a dump of the file shows.
od -x tmp.dat
0000000 0100 0302 0504 0706 0908 0b0a 0d0c 0f0e
0000020 1110 1312 1514 1716 1918 1b1a 1d1c 1f1e
0000040 2120 2322 2524 2726 2928 2b2a 2d2c 2f2e
0000060 3130 3332 3534 3736 3938 3b3a 3d3c 3f3e
0000100 4140 4342 4544 4746 4948 4b4a 4d4c 4f4e
0000120 5150 5352 5554 5756 5958 5b5a 5d5c 5f5e
0000140 6160 6362 6564 6766 6968 6b6a 6d6c 6f6e
0000160 7170 7372 7574 7776 7978 7b7a 7d7c 7f7e
0000200 8180 8382 8584 8786 8988 8b8a 8d8c 8f8e
0000220 9190 9392 9594 9796 9998 9b9a 9d9c 9f9e
0000240 a1a0 a3a2 a5a4 a7a6 a9a8 abaa adac afae
0000260 b1b0 b3b2 b5b4 b7b6 b9b8 bbba bdbc bfbe
0000300 c1c0 c3c2 c5c4 c7c6 c9c8 cbca cdcc cfce
0000320 d1d0 d3d2 d5d4 d7d6 d9d8 dbda dddc dfde
0000340 e1e0 e3e2 e5e4 e7e6 e9e8 ebea edec efee
0000360 f1f0 f3f2 f5f4 f7f6 f9f8 fbfa fdfc fffe
I was curious about the runhprof output? I am mainly concerned about the memory section. It looks like there are multiple entries of the same class. Why would that be.
Is there a way to get hprof to print how much memory a particular class(the instances of that class) take up in memory. One value for each class.
Also, what tools do you use beside 'hat' to analyze the output?
I ran the java command with jvm arg:
-Xrunhprof:heap=sites,depth=4,format=a,file=prof/hprof_dump.txt
Here is brief snippet of the output. Some classes are listed multiple times in the output.
SITES BEGIN (ordered by live bytes) Tue Jul 28 19:33:41 2009
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 29.75% 29.75% 700080 43755 576000016 36000001 307483 java.lang.Double
2 7.13% 36.88% 167840 5245 370432 11576 300993 clojure.lang.PersistentHashMap$LeafNode
3 2.09% 38.98% 49296 2054 60048 2502 301295 clojure.lang.Symbol
4 2.09% 41.07% 49200 3 49200 3 301071 char[]
5 1.33% 42.40% 31344 1306 68088 2837 300998 clojure.lang.PersistentHashMap$BitmapIndexedNode
6 1.10% 43.50% 25800 645 25800 645 301050 clojure.lang.Var
7 1.05% 44.54% 24624 3 24624 3 301069 byte[]
8 0.86% 45.40% 20184 841 49608 2067 301003 clojure.lang.PersistentHashMap$INode[]
9 0.78% 46.18% 18304 572 58720 1835 301308 clojure.lang.PersistentList
10 0.75% 46.93% 17568 549 17568 549 308832 java.lang.String[]
11 0.70% 47.62% 16416 2 16416 2 301036 byte[]
Eclipse Memory Analyzer is excellent. Loads the dump file up very very quickly, produces lots of nice reports about the heapdump, lets you query the dump for objects/classes using a SQL-like language. Love it.