You are not logged in.
Pages: 1
Эти опкоды используются в оригинальном SCM, могут иметь один или более параметра, но на самом деле они ничего не делают. Игра просто собирает параметры и переходит к следующему опкоду.
Данный список неполный и будет постепенно пополняться.
Вы можете помочь мне в этом. Для этого достаточно дизассемблировать gta-sa.exe (я пользуюсь IDA Pro 4.3 - чудесная программа, к тому же бесплатная), и найти адрес 0x8A6168.
Там будут записаны адреса 27 процедур, обрабатывающий опкоды (примерно по 100 опкодов на процедуру). После этого можно исследовать опкоды.
Ссылки:
Процедуры
Опкод-пустышка - игра собирает 3 параметра и возвращается обратно в парсер потока.
некоторые полезные адреса
Вот список опкодов-пустышек:
0052: nop 98@ 100@ $TEMPVAR_FLOAT_3 99@ 100@ $TEMPVAR_FLOAT_3 018D: play_sound_at_3D_coord 2181.127 -2251.999 14.0361 reference 65535 handle_as 76@ 0235: nop 0236: nop 02EC: nop 03A7: write_debug_int $CURRENT_WANTED_LIST 03A8: write_debug_float 208@ 03A9: write_debug_newline 03AA: play_suspect_last_seen_at_3D_coord 116@ 117@ $TEMPVAR_FLOAT_3 03AD: nop 0 04E2: UNKNOWN_player $PLAYER_CHAR flag 1 05E9: UNKNOWN_set_vehicle 35@ position_to_end_of_path 152 0596: false // всегда возвращает False 0636: UNKNOWN_AS_nop_parameters 0 0 0 0 0 0 0 0 0 0662: write_debug_message "AAAAAAAAA" 0663: write_debug_intvar "IGFIDX" $GIRLFRIEND 0664: write_debug_floatvar "CHIP_SET_Z" $9387 06AA: unknown_car_check 244@ 06CF: nop 0 0752: unknown_vehicle 244@ 0914: init_external_script 0 (PLAYER_PARACHUTE) 091A: UNKNOWN v$1221 093E: unknown_actor $PLAYER_ACTOR set 0.3001 09D8: unknown_flag 1
Некоторые из этих опкодов могут работать на версиях игры для PS2/XBox (например 0914), но в версии для PC R* по известным им причинам их убрала.
Last edited by Seemann (31-01-2007 05:16)
Offline
Дизассемблировать 14 мб идой надо неимеворное терпение :), уж лучше OllyDbg
---
IDA Pro 5.0.0.879 Advanced Full with SDK, Flair and WinCE Debugger -
[You must login to view hidden text.]
Ссылку спрятал в тег hide.
Last edited by Seemann (15-12-2006 11:40)
Offline
Давайте все же программы/дебаггеры обсуждать в другой теме. Флуд потер.
Постите здесь свои находки, связанные с опкодами-пустышками.
Offline
00490FA0 > \6A 02 PUSH 2 ; Case 5E9 of switch 00490DD5 00490FA2 . 8BCE MOV ECX,ESI 00490FA4 . E8 D730FDFF CALL gta_sa.00464080 00490FA9 . 32C0 XOR AL,AL 00490FAB . E9 FB1A0000 JMP gta_sa.00492AAB
2Seemann:
1. Является ли этот опкод пустышкой?
2. CALL gta_sa.00464080 - что за процедура?
Offline
1. Да.
Мой вариант в IDA (кстати, 5-я версия просто рулезззз, со встроенным дебаггером все стало в разы проще с ней):
.text:00490FA0 .text:00490FA0 _opcode_05E9: ; CODE XREF: _OpcodeSelector_16_05DC_+37j .text:00490FA0 ; DATA XREF: .text:00492AFCo .text:00490FA0 push 2 ; ParamsNumber .text:00490FA2 mov ecx, esi .text:00490FA4 call CollectNumberParams ; P1: Number of params to parse; .text:00490FA9 xor al, al ; Logical Exclusive OR .text:00490FAB jmp _case_opcode_end ; Jump
2.
В ссылке в первом посте написано, да и на моем скриншоте тоже видно.
CALL gta_sa.00464080 - я назвал ее CollectNumberParams. Это процедура, которая собирает в майне параметры опкода. Сколько собирать определяется параметром (push 2 - два параметра).
Она собирает только числовые параметры и переменные (включая массивы).
Еще есть процедура
.text:00463D50 ; int __stdcall GetStringParam(int MoveAddress_ptr,byte MaxStringLength)
Она собирает параметры типа s$, v$, '', "".
2 параметра: куда записывать строку, какой она длины максимум.
Offline
004846EF > \6A 01 PUSH 1 ; Cases 3A7,3A8 of switch 00483BF2 004846F1 . 8BCE MOV ECX,ESI 004846F3 . E8 88F9FDFF CALL gta_sa.00464080 004846F8 . 32C0 XOR AL,AL 004846FA . E9 9C0F0000 JMP gta_sa.0048569B 00490FA0 > \6A 02 PUSH 2 ; Case 5E9 of switch 00490DD5 00490FA2 . 8BCE MOV ECX,ESI 00490FA4 . E8 D730FDFF CALL gta_sa.00464080 00490FA9 . 32C0 XOR AL,AL 00490FAB . E9 FB1A0000 JMP gta_sa.00492AAB 0049289D > \6A 09 PUSH 9 ; Case 636 of switch 00490DD5 0049289F . 8BCE MOV ECX,ESI 004928A1 . E8 DA17FDFF CALL gta_sa.00464080 004928A6 . 32C0 XOR AL,AL 004928A8 . E9 FE010000 JMP gta_sa.00492AAB 0047730C > \6A 02 PUSH 2 ; Case 93E of switch 004762E0 0047730E . 8BCE MOV ECX,ESI 00477310 . E8 6BCDFEFF CALL gta_sa.00464080 00477315 . 32C0 XOR AL,AL 00477317 . 5F POP EDI 00477318 . 5E POP ESI 00477319 . 5B POP EBX 0047731A . 81C4 84000000 ADD ESP,84 00477320 . C2 0400 RETN 4 0047742B > \6A 01 PUSH 1 ; Case 945 of switch 004762E0 0047742D . 8BCE MOV ECX,ESI 0047742F . E8 4CCCFEFF CALL gta_sa.00464080 00477434 . 8B0D 783CA400 MOV ECX,DWORD PTR DS:[A43C78] 0047743A . 69C9 90010000 IMUL ECX,ECX,190 00477440 . 0FB691 E8CEB700 MOVZX EDX,BYTE PTR DS:[ECX+B7CEE8] 00477447 . E9 93070000 JMP gta_sa.00477BDF 0047AC3E > \6A 01 PUSH 1 ; Case 9D8 of switch 0047A787 0047AC40 . 8BCE MOV ECX,ESI 0047AC42 . E8 3994FEFF CALL gta_sa.00464080 0047AC47 . 32C0 XOR AL,AL 0047AC49 . E9 E3120000 JMP gta_sa.0047BF31
2Seemann:
А почему 3AD и 91A пустышки?
0048475A > \6A 01 PUSH 1 ; Case 3AD of switch 00483BF2 0048475C . 8BCE MOV ECX,ESI 0048475E . E8 1DF9FDFF CALL gta_sa.00464080 00484763 . A1 783CA400 MOV EAX,DWORD PTR DS:[A43C78] 00484768 . 85C0 TEST EAX,EAX 0048476A . 74 11 JE SHORT gta_sa.0048477D 0048476C . 6A 01 PUSH 1 0048476E . E8 4DBD2900 CALL gta_sa.007204C0 00484773 . 83C4 04 ADD ESP,4 00484776 . 32C0 XOR AL,AL 00484778 . E9 1E0F0000 JMP gta_sa.0048569B 0048477D > 6A 00 PUSH 0 0048477F . E8 3CBD2900 CALL gta_sa.007204C0 00484784 . 83C4 04 ADD ESP,4 00484787 . 32C0 XOR AL,AL 00484789 . E9 0D0F0000 JMP gta_sa.0048569B 004768D5 > \6A 02 PUSH 2 ; /Arg1 = 00000002; Case 91A of switch 004762E0 004768D7 . 8BCE MOV ECX,ESI ; | 004768D9 . E8 B2DEFEFF CALL gta_sa.00464790 ; \gta_sa.00464790 004768DE . 32C0 XOR AL,AL 004768E0 . 5F POP EDI 004768E1 . 5E POP ESI 004768E2 . 5B POP EBX 004768E3 . 81C4 84000000 ADD ESP,84 004768E9 . C2 0400 RETN 4
Offline
Неплохие находки.
Я только не соглашусь с 0945. Этот опкод рабочий:
.text:0047742B .text:0047742B _opcode_0945: ; DATA XREF: .text:00477D30o .text:0047742B push 1 ; ParamsNumber .text:0047742D mov ecx, esi .text:0047742F call CollectNumberParams ; P1: Number of params to parse; .text:00477434 mov ecx, ds:dwOpcodeParameter1 .text:0047743A imul ecx, 400 ; Signed Multiply .text:00477440 movzx edx, ds:byte_B7CEE8[ecx] ; Move with Zero-Extend .text:00477447 jmp loc_477BDF ; Jump ... .text:00477BDF nop ; No Operation .text:00477BE0 .text:00477BE0 loc_477BE0: ; DATA XREF: sub_156FCA2+16Ar .text:00477BE0 jmp loc_403A72 ; Jump .text:00477BE5 ; --------------------------------------------------------------------------- .text:00477BE5 .text:00477BE5 loc_477BE5: ; CODE XREF: .text:00403A85j .text:00477BE5 ; _OpcodeSelector_24+6DBj ... .text:00477BE5 push 1 ; VariablesCount .text:00477BE7 mov ecx, esi .text:00477BE9 call WriteResult2Variable ; Call Procedure
Если не принимать во внимание loc_403A72 (я хз че там происходит, код какой-то левый), то игра читает массив по адресу B7CEE8 и записывает значение в переменную. Кстати 400 - это размер записи cPlayer. Т.е. например, если переменной хранится 2, это значит что данные игрока начинаются с 800-го байта в записи игроков.
А почему 3AD и 91A пустышки?
03ad;
.text:0048475A _opcode_03AD: ; DATA XREF: .text:00485720o .text:0048475A push 1 ; ParamsNumber .text:0048475C mov ecx, esi .text:0048475E call CollectNumberParams ; P1: Number of params to parse; .text:00484763 mov eax, ds:dwOpcodeParameter1 .text:00484768 test eax, eax ; Logical Compare .text:0048476A jz short loc_48477D ; Jump if Zero (ZF=1) .text:0048476C push 1 .text:0048476E call nullsub_61 ; Call Procedure .text:00484773 add esp, 4 ; Add .text:00484776 xor al, al ; Logical Exclusive OR .text:00484778 jmp _end ; Jump .text:0048477D ; --------------------------------------------------------------------------- .text:0048477D .text:0048477D loc_48477D: ; CODE XREF: OpcodeSelector_10_0384_03E7+B9Aj .text:0048477D push 0 .text:0048477F call nullsub_61 ; Call Procedure .text:00484784 add esp, 4 ; Add .text:00484787 xor al, al ; Logical Exclusive OR .text:00484789 jmp _end ; Jump .text:0048478E ; ---------------------------------------------------------------------------
как видишь, вызывается процедура с параметром-флагом, но сама процедура пустая, только return. IDA такие процедуры метит как nullsub.
091A;
.text:004768D5 _opcode_091A: ; DATA XREF: .text:00477C84o .text:004768D5 push 2 ; VarType .text:004768D7 mov ecx, esi .text:004768D9 call GetVariablePosInVarBlock ; push 1 - localvar; push 2 - global var; .text:004768DE xor al, al ; Logical Exclusive OR .text:004768E0 pop edi .text:004768E1 pop esi .text:004768E2 pop ebx .text:004768E3 add esp, 84h ; Add .text:004768E9 retn 4 ; Return Near from Procedure
а здесь вызывается процедура, которая возвращает смещение до переменной от начала main.scm. Больше ничего.
Кстати, все debug опкоды (0662, например) тоже пустышки.
PS
Если бы я мог, то выложил бы свою базу IDA, в которой описано множество процедур gta-sa.ехе, адресов, структур и пр. Но 120 мегов (15 в архиве) я не потяну.
Offline
2Seemann:
Вот еще нарыл:
0047D099 > \6A 01 PUSH 1 ; Case 18E of switch 0047C108 0047D09B . 8BCE MOV ECX,ESI 0047D09D . E8 DE6FFEFF CALL gta_sa.00464080 0047D0A2 . 32C0 XOR AL,AL 0047D0A4 . 5F POP EDI 0047D0A5 . 5E POP ESI 0047D0A6 . 83C4 7C ADD ESP,7C 0047D0A9 . C2 0400 RETN 4 0048C206 > \6A 02 PUSH 2 ; Case 4E2 of switch 0048B5BB 0048C208 . 8BCE MOV ECX,ESI 0048C20A . E8 717EFDFF CALL gta_sa.00464080 0048C20F . 32C0 XOR AL,AL 0048C211 . E9 290A0000 JMP gta_sa.0048CC3F 00495A7D > \0FB605 81F0B600 MOVZX EAX,BYTE PTR DS:[B6F081] ; Case 68D of switch 00494005 00495A84 . 69C0 38020000 IMUL EAX,EAX,238 00495A8A . 8B88 38F3B600 MOV ECX,DWORD PTR DS:[EAX+B6F338] 00495A90 . 8B90 3CF3B600 MOV EDX,DWORD PTR DS:[EAX+B6F33C] 00495A96 . 8B80 40F3B600 MOV EAX,DWORD PTR DS:[EAX+B6F340] 00495A9C . E9 EE020000 JMP gta_sa.00495D8F 0046E91A > \6A 01 PUSH 1 ; Case 752 of switch 0046D076 0046E91C . 8BCE MOV ECX,ESI 0046E91E . E8 5D57FFFF CALL gta_sa.00464080 0046E923 . 32C0 XOR AL,AL 0046E925 . E9 6E040000 JMP gta_sa.0046ED98
Offline
068D рабочий
.text:00495A7D _opcode_068D: ; CODE XREF: _OpcodeSelector_17+37j .text:00495A7D ; DATA XREF: .text:00495F2Co .text:00495A7D movzx eax, byte ptr ds:@ScreenStruct+59h ; Move with Zero-Extend .text:00495A84 imul eax, 238h ; Signed Multiply .text:00495A8A mov ecx, ds:dword_B6F338[eax] .text:00495A90 mov edx, ds:dword_B6F33C[eax] .text:00495A96 mov eax, ds:dword_B6F340[eax] .text:00495A9C jmp loc_495D8F ; Jump ... .text:00495D8F loc_495D8F: ; CODE XREF: sub_49485A+1242j .text:00495D8F mov ds:dwOpcodeParameter1, ecx .text:00495D95 push 3 ; VariablesCount .text:00495D97 mov ecx, esi .text:00495D99 mov ds:dwOpcodeParameter2, edx .text:00495D9F mov ds:dwOpcodeParameter3, eax .text:00495DA4 call WriteResult2Variable ; Call Procedure
Offline
2Seemann:
068D рабочий
Это я перепутал.
Я просмотрел все блоки вроде больше не нашел.
В конце каждого блока идет несколько опкодов, но их нету в скм.
Offline
В конце каждого блока идет несколько опкодов, но их нету в скм.
Не совсем понял, что конкретно ты имеешь ввиду (кусок кода)?
Offline
Sanchez wrote:В конце каждого блока идет несколько опкодов, но их нету в скм.
Не совсем понял, что конкретно ты имеешь ввиду (кусок кода)?
У меня в ольке показывается так:
Case XXX of switch 00494005
А вконце каждого блока вот так:
Case default XXX XXX XXX XXX of switch 00494005
где XXX опкоды, в разных блоках их разное кол-во, так вот этих самых опкодов нету в скм.
зы лучше ольку скачай и посмотри, она всего 1 мб
Offline
где XXX опкоды, в разных блоках их разное кол-во, так вот этих самых опкодов нету в скм.
Да, понял. Это действительно в таблице опкодов встречаются те, которые либо не поддерживаются либо ничего не делают. Первые ведут на строку
or al, -1
которая делает результат отрицательным, и потом парсер потока прекращает работу;
вторые - на строку
xor al, al
которая обнуляет результат (т.е. опкод выполнен успешно).
Вот твой пример:
.text:00495DDD _opcode17_nop: ; CODE XREF: _OpcodeSelector_17+37j .text:00495DDD ; _OpcodeSelector_17+E9j ... .text:00495DDD xor al, al ; Logical Exclusive OR .text:00495DDF jmp short _exit ; Jump .text:00495DE1 ; --------------------------------------------------------------------------- .text:00495DE1 .text:00495DE1 _opcode17_unsupported: ; CODE XREF: _OpcodeSelector_17+31j .text:00495DE1 ; _OpcodeSelector_17+37j .text:00495DE1 ; DATA XREF: ... .text:00495DE1 or al, -1 ; Logical Inclusive OR
а в таблице
.text:00495E08 dd offset _opcode17_unsupported .text:00495E0C dd offset _opcode17_unsupported .text:00495E10 dd offset loc_4940F3 .text:00495E14 dd offset loc_49415B .text:00495E18 dd offset loc_4941F5 .text:00495E1C dd offset _opcode17_unsupported .text:00495E20 dd offset _opcode17_nop .text:00495E24 dd offset _opcode_064B .text:00495E28 dd offset loc_494323 .text:00495E2C dd offset _opcode17_nop
зы олька некрасивая ида лучше.
Я просмотрел все блоки вроде больше не нашел.
А чтоже опкоды 0662-0664? Они тоже ниче не делают.
Offline
Да то самое, примерно так:
0046ED92 > \32C0 XOR AL,AL ; Cases 711,712,718,71B,71C,71D,720,721,722,725,728,738,739,73A,73D,740,744,748,758,759,764,765,766 of switch 0046D076 0046ED94 . EB 02 JMP SHORT gta_sa.0046ED98 0046ED96 > 0C FF OR AL,0FF ; Default case of switch 0046D076 0046ED98 > 90 NOP 0046ED99 . 90 NOP 0046ED9A .^ E9 0695F9FF JMP gta_sa.004082A5 0046ED9F > 5F POP EDI 0046EDA0 . 5E POP ESI 0046EDA1 . 5D POP EBP 0046EDA2 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX 0046EDA9 . 5B POP EBX 0046EDAA . 81C4 C4000000 ADD ESP,0C4 0046EDB0 . C2 0400 RETN 4
А чтоже опкоды 0662-0664? Они тоже ниче не делают.
Сам же писал
Кстати, все debug опкоды (0662, например) тоже пустышки.
Что в таблицу не занес?
Offline
Pages: 1