#1 06-11-2010 00:33

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Вызов процедуры, код которой прописан в скрипте

Хотел поставить эксперимент: скопировал код процедуры _cheatSpawnRhino в скрипт (см.ниже) и попытался исполнить этот код с помощью 0AA5, однако при этом игра вылетела. В чём причина?

{$CLEO}
0AC6: 0@ = label @SPAWN_RHINO offset
while true
    wait 0
    if
        not player.Defined($player_char)
    then
        continue
    end
    if
        0AB0: key_pressed 220    //         \
    then
        0AA5: call 0@ num_params 0 pop 0
    end
end

:SPAWN_RHINO
hex
    68 B0 01 00 00         // push 1B0h
    E8 06 FC FF FF         // call _spawnCarAtPlayerLocation
    59                     // pop ecx
    C3                     // retn
end

Offline

#2 06-11-2010 21:33

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Вызов процедуры, код которой прописан в скрипте

В exe при вызове процедур используются локальные смещения относительно текущего адреса. Грубо говоря, вызывается не call 0x454654 а call -12.

E8 06 FC FF FF

Поэтому скопированный в другое место call будет указывать не на процедуру, а в другое место.

Чтобы избежать этого нужно адрес вызываемой в ехе функции записать в регистр, например eax, и вызвать call eax.

http://sannybuilder.com/forums/viewtopi … d=166#p166
http://sannybuilder.com/forums/viewtopi … d=369#p369

Offline

#3 06-11-2010 23:59

Den_spb
From: Ленинград
Registered: 23-11-2008
Posts: 941
Website

Re: Вызов процедуры, код которой прописан в скрипте

Спасибо, разобрался. Исправленный код выглядит так:

{$CLEO
0AC6: 0@ = label @SPAWN_RHINO offset
while true
    wait 0
    if
        not player.Defined($player_char)
    then
        continue
    end
    if
        0AB0: key_pressed 220    //         \
    then
        0AA5: call 0@ num_params 0 pop 0
    end
end

:SPAWN_RHINO
hex
    68 B0 01 00 00         // push 1B0h
    B8 B0 A0 43 00         // mov  eax, 0x43A0B0 (_spawnCarAtPlayerLocation)
    FF D0                  // call eax
    59                     // pop ecx
    C3                     // retn
end

Второй вариант - без использования регистра, но более громоздкий:

{$CLEO}
0AC6: 1@ = label @SPAWN_RHINO offset
1@ += 10  // оффсет команды pop ecx
1@ *= -1
1@ += 0x43A0B0   // находим смещение между командой вызова и процедурой
0AC6: 0@ = label @SPAWN_RHINO offset
0@ += 6
0A8C: write_memory 0@ size 4 value 1@ virtual_protect 1  // записываем смещение в команду
0@ -= 6 
while true
    wait 0
    if
        not player.Defined($player_char)
    then
        continue
    end
    if
        0AB0: key_pressed 220    //         \
    then
        0AA5: call 0@ num_params 0 pop 0
    end
end

:SPAWN_RHINO
hex
    68 B0 01 00 00         // push 1B0h
    E8 00 00 00 00         // call 1@
    59                     // pop ecx
    C3                     // retn
end

Offline

#4 08-11-2010 00:16

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Вызов процедуры, код которой прописан в скрипте

1@ += 10  // оффсет команды pop ecx
1@ *= -1
1@ += 0x43A0B0   // находим смещение между командой вызова и процедурой

путем несложных математических операций я свернул эти 3 команды в одну:

0A8F: 1@ = 0x43A0A6 - 1@

Offline

Board footer

Powered by FluxBB