Перейти к содержанию

Darksiders 2 Как Сделать Правильное Вычитание


Рекомендуемые сообщения

Есть инструкция которая срабатывает на запись, я хочу что бы при каждом ударе отнималось 150. То есть как загрузить в FPU стек свое значение чтобы оно корректно отнималось? Сам скрипт 

[ENABLE]alloc(newmem,2048)label(returnhere)label(originalcode)label(subst)label(exit)newmem:subst:dd (float)150originalcode:fsub dword ptr [subst] //так не работаетfstp dword ptr [eax] //инструкция срабатывающая на запись жизней противника push esi //оригинальный кодmov ecx,edi //оригинальный кодexit:jmp returnhere"Darksiders2.exe"+3B7857:jmp newmemreturnhere: [DISABLE]dealloc(newmem)"Darksiders2.exe"+3B7857:fstp dword ptr [eax]push esimov ecx,edi

Вот так отнимает единицу, а как сделать свое произвольное значение?

[ENABLE]alloc(newmem,2048)label(returnhere)label(originalcode)abel(exit)newmem:originalcode:fstp ST(0) fld dword ptr [eax] fld1 fsubp fstp dword ptr [eax]push esimov ecx,ediexit:jmp returnhere"Darksiders2.exe"+3B7857:jmp newmemreturnhere: [DISABLE]dealloc(newmem)"Darksiders2.exe"+3B7857:fstp dword ptr [eax]push esimov ecx,edi

Если просто написать

fstp dword ptr [eax] 

sub dword ptr [eax] ,(float)150

то жизни противников превращаются в  2.54846917E-35.

Изменено пользователем lamalamaz
Ссылка на комментарий
Поделиться на другие сайты

Как минимум

dd (float)150

находится в исполняемом коде. Нужно вынести, например так

newmem:originalcode:fsub dword ptr [subst] fstp dword ptr [eax] push esimov ecx,ediexit:jmp returnheresubst:dd (float)150"Darksiders2.exe"+3B7857:jmp newmemreturnhere:
Ссылка на комментарий
Поделиться на другие сайты

 

Как минимум

dd (float)150

находится в исполняемом коде. Нужно вынести, например так

newmem:originalcode:fsub dword ptr [subst] fstp dword ptr [eax] push esimov ecx,ediexit:jmp returnheresubst:dd (float)150"Darksiders2.exe"+3B7857:jmp newmemreturnhere:

 

 

Спасибо, так вроде работает. Не знаете ли где можно почитать подробнее про операции с FPU регистрами и командами на примере игр. Просто все что находится в Гугле очень обширно и мало интересно. А вот конкретные примеры с играми очень пригодились бы для полного понимания как правильно использовать команды сопроцессора.

Ссылка на комментарий
Поделиться на другие сайты

>>Не знаете ли где можно почитать подробнее про операции с FPU регистрами и командами на примере игр
 
Я думаю, что нигде. Приложив усилий надо немного понять ассемблер по работе с fpu числами. Найти в Интернете справочник по FPU инструкциям, найти базовые объяснения как и что. Сложение, вычитание, умножение, деление, запись, чтение, выталкивание из стека fpu, добавление в стек fpu, преобразования из одного типа в другой, понимание смены состояния флагов при операциях с fpu (иногда флаги меняются, а игра это может неправильно понять). Вот и все.
 
Один из туторов по асму из справки по Cheat Engine с некоторыми инструкциями FPU (в разделе туторов по асму):

 

 

Hope thats explanatory enough :)

 
 
Before I show an example or two, lets talk about Stacks. What are they?
 
 
 
STACKS
======
 
 
Well a stack is used for a temporary location for values, a game or application may
want to use a register for something else but want to keep the previous value for
future reference, so the program will PUSH a value onto the stack for later
retrieval.
 
 
The stack is 8 small stacks in the 1, so look at it as a small filing
cabinet in a way. Any of these values can be retrieved by calling for the stack and
its position, like the following
 
 
st(0) - always the top of the stack
st(1) - next after top
st(2) - 2nd from the top
..
st(7) - Bottom of the stack
 
 
So when you want to get a value you can if you know where it is stored, it does
become a little complicated if you keep PUSH'ing values to the top of the stack as
the previous value is moved down 1. So to take a value we just POP it back.
 
 
So remember
 
PUSH - Places a value on a stack
POP  - Removes a value from the stack
 
 
But those opcodes are handy for integer values, what about floats?
 
 
The next section will show you.
 
 
 
FLOAT EXAMPLES
==============
 
 
 
OK how to PUSH and POP values from the stack, its not difficult, heres a few
examples :)
 
 
Example 1
 
Say we have a value in a known address which is a REAL value (so float) and want
to add a value to it? For arguments sake lets say the register EAX contains the
address 450000h which contains money in a game and we want to add a value from
revenue which resides in an address contained in register EBX at 450008h and
then send back to the original address?
 
 
Here is how
 
 
FLD [eax]   - This opcode PUSH's the value at the address 450000h contained in
              EAX and pushes it to the top of the stack
 
FADD [ebx]  - This then adds the value at the address 450008h contained in EBX
              with the value at the top of the stack, then replaces the value
              at the top of the stack with the new value from the FADD opcode.
 
FSTP [eax]  - This then POP's the value on top of the stack to the address 450000h
              contained in the register EAX, where your old money value was and
              replaces with new one.
 
 
 
Example 2
 
Say now we want to calculate a Health Points value after taking damage, but wait!
The damage is a float value but health is integer O_O So how does this work out??
Its not difficult ill show you how :) Again we will use the last registers for
this example, EAX (450000h) contains our Health integer value and and EBX (450008h)
contains our damage float value.
 
 
Here it is
 
 
FILD (EAX)  - This opcode PUSH's an integer value to the top of the stack from the
              address 450000h contained in EAX.
 
FSUB (EBX)  - This subtracts the value at address 450008h (float) contained in EBX
              from the value at the top of the stack.
 
FISTP (EAX) - This opcode POP's an integer value from the the top of the stack to
              the address 450000h contained in EAX. If the REAL value was 1.50 or
              higher it will send as an integer of 2, if 1.49 or lower then it will
              send as 1.
 
 
Great huh :) See its not that difficult to understand :)
 
 
 
Example 3
 
This one is a toughy, we have a game but one of the addresses in the EAX register is
needed for later on, but we also need the EAX register to work out a new ammo value,
and no other register is free to send the address to, omg what to do what to do!!
 
Dont worry, believe in the stacks :) The following will contain POP and PUSH command :)
 
So for this example, EAX contains the value 800000h, the ammo value is contained
at the address 450000h and the EBX contains the address 450008h which contains the
either positive or negative number to be added to the ammo amount, if negative a shot
was fired, if positive then a reload of the weapon or ammo picked up.
 
 
PUSH EAX         - This opcode PUSH's the value of EAX (notice without the [ ] it moves
                   the value in EAX to the stack but if it had the [ ] it would move
                   the value contained at the address of the value in EAX). In this
                   case 800000h is PUSH'd on top of the stack.
 
MOV EAX, 450000h - This opcode moves the value 450000h into the register EAX, which
                   replaces the old 800000h value.
 
FILD [EAX]       - This opcode as you know will PUSH the value at the address contained
                   in the register EAX, see the difference its using the [ ] so the
                   game will look at the address 450000h and take the value there, and
                   the PUSH to the top of the stack.
 
FADD [EBX]       - This again is self explanatory now, it adds the value at address
                   450008h with the value on the stack, if it was a negative number it
                   will decrease the value, if positive increase it, just basic maths :)
 
FISTP [EAX]      - Again this POP's an integer value from top of stack to the memory
                   location contained in EAX, which is 450000h.
 
CALL 46AEFF      - What the hell is this??? I hear you say, wait a bit ill tell you
                   just after :)
 
POP EAX          - This opcode POP's the original 800000h back into the register EAX, so
                   the game hasnt lost that value.
 
 
OK, the CALL opcode, its a handy opcode for the fact that if your program or game uses
a routine to work out something but is always used it would be messy code if we were to
keep manually typing it out not to mention a much bigger file.
 
 
The CALL opcode, calls the opcodes at a certain address to work out the same function
it does later on, so you only need to have that 1 set of opcodes for the entire program
or game, you just CALL it, saves time and space.
 
 
At the end of these opcodes from a CALL will be an opcode call RET (return) it will make
the program or game go back to where it left off, in this case to the POP EAX opcode


 

Ссылка на комментарий
Поделиться на другие сайты

Спасибо MasterGH! Замечательный тутор, все понятно и доступно рассказано. Про справку в самом Cheat engine как раз и забыл....

Изменено пользователем lamalamaz
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.