aliast Опубликовано 29 ноября, 2012 Поделиться Опубликовано 29 ноября, 2012 Есть такая пошаговая стратегия Panzer General. Вот скрипт для максимального числа юнитов: Показать контент [ENABLE]//code from here to '[DISABLE]' will be used to enable the cheatalloc(newmem,2048) //2kb should be enoughlabel(cycle)label(returnhere)label(originalcode)label(exit)registersymbol(ZeroAddress)label(ZeroAddress)label(cycle)label(restore)createthread(newmem)newmem: //this is allocated memory, you have read,write,execute access//place your code herecmp edi,DAA54 //start unit's listjne originalcodepush edipush ebxmov [ZeroAddress],ecxadd edi,1B //1st unit countcycle:mov ebx,[ZeroAddress]add ebx,edicmp [ebx],0 //unit exists?je restoremov byte ptr [ebx],#30 //max countadd edi,58 //next unit countpush #1000call sleepjmp cyclerestore:pop ebxpop edioriginalcode:movzx eax,byte ptr [eax+ecx]retexit:jmp returnhereZeroAddress:dd 0"FreeDOCore.dll"+1D4D0:jmp newmemreturnhere:[DISABLE]//code from here till the end of the code will be used to disable the cheat"FreeDOCore.dll"+1D4D0:movzx eax,byte ptr [eax+ecx]retdealloc(newmem)unregistersymbol(ZeroAddress)//Alt: db 0F B6 04 08 C3К сожалению данный скрипт срабатывает только один раз при выборе первого юнита в отряде, если писать его без потока. С потоком насколько я понимаю скрипт срабатывает N раз, где N - число юнитов на карте, а потом один хрен работать перестаёт и никакого бессмертия не выходит. И кстати, пока поток повторяется игра зависает... Можно ли как-то переписать скрипт, чтобы он срабатывал без выхода и не завешивал игру? Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 29 ноября, 2012 Поделиться Опубликовано 29 ноября, 2012 поток пристыковывай не к newmem, ибо туда идет прыжок с оригинальной инструкции, а создай отдельную выделенную память. А еще у тебя получается, игра входит в новую память, и пока всех юнитов не переберет - не успокоится, ибо у тебя цикл выполняется в основном потоке игры, так как прыжок на newmem идет из него. И только потом возвращается в оригинальный код. Точнее по работе с потоками в СЕ тебе Андрей расскажет. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 29 ноября, 2012 Поделиться Опубликовано 29 ноября, 2012 1) От потоков, которые работают по циклу даже с задержкой лучше отказываться. Сулит тормозами и вылетами из игры (особенно без проверок адресов есть ли доступ на чтения и запись)2) Новый поток можно и нужно создавать в отдельной выделенной памяти. Два потока на одном блоке кода выполняться не могут. Они будут ждать друг друга пока один не выйден из блока кода. Тоже самое касается чтения данных в одной области. К сожалению, я не помню размеры этих областей. Эти и другие тонкости должны быть у Рихтера в его мемуарах или MSDN.Короче.Тебе нужно не использовать новый поток, а найти часто работающую инструкцию, которая позволила бы записать здоровье всем твоим юнитам или же не позволила наносить урон от юнита, который принадлежит противнику.Речь идёт о "Panzer General III - Scorched Earth" (от 2000го года)? Ссылка на комментарий Поделиться на другие сайты Поделиться
aliast Опубликовано 29 ноября, 2012 Автор Поделиться Опубликовано 29 ноября, 2012 Речь вообще шла о первом Панзере, выходившем на приставке Panasonic 3DO в 96 году. Возможно следовало создать тему в разделе о приставках, но вопрос был про потоки, создал тут) Теперь сомнения одолели, возможно в эмуляторе эти потоки работают не так, как в PC-играх? Ну и в эмуле все события в игре обрабатываются одной инструкцией, что в общем то логично для эмулятора...Такой скрипт крашит игру: Показать контент [ENABLE]//code from here to '[DISABLE]' will be used to enable the cheatalloc(newmem,256) //2kb should be enoughalloc(thread,256)createthread(thread)label(cycle)label(returnhere)label(originalcode)label(exit)registersymbol(ZeroAddress)label(ZeroAddress)label(restore)newmem: //this is allocated memory, you have read,write,execute access//place your code herecmp edi,DAA54 //start unit's listjne originalcodepush edipush ebxthread:mov [ZeroAddress],ecxadd edi,1B //1st unit countcycle:mov ebx,[ZeroAddress]add ebx,edicmp [ebx],0 //unit exists?je restoremov byte ptr [ebx],#30 //max countadd edi,58 //next unit countjmp cyclerestore:pop ebxpop edipush #1000call sleepjmp threadoriginalcode:movzx eax,byte ptr [eax+ecx]retexit:jmp returnhereZeroAddress:dd 0"FreeDOCore.dll"+1D4D0:jmp newmemreturnhere:[DISABLE]//code from here till the end of the code will be used to disable the cheat"FreeDOCore.dll"+1D4D0:movzx eax,byte ptr [eax+ecx]retdealloc(newmem)dealloc(thread)unregistersymbol(ZeroAddress)//Alt: db 0F B6 04 08 C3Здесь метка cycle никак не влияет на поток thread, не обрывает его? Ссылка на комментарий Поделиться на другие сайты Поделиться
Coder Опубликовано 29 ноября, 2012 Поделиться Опубликовано 29 ноября, 2012 А ещё проще заинжетить DLL.И там уже сделать поток, и в нём, что типо этого.for (;;Sleep(50)){ DWORD* health_addr = ..... DWORD* team_id = ... if (*team_id == 0) // 0 - id твоей команды *health_addr = 100;} Ссылка на комментарий Поделиться на другие сайты Поделиться
aliast Опубликовано 29 ноября, 2012 Автор Поделиться Опубликовано 29 ноября, 2012 Ну да, про DLL тоже была мысль. Но потом решил накатать по быстрому ассемблерный скрипт (как-то им чаще пользуюсь, чем C++) и на удивление с первой попытки без ошибок прописал всем своим юнитам максимум рекрутов. Обрадовался, но радость оказалась преждевременной - чит сработал один раз и никаких значений не заморозил, обидно.. а мне ещё хотелось чит "бесконечный ход", а тут уже одноразовым читом никак не отделаться, нужна заморозка... надо будет попробовать DLL.Как тут правильно написать? По адресу [[FREEDOCORE.DLL+28370]+0xDAA54] находится имя юнита, а вовсе не указатель на класс. Поэтому в классе поставил char skip[0xDAA54] - а как по другому написать? Показать контент DWORD WINAPI Panzer_thread( LPVOID ){Unit* localUnit = NULL;DWORD old_protect = 0;CreateConsole();DWORD ZeroAddress = (DWORD)GetModuleHandle(L"FreeDOCore.dll") + 0x28370; // нулевой адрес эмулятора//DWORD pZeroAddress = *(DWORD*)ZeroAddress;//DWORD Unit = pZeroAddress + 0xDAA54; // наш класс Unitif (HIWORD ( ZeroAddress ) ){ //printf("ZeroAddress = 0x%X\n", pZeroAddress); //printf("pUnit = 0x%X\n", Unit); int offsets[1] = { 0x0 }; int* locUnit = ReadPointer(ZeroAddress, offsets, 1); printf("locUnit = 0x%X\n", locUnit); localUnit = Unit::Singleton(locUnit); // создаём экземляр игрового класса, но с одним и тем же адресом printf("UnitName = %s\n", localUnit->UnitName); //вместо имени выводится пустая строка ошибочка...}class Unit{public:char skip[0xDAA54];char UnitName[12];...}; Ссылка на комментарий Поделиться на другие сайты Поделиться
Coder Опубликовано 30 ноября, 2012 Поделиться Опубликовано 30 ноября, 2012 В 29.11.2012 в 19:24, aliast сказал: Ну да, про DLL тоже была мысль. Но потом решил накатать по быстрому ассемблерный скрипт (как-то им чаще пользуюсь, чем C++) и на удивление с первой попытки без ошибок прописал всем своим юнитам максимум рекрутов. Обрадовался, но радость оказалась преждевременной - чит сработал один раз и никаких значений не заморозил, обидно.. а мне ещё хотелось чит "бесконечный ход", а тут уже одноразовым читом никак не отделаться, нужна заморозка... надо будет попробовать DLL.Как тут правильно написать? По адресу [[FREEDOCORE.DLL+28370]+0xDAA54] находится имя юнита, а вовсе не указатель на класс. Поэтому в классе поставил char skip[0xDAA54] - а как по другому написать? Показать контент DWORD WINAPI Panzer_thread( LPVOID ){Unit* localUnit = NULL;DWORD old_protect = 0;CreateConsole();DWORD ZeroAddress = (DWORD)GetModuleHandle(L"FreeDOCore.dll") + 0x28370; // нулевой адрес эмулятора//DWORD pZeroAddress = *(DWORD*)ZeroAddress;//DWORD Unit = pZeroAddress + 0xDAA54; // наш класс Unitif (HIWORD ( ZeroAddress ) ){ //printf("ZeroAddress = 0x%X\n", pZeroAddress); //printf("pUnit = 0x%X\n", Unit); int offsets[1] = { 0x0 }; int* locUnit = ReadPointer(ZeroAddress, offsets, 1); printf("locUnit = 0x%X\n", locUnit); localUnit = Unit::Singleton(locUnit); // создаём экземляр игрового класса, но с одним и тем же адресом printf("UnitName = %s\n", localUnit->UnitName); //вместо имени выводится пустая строка :(/> ошибочка...}class Unit{public:char skip[0xDAA54];char UnitName[12];...};Смотри мои уроки по реверсингу на C++, их было не мало) Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения