Привет Гость!
Ты можешь:
Войти или зарегистрироваться

Забыл пароль
Регистрация
Меню сайта
Главная страница Каталог файлов Всё для моддинга Новости Моды ПК игр Форум Flash игры/журналы Помощь сайту WAP/PDA версия сайта Мы вКонтакте
Категории
Уроки по модификации java [174]
Уроки по переводу java игр [15]
Программы для компьютера [100]
Программы для телефона [82]
Модификация смартфонных игр [15]
Symbian, Android, iPhone и т.д.
Прочее [35]
Уроки по модификации ПК игр [9]
Мини-чат
Главная » Статьи » Уроки по модификации java

04.12.2012, 18:06

Структура class-файла

Первые 4 байта имеют шестнадцатеричное значение 0xCAFEBABE
Следующие 4 байта содержат информацию о версии класса
Потом идут два байта, обозначающие количество записей в константном пуле.
11 типов записей в пуле: Utf8, Integer, Float, Long, Double, Class, String, FieldRef, MethodRef, InterfaceMethodRef, NameAndType.
Записи идут по порядку.
Utf8. Идентификатор для любого типа 1байт, равен 1, длина 2 байта, потом текст в формате java utf8 заданной длины.
Integer. Идентификатор равен 3, значение занимает 4 байта.
Float. Идентификатор равен 4, значение занимает 4 байта.
Long. Идентификатор 5, значение 8 байт.
Double. Идентификатор 6, значение 8байт.
Class. Идентификатор 7, значение 2 байта, является ссылкой на запись в пуле формата Utf8.
String. Идентификатор 8, значение 2 байта, является ссылкой на запись в пуле формата Utf8.
FieldRef. Идентификатор 9, 2 байта ссылка на запись в пуле формата Utf8 (имя переменной), 2 байта ссылка на запись формата Utf8 (дескриптор, т.е.:
I если int
Z если булев (логический)
C если char
J если long
B если byte
F если float
D если double
S если short
Объекты обозначаются так: Lимя_родит._класса; вместе с точкой с запятой
Массивы обозначаются так: [дескриптор, если массив использует несколько измерений, то значок [ повторяется подряд нужное количество раз).
MethodRef. Идентификатор 10, 2байта ссылка на запись в пуле формата Utf8 (имя метода), 2 байта ссылка на запись формата Utf8 (дескриптор, для обозначения типа void используется значок V, для обозначения параметров, типов параметров и результата используется следующая запись: (дескриптор_параметра1дескриптор_параметра2...)дескриптор_результата, например: (ICZ)V означает, что метод возвращает void и запрашивает три параметра типов int, char и логический именно в таком порядке, параметры в скобках дескриптора указываются всегда вплотную, даже если параметр объект).
InterfaceMethodRef. Идентификатор 11, 2 байта ссылка на запись в пуле формата Utf8 (имя метода интерфейса), 2 байта ссылка на запись формата Utf8 (дескриптор метода интерфейса).
NameAndType. Идентификатор 12, 2 байта ссылка на запись в пуле формата Utf8 (имя переменной), 2 байта ссылка на запись формата Utf8 (дескриптор переменной).

Итак, записи я расписал.
Укажу, как считаются количество записей в пуле, длина в Utf8, значения в Integer, Float, Long, Double, а также опишу формат Java Utf8.
Значит, так: чтобы посчитать число из нескольких байтов, нужно прочитать значения этих байтов по порядку и умножать начиная с первого до последнего на 2 в степени (общее_количество_байтов-текущий_номер_байта). Ну и соответственно, полученные результаты от каждого байта складываются, и получается нужное значение. Как считаются знаки вы и так знаете, а как считаются дробные значения, я, к сожалению, не знаю.
Теперь насчет формата Java Utf8. Если значение символа в пределе от 0 до 7f, то кодируется он одним байтом, равным этому значению.
Если значение от 80 до 7ff то кодируется так: берутся последние 5 битов, спереди ставится три бита 110 и значение полученного байта является первым символом этого байта, второй символ строится так: ставится 10, потом первые 6 битов первичного значения.
Если значение символа от 800 до ffff, то запись его состоит из трех байтов: первый- биты 1110 и потом последние 4 бита значения, второй-биты 110 и 5 битов после этих четырех, третий-биты 10 и первые 6битов значения. Если значение символа больше ffff, то есть больше 65535, то этот символ в Java представить невозможно.

Собственно, это было небольшое "лирическое" отступление. Теперь продолжу писать про класс.
Поясню про константный пул: количество записей в пуле равно количеству записей указанному на 9 и 10 байтах минус один, это похоже на массив в Java, но элемент массива с индексом 0 не используется, он зарезервирован, и нумерация начинается с номера 1.
Итак, после пула идут 2 байта обозначающие флаги доступа класса, т.е. public, private, "по умолчанию", а также тип файла: класс или интерфейс. Точные значения я не запоминал, да по-моему это и не нужно вовсе. Кому надо, позже могу предоставить. После флагов идут 2 байта указывающие количество задействованных интерфейсов. Потом вплотную идут записи интерфейсов в количестве указанном, каждая по 2 байта и представляющая из себя ссылку на запись в пуле формата Class (ссылающуюся, в свою очередь, на запись с именем класса интерфейса формата Utf8). После интерфейсов идут 2 байта указывающие количество переменных. Дальше идут записи описывающие переменные в количестве указанном.
Каждая запись переменной выглядит так: 2 байта флаги доступа, 2 байта ссылка на запись в пуле формата Utf8 (имя переменной), 2 байта ссылка на запись формата Utf8(дескриптор), 2 байта количество атрибутов, далее следуют атрибуты в указанном количестве.
Каждый атрибут имеет следующую структуру: 2 байта ссылка на запись в пуле формата Utf8 (имя атрибута), 4 байта длина атрибута, далее данные общим размером в байтах равным указанной длине. По идее, можно использовать сколько угодно атрибутов. Но есть атрибуты уже предопределенные. Для переменных такой один - ConstantValue. У него четкая длина равная 2, а данные представляют из себя ссылку на запись в пуле соответствующего типу переменной формата и содержащую значение константы.
После переменных идут 2 байта указывающие количество методов, а потом записи описывающие методы в указанном количестве. Каждая запись состоит из следующих частей: 2 байта флаги доступа, 2 байта ссылка на запись в пуле формата Utf8 (имя метода), 2 байта ссылка на запись формата Utf8 (дескриптор метода), 2 байта количество атрибутов, далее идут атрибуты в указанном количестве. Для методов есть только один предопределенный атрибут-Code. Этот атрибут обязательный, кстати больше обязательных атрибутов нет.
Атрибут Code выглядит следующим образом: 2 байта ссылка на запись в пуле формата Utf8 (имя атрибута), 4байта длина атрибута, 2 байта максимальное количество данных в стеке, 2 байта максимальное количество локальных переменных, 2 байта количество байтов в коде, тут будут байты кода в указанном количестве, 2 байта количество конструкций try-catch, ловушек для ошибок, тут записи конструкций try-catch, ловушек ошибок, каждая запись занимает 8 байт, первые 2 байта это номер байта в коде от которого начинается try, следующие 2 байта указывают номер байта в коде до которого распространяется действие try, потом 2 байта указывающие номер байта в коде с которого начинается catch, последние 2 байта являются ссылкой на запись в пуле формата Class (ссылающегося, в свою очередь, на Utf8 имя класса представляющего ошибку), после записей ловушек ошибок следуют 2 байта указывающие количество атрибутов, а далее, соответственно, атрибуты в указанном количестве.
Стандартные атрибуты атрибута Code это Exceptions, LineNumberTable, LocalVariableTable. Я сомневаюсь что вам понадобятся параметры этих атрибутов, так как они относятся к типу debugging info, но если надо, я их скажу. После методов идут 2 байта указывающие количество атрибутов всего класса, далее следуют атрибуты в указанном количестве. У класса всего один предопределенный атрибут - SourceFile. Он относится к типу debugging info. Структура этого атрибута такова: 2 байта ссылка на запись в пуле формата Utf8 (имя атрибута), 4 байта длина (постоянная, равна 2), далее байты данных в указанном количестве байтов, т.е. 2 байта, ссылающиеся на запись в пуле формата Utf8 (имя исходного файла).

Теперь распишу коды в Code.
В языке JVM 256 мнемонических команд. Они занумерованы от 0 до 255, номер команды называется кодом операции. 3 кода зарезервированы, это коды 202(breakpoint), 254 (impdep1), 255(impdep2).
Операции бывают обычными и quick. Код операции занимает один байт, после кода может быть от 0 до 4 байт данных, т.е. операции могут быть без параметров, с одним параметром или с двумя параметрами. На каждый параметр может быть выделено 1-4 байтов. Операции в коде нумеруются от начала в виде количества байтов до нее. Первая операция имеет номер в коде равный 0. При выполнении операций с переходом на другую строку, например goto, в виде параметра используется номер нужной строки.
Короче так, команды работают со стеком и операнды команды должны быть подряд и последними в стеке. Неявного преобразования типов уже нет. Логический тип как и во всех ассемблерах, а также char, byte и short входят в int. Итого 5 типов: int, float, long, double и объекты. Есть еще некоторые, но они в вычислениях не используются. Операции с числами это add, sub, mul, div соответственно сложение, вычитание, умножение, деление. Сама мнемочиская команда составляется из первой буквы имени типа и имени операции. Опкод будете смотреть в табличке. Эти операции не содержат операндов, берут последние два значения из стека и оставляют вместо них результат. Занимают один байт в коде. Преобразование типов осуществляется с помощью команд типа тип2тип (смотреть в таблице). Тут уже поддерживаются типы byte, boolean, short, char. Типы byte и логический обозначаются как и все - первой буквой имени (b).
В классах используются только обычные опкоды, _quick опкоды - это трансформированные обычные, они работают быстрее, но в классе они появиться не могут, их создает только ява машина. Одним словом, зарезервированные и _quick опкоды в реальном и работающем классе никогда не бывают.
invokespecial используется только для вызова методов инициализации класса (, в коде это конструктор класса) и интерфейса (). Операнд команды занимает два байта и обозначает ссылку (запись в константном пуле) на нужный метод. Для вызова обычных методов используется команда invokevirtual. Все так же. Параметры метода берутся подряд из конца стека.

Opcodes:
Обычные операции:

0 nop
1 aconst_null
2 iconst_m1
3 iconst_0
4 iconst_1
5 iconst_2
6 iconst_3
7 iconst_4
8 iconst_5
9 lconst_0
10 lconst_1
11 fconst_0
12 fconst_1
13 fconst_2
14 dconst_0
15 dconst_1
16 bipush
17 sipush
18 ldc
19 ldc_w
20 ldc2_w
21 iload
22 lload
23 fload
24 dload
25 aload
26 iload_0
27 iload_1
28 iload_2
29 iload_3
30 lload_0
31 lload_1
32 lload_2
33 lload_3
34 fload_0
35 fload_1
36 fload_2
37 fload_3
39 dload_1
40 dload_2
41 dload_3
42 aload_0
43 aload_1
44 aload_2
45 aload_3
46 iaload
47 laload
48 faload
49 daload
50 aaload
51 baload
52 caload
53 saload
54 istore
55 lstore
56 fstore
57 dstore
58 astore
59 istore_0
60 istore_1
61 istore_2
62 istore_3
63 lstore_0
64 lstore_1
65 lstore_2
66 lstore_3
67 fstore_0
68 fstore_1
69 fstore_2
70 fstore_3
71 dstore_0
72 dstore_1
73 dstore_2
74 dstore_3
75 astore_0
76 astore_1
77 astore_2
78 astore_3
79 iastore
80 lastore
81 fastore
82 dastore
83 aastore
84 bastore
85 castore
86 sastore
87 pop
88 pop2
89 dup
90 dup_x1
91 dup_x2
92 dup2
93 dup2_x1
94 dup2_x2
95 swap
96 iadd
97 ladd
98 fadd
99 dadd
100 isub
101 lsub
102 fsub
103 dsub
104 imul
105 lmul
106 fmul
107 dmul
108 idiv
109 ldiv
100 fdiv
111 ddiv
112 irem
113 lrem
114 frem
115 drem
116 ineg
117 lneg
118 fneg
119 dneg
120 ishl
121 lshl
122 ishr
123 lshr
124 iushr
125 lushr
126 iand
127 land
128 ior
129 lor
130 ixor
131 lxor
132 iinc
133 i2l
134 i2f
135 i2d
136 l2i
137 l2f
138 l2d
139 f2i
140 f2l
141 f2d
142 d2i
143 d2l
144 d2f
145 i2b
146 i2c
147 i2s
148 lcmp
149 fcmpl
150 fcmpg
151 dcmpl
152 dcmpg
153 ifeq
154 ifne
155 iflt
156 ifge
157 ifgt
158 ifle
159 if_icmpeq
160 if_icmpne
161 if_icmplt
162 if_icmpge
163 if_icmpgt
164 if_icmple
165 if_acmpeq
166 if_acmpne
167 goto
168 jsr
169 ret
170 tableswitch
171 lookupswitch
172 ireturn
173 lreturn
174 freturn
175 dreturn
176 areturn
177 return
178 getstatic
179 putstatic
180 getfield
181 putfield
182 invokevirtual
183 invokespecial
184 invokestatic
185 invokeinterface
186 xxxunusedxxx
187 new
188 newarray
189 anewarray
190 arraylength
191 athrow
192 checkcast
193 instanceof
194 monitorenter
195 monitorexit
196 wide
197 multianewarray
198 ifnull
199 ifnonnull
200 goto_w
201 jsr_w

_quick операции:

203 ldc_quick
204 ldc_w_quick
205 ldc2_w_quick
206 getfield_quick
207 putfield_quick
208 getfield2_quick
209 putfield2_quick
210 getstatic_quick
211 putstatic_quick
212 getstatic2_quick
213 putstatic2_quick
214 invokevirtual_quick
215 invokenonvirtual_quick
216 invokesuper_quick
217 invokestatic_quick
218 invokeinterface_quick
219 invokevirtualobject_quick
221 new_quick
222 anewarray_quick
223 multianewarray_quick
224 checkcast_quick
225 instanceof_quick
226 invokevirtual_quick_w
227 getfield_quick_w
228 putfield_quick_w

Зарезервированные операции:

202 breakpoint
254 impdep1
255 impdep2

Автор: Тимерша (s-c)
FAQ by aNNiMON
Категория: Уроки по модификации java | Добавил: Tommy_M
Просмотров: 3145 | Комментарии: 9 | Рейтинг: 5.0/1

Всего комментариев: 9
Спам
HapyTo-05   (14.12.2012 20:03)
sevas, меньше да, а больше не пробовал, лень :D

Спам
sevas   (14.12.2012 17:03)
нухчик, а больше пушек получалось?Но декомплировать не удобно как-то.

Спам
Werewolf   (06.12.2012 18:03)
sevas, теперь понял

Спам
Werewolf   (06.12.2012 18:01)
sevas, wtf?
открыть через джава байт
или Java bite

Спам
HapyTo-05   (05.12.2012 18:46)
оружия :D

Спам
HapyTo-05   (05.12.2012 18:45)
sevas, поковыряйся в классах au,e,i, я их декомпилировал, там в одном из них есть все оружия. Я смог сделать чтоб в игре было всего 2 оружия. Я удолял все строки которые связаны ну например с узи. Думаю можно также добавить орудия.

Спам
sevas   (05.12.2012 12:17)
_ReVeS_, а я часть,я ведь через джава байт модил классы л2д.Например чтоб у каждого оружия сделать разные эффекты выстрелаа,надо сделать в опции utf8 4 строки название типа как \fire2.png ,\fire3.png и так далее.По идее чтоб выбрать для оружия эффект надо выбрать для него string строку,но написать напрямую путь нельзя.Поэтому я создовал utf8 строки,а патом string строки создовал,но так нельзя напрямую текст писать поэтому надо выбирать строки с функцией utf8.

Спам
WEBB   (04.12.2012 21:53)
_ReVeS_, я тож

Спам
Werewolf   (04.12.2012 19:21)
%) ни чё непонял

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

о, привет
Новинки
  • Файлы
  • Статьи
  • Новости

Quantum 3.0
Комментов: 65 | Загрузок: 204
{Crutches} Bloody Friday
Комментов: 1 | Загрузок: 22
Temple Run
Комментов: 0 | Загрузок: 39
Fruit Ninja
Комментов: 0 | Загрузок: 17
Talking Tom
Комментов: 0 | Загрузок: 31
SILENT EVIL 3D v.1.4 Beta (Обнова 12.08.2018)
Комментов: 51 | Загрузок: 318
Gish Ultimate
Комментов: 0 | Загрузок: 31
Help Me
Комментов: 1 | Загрузок: 30
Resident Evil: Raccoon City
Комментов: 4 | Загрузок: 61
Darkest Fear 3D [Alpha]
Комментов: 11 | Загрузок: 61

БЫСТРАЯ НАВИГАЦИЯ ПО САЙТУ
Комментов: 3 | Просмотров: 2701
Работа с EMG Studio
Комментов: 9 | Просмотров: 4059
J2ME Loader - 1.2.5.1 (эмулятор Java на Android)
Комментов: 2 | Просмотров: 2131
M3G to OBJ Converter + Lang Editor
Комментов: 2 | Просмотров: 855
Исходный код Gish Reloaded
Комментов: 2 | Просмотров: 1894
Моды Minecraft PE
Комментов: 0 | Просмотров: 1505
Оптимизация графики
Комментов: 5 | Просмотров: 2595

Неизданное (JAVA)
Комментов: 10 | Просмотров: 431
Splatterhouse: Cry & Fear
Комментов: 15 | Просмотров: 316
КОНКУРС МОДОВ 2018
Комментов: 3 | Просмотров: 369
Old Gameloft games
Комментов: 0 | Просмотров: 462
С наступающим короч)
Комментов: 1 | Просмотров: 734
Silent Evil - что же с релизом?
Комментов: 5 | Просмотров: 625
Alien Shooter на телефон! |Java| (Полное прохождение)
Комментов: 0 | Просмотров: 660
Случайный мод
Моды на Galaxy On Fire 2
10124 24 3.9
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Пользователи
Гости сайта

[ Нас сегодня посетили ]
При копировании материалов, желательно оставлять ссылку на этот сайт!
© Tommy_M 2009-2018 | Хостинг от uCoz