lamalamaz Опубликовано 20 октября, 2014 Поделиться Опубликовано 20 октября, 2014 (изменено) Есть инструкция которая срабатывает на запись, я хочу что бы при каждом ударе отнималось 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. Изменено 20 октября, 2014 пользователем lamalamaz Ссылка на комментарий Поделиться на другие сайты Поделиться
A1t0r Опубликовано 20 октября, 2014 Поделиться Опубликовано 20 октября, 2014 Как минимум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: Ссылка на комментарий Поделиться на другие сайты Поделиться
lamalamaz Опубликовано 20 октября, 2014 Автор Поделиться Опубликовано 20 октября, 2014 В 20.10.2014 в 18:56, A1t0r сказал: Как минимум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 регистрами и командами на примере игр. Просто все что находится в Гугле очень обширно и мало интересно. А вот конкретные примеры с играми очень пригодились бы для полного понимания как правильно использовать команды сопроцессора. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 20 октября, 2014 Поделиться Опубликовано 20 октября, 2014 >>Не знаете ли где можно почитать подробнее про операции с 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 maywant to use a register for something else but want to keep the previous value forfuture reference, so the program will PUSH a value onto the stack for laterretrieval. The stack is 8 small stacks in the 1, so look at it as a small filingcabinet in a way. Any of these values can be retrieved by calling for the stack andits position, like the following st(0) - always the top of the stackst(1) - next after topst(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 doesbecome a little complicated if you keep PUSH'ing values to the top of the stack asthe previous value is moved down 1. So to take a value we just POP it back. So remember PUSH - Places a value on a stackPOP - 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 fewexamples Example 1 Say we have a value in a known address which is a REAL value (so float) and wantto add a value to it? For arguments sake lets say the register EAX contains theaddress 450000h which contains money in a game and we want to add a value fromrevenue which resides in an address contained in register EBX at 450008h andthen 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 So how does this work out??Its not difficult ill show you how Again we will use the last registers forthis 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 isneeded 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 containedat the address 450000h and the EBX contains the address 450008h which contains theeither positive or negative number to be added to the ammo amount, if negative a shotwas 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 usesa routine to work out something but is always used it would be messy code if we were tokeep 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 functionit does later on, so you only need to have that 1 set of opcodes for the entire programor 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 makethe program or game go back to where it left off, in this case to the POP EAX opcode Ссылка на комментарий Поделиться на другие сайты Поделиться
lamalamaz Опубликовано 21 октября, 2014 Автор Поделиться Опубликовано 21 октября, 2014 (изменено) Спасибо MasterGH! Замечательный тутор, все понятно и доступно рассказано. Про справку в самом Cheat engine как раз и забыл.... Изменено 21 октября, 2014 пользователем lamalamaz Ссылка на комментарий Поделиться на другие сайты Поделиться
A1t0r Опубликовано 21 октября, 2014 Поделиться Опубликовано 21 октября, 2014 Я пользуюсь этим справочником. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения