Гость bronis Опубликовано 28 июня, 2011 Поделиться Опубликовано 28 июня, 2011 Суть понял, пойду разбираться в IDA. А то я начиная с этого момента могу лишь изучать и задавать вопросы. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 29 июня, 2011 Поделиться Опубликовано 29 июня, 2011 Я что-то потерялся в дебрях вызовов и упёрся в аргумент функции "location_manager().update_positions". Эта функция постоянно работает с позициями.... Внизу есть другая функция, которая может вызывать "подставляемые" функции. Одну функцию может вызвать для бота и совершенно другую для пользователя. По какому принципу это делается нет времени разбирать, т.к. похоже это надолго. Всё-таки надо было ставить бряк на изменение курсора или на клик. Но для этого париться с хуками directX, на это тоже надо какое-то время.Но у меня есть не плохие новости. Есть же уже готовая таблица Recifense - ещё тот Гуру по таким случаям.=========================================== Total War - Shogun 2 Game Version : 1.00 Script Version: 1.0 CE Version : 6.0 GM, Ammo, Gold, MP, MSO 23-Mar-2011 By Recifense=========================================== Total War - Shogun 2 Game Version : 1.00 Script Version: 1.0 CE Version : 6.0 GM, Ammo, Gold, MP, MSO 23-Mar-2011 By Recifense===========================================1) God Mode: For all Units and Ships2) Unlimited Ammo (Arrows, Bombs, etc)3) Unlimited Movement Points (Army on campaign)4) Recover troop size when Army moves (Army on campaign)5) Minimum Gold (On campaign)6) Player's Current Gold (On campaign)7) Skill points of selected army's general (On Campaign)}[ENABLE]//=========================================// Check if script is compatible to this game version// If false the script will not be loadedassert(Shogun2.dll+00a63e50,55 8b ec 83 e4 f8)assert(Shogun2.dll+00c7e770,55 8b ec 83 e4 f8)assert(Shogun2.dll+01199dc3,8b b7 34 01 00 00)assert(Shogun2.dll+009e7af3,f3 0f 11 86 40 0f 00 00)assert(Shogun2.dll+00cf54e0,51 8b 8f a0 03 00 00)assert(Shogun2.dll+011cb77d,89 8e b0 00 00 00)assert(Shogun2.dll+00b560d7,8b 43 40)assert(Shogun2.dll+0046df80,?? ?? 6c 04 00 00)assert(Shogun2.dll+011ad6bc,?? ?? 0c 1c 00 00)//=========================================alloc(MyCode,1024)//=========================================// Declaration sectionlabel(_GodMode)label(_GodM00)label(_GodM01)label(_BackGM)label(_ExitGM)label(_GodMode1)label(_GodM10)label(_GodM11)label(_BackGM1)label(_ExitGM1)label(_MonSel)label(_BackMS)label(_MonAmmo)label(_MonA0)label(_MonA1)label(_BackMA)label(_ExitMA)label(_GodModeS)label(_BackGMS)label(_ExitGMS)label(_MonSelShip)label(_BackMSS)label(_ExitMSS)label(_GodModeSH)label(_BackGMSH)label(_ExitGMSH)label(_MonGold)label(_BackMG)label(_ExitMG)label(_MonMP)label(_MonM0)label(_BackMM)label(_ExitMM)label(_MonSelOfficer)label(_BackMSO)label(_ExitMSO)label(pSel)label(pGold)label(pOfficer)label(iEnableGM)label(iEnableGM1)label(iEnableGM2)label(iEnableGMS)label(iEnableMA)label(iEnableQR)label(iEnableMG)label(iEnableMM)label(iEnableMTS)label(iPlayerID)label(iMinGold)label(iEAX)label(iCount0)label(iCount1)label(iCount2)label(iCount3)label(iCountS)registersymbol(MyCode)registersymbol(pSel)registersymbol(pGold)registersymbol(pOfficer)registersymbol(iEnableGM)registersymbol(iEnableGM1)registersymbol(iEnableGM2)registersymbol(iEnableGMS)registersymbol(iEnableMA)registersymbol(iEnableQR)registersymbol(iEnableMG)registersymbol(iEnableMM)registersymbol(iEnableMTS)registersymbol(iMinGold)registersymbol(iPlayerID)registersymbol(iCount0)registersymbol(iCount1)registersymbol(iCount2)registersymbol(iCount3)registersymbol(iCountS)//=========================================MyCode://=========================================_GodMode: mov [iEAX],eax // Save EAX mov eax,[esp+04] // Get Unit mov eax,[eax+00000204] // Get pTroop test eax,eax jnz _GodM00 // Jump if the pointer is null mov eax,[eax+0000020c] // Get pShip test eax,eax jz _ExitGM // Jump if the pointer is null mov al,[eax+0000111f] // Get pCommon cmp al,[iPlayerID] // Is it a Player's Troop ? jne _ExitGM // Jump if false inc dword ptr [iCount0] cmp dword ptr [iEnableGM],0 je _ExitGM // Jump if feature is disabled jmp _GodM01//=====_GodM00: mov eax,[eax+00000294] // Get pPlayerInfo test eax,eax jz _ExitGM // Jump if the pointer is null mov eax,[eax+04] // Get playerID cmp eax,[iPlayerID] // Is it a Player's Troop ? jne _ExitGM // Jump if false inc dword ptr [iCount1] cmp dword ptr [iEnableGM],0 je _ExitGM // Jump if feature is disabled_GodM01: mov eax,[iEAX] // Restore EAX ret 0004 // Avoid routine//-----_ExitGM: mov eax,[iEAX] // Restore EAX push ebp // Original code mov ebp,esp // Original code and esp,f8 // Original code jmp _BackGM // Back to main code//=========================================_GodMode1: mov [iEAX],eax // Save EAX mov eax,[ecx+00000204] // Get pTroop test eax,eax jnz _GodM10 // Jump if the pointer is not null mov eax,[ecx+0000020c] // Get pShip test eax,eax jz _ExitGM1 // Jump if the pointer is null// Ship Crew mov al,[eax+0000111f] // Get pCommon cmp al,[iPlayerID] // Is it a Player's Troop ? jne _ExitGM1 // Jump if false inc dword ptr [iCount2] cmp dword ptr [iEnableGM],0 je _ExitGM1 // Jump if feature is disabled jmp _GodM11//Land Soldiers_GodM10: mov eax,[eax+00000294] // Get pPlayerInfo test eax,eax jz _ExitGM1 // Jump if the pointer is null mov eax,[eax+04] // Get playerID cmp eax,[iPlayerID] // Is it a Player's Troop ? jne _ExitGM1 // Jump if false inc dword ptr [iCount3] cmp dword ptr [iEnableGM],0 je _ExitGM1 // Jump if feature is disabled_GodM11: mov eax,[iEAX] // Restore EAX ret 0004 // Avoid routine//-----_ExitGM1: mov eax,[iEAX] // Restore EAX push ebp // Original code mov ebp,esp // Original code and esp,f8 // Original code jmp _BackGM1 // Back to main code//=========================================_MonSel: mov esi,[edi+00000134] // Original code mov [pSel],esi jmp _BackMS // Back to main code//=========================================_MonAmmo: mov eax,[esi+00000294] // Get pPlayerInfo test eax,eax jz _ExitMA // Jump if the pointer is null mov eax,[eax+04] // Get playerID cmp eax,[iPlayerID] // Is it a Player's Troop ? jne _ExitMA // Jump if false cmp dword ptr [iEnableMA],0 je _MonA0 // Jump if feature is disabled cvtsi2ss xmm0,[esi+00000F44] // Get Maximum Ammo_MonA0: cmp dword ptr [iEnableQR],0 je _ExitMA // Jump if feature is disabled cmp dword ptr [esi+00000dbc],#15 jle _MonA1 mov dword ptr [esi+00000dbc],#15_MonA1: cmp dword ptr [esi+00000dc0],#15 jle _ExitMA mov dword ptr [esi+00000dc0],#15_ExitMA: comiss xmm1,xmm0 // Update EFLAGS movss [esi+00000F40],xmm0 // Original code jmp _BackMA // Back to main code//=========================================_GodModeS: mov [iEAX],eax // Save EAX mov eax,[edi+0000020c] // Get pShip test eax,eax jz _ExitGMS // Jump if the pointer is null mov al,[eax+0000111f] // Get pCommon cmp al,[iPlayerID] // Is it a Player's Troop ? jne _ExitGMS // Jump if false inc dword ptr [iCountS] cmp dword ptr [iEnableGM],0 je _ExitGMS // Jump if feature is disabled mov eax,[iEAX] // Restore EAX ret // Avoid routine//-----_ExitGMS: mov eax,[iEAX] // Restore EAX push ecx // Original code mov ecx,[edi+000003A0] // Original code jmp _BackGMS // Back to main code//=========================================// Card under cursor_MonSelShip: mov [pSel],ecx_ExitMSS: mov [esi+000000B0],ecx // Original code jmp _BackMSS // Back to main code//=========================================// Ship Hull_GodModeSH: mov eax,[ebx+24] // Get pShip test eax,eax jz _ExitGMSH // Jump if the pointer is null mov al,[eax+0000111f] // Get pCommon cmp al,[iPlayerID] // Is it a Player's Troop ? jne _ExitGMSH // Jump if false cmp dword ptr [iEnableGM],0 je _ExitGMSH // Jump if feature is disabled mov eax,[ebx+1c] // Get max HP mov [ebx+40],eax // Update cur HP xor edi,edi // value2decrease = 0_ExitGMSH: mov eax,[ebx+40] // Original code sub eax,edi // Original code jmp _BackGMSH // Back to main code//=========================================// RTS Gold_MonGold: mov eax,[ecx+0000048c] // Get pointer to info test eax,eax jz _ExitMG // Jump if null pointer mov eax,[eax+24] // Get pointer to uPlayerID test eax,eax jz _ExitMG // Jump if null pointer mov eax,[eax] cmp eax,006c0070 jne _ExitMG // Jump if it's an AI mov eax,[ecx+00000470] // Get pointer to player mov [pGold],eax cmp dword ptr [iEnableMG],0 je _ExitMG // Jump if feature is disabled mov eax,[iMinGold] cmp eax,[ecx+0000046C] jle _ExitMG mov [ecx+0000046C],eax // Update gold_ExitMG: mov eax,[ecx+0000046C] // Original code jmp _BackMG // Back to main code//=========================================// RTS Troop Movement Points/Size_MonMP: push ecx mov ecx,[eax+44] // Get pointer to Owner cmp ecx,[pGold] // Is it a player's troop? jne _ExitMM cmp dword ptr [iEnableMM],0 je _MonM0 // Jump if feature is disabled xor edi,edi // value2decrease = 0_MonM0: cmp dword ptr [iEnableMTS],0 je _ExitMM // Jump if feature is disabled mov ecx,[eax+50] // Get troop maximum size mov [eax+4c],ecx // Update current size_ExitMM: pop ecx sub edx,edi // Original code mov [eax+6C],edx // Original code jmp _BackMM // Back to main code//=========================================// RTS Selected Officer_MonSelOfficer: mov [pOfficer],eax_ExitMSO: cmp [eax+00001C0C],ebx // Original code jmp _BackMSO // Back to main code//=========================================// VariablesiEnableGM: dd 1iEnableGM1: dd 0iEnableGM2: dd 1iEnableMA: dd 1iEnableQR: dd 1iEnableGMS: dd 1iEnableMG: dd 1iEnableMM: dd 1iEnableMTS: dd 1pSel: dd 0pGold: dd 0pOfficer: dd 0iPlayerID: dd 1iEAX: dd 0iCount0: dd 0iCount1: dd 0iCount2: dd 0iCount3: dd 0iCountS: dd 0iMinGold: dd #50000//=========================================// Hacking PointsShogun2.dll+00a63e50: jmp _GodMode nop_BackGM:Shogun2.dll+00c7e770: jmp _GodMode1 nop_BackGM1:Shogun2.dll+01199dc3: jmp _MonSel nop_BackMS:Shogun2.dll+009e7af3: jmp _MonAmmo nop nop nop_BackMA:Shogun2.dll+00cf54e0: jmp _GodModeS nop nop_BackGMS:Shogun2.dll+011cb77d: jmp _MonSelShip nop_BackMSS:Shogun2.dll+00b560d7: jmp _GodModeSH_BackGMSH:Shogun2.dll+0046df80: jmp _MonGold nop_BackMG:Shogun2.dll+0026a5e0: jmp _MonMP_BackMM:Shogun2.dll+011ad6bc: jmp _MonSelOfficer nop_BackMSO://=========================================// Original Codes[DISABLE]Shogun2.dll+00a63e50: push ebp mov ebp,esp and esp,f8Shogun2.dll+00c7e770: push ebp mov ebp,esp and esp,f8Shogun2.dll+01199dc3: mov esi,[edi+00000134]Shogun2.dll+009e7af3: movss [esi+00000F40],xmm0Shogun2.dll+00cf54e0: push ecx mov ecx,[edi+000003A0]Shogun2.dll+011cb77d: mov [esi+000000B0],ecxShogun2.dll+00b560d7: mov eax,[ebx+40] sub eax,ediShogun2.dll+0046df80: mov eax,[ecx+0000046C]Shogun2.dll+0026a5e0: sub edx,edi mov [eax+6C],edxShogun2.dll+011ad6bc: cmp [eax+00001C0C],ebxunregistersymbol(MyCode)unregistersymbol(pSel)unregistersymbol(pGold)unregistersymbol(pOfficer)unregistersymbol(iEnableGM)unregistersymbol(iEnableGM1)unregistersymbol(iEnableGM2)unregistersymbol(iEnableGMS)unregistersymbol(iEnableMA)unregistersymbol(iEnableQR)unregistersymbol(iEnableMG)unregistersymbol(iEnableMM)unregistersymbol(iEnableMTS)unregistersymbol(iMinGold)unregistersymbol(iPlayerID)unregistersymbol(iCount0)unregistersymbol(iCount1)unregistersymbol(iCount2)unregistersymbol(iCount3)unregistersymbol(iCountS)dealloc(MyCode){Как видно по смещению +0x44, я об этом смещение уже писал почему-то указатель на pGold (вроде как золото) Пользователя является уже критерием принадлежности войскам. Вообще-то странно кажется это корявые названия указателей. // RTS Troop Movement Points/Size_MonMP: push ecx mov ecx,[eax+44] // Get pointer to Owner cmp ecx,[pGold] // Is it a player's troop? jne _ExitMM cmp dword ptr [iEnableMM],0 je _MonM0 // Jump if feature is disabled xor edi,edi // value2decrease = 0_MonM0: cmp dword ptr [iEnableMTS],0 je _ExitMM // Jump if feature is disabled mov ecx,[eax+50] // Get troop maximum size mov [eax+4c],ecx // Update current size_ExitMM: pop ecx sub edx,edi // Original code mov [eax+6C],edx // Original code jmp _BackMM // Back to main codeНапоминаю, что это инъекция в эту функцию:{ int result; // eax@1 char *v3; // ecx@1 int v4; // esi@1 int v5; // eax@2 int v6; // edx@2 v3 = (char *)this + 148; v4 = *((_DWORD *)v3 + 5); for ( result = v4 + 4 * *((_DWORD *)v3 + 4); // начальное значения для начала цикла v4 != result; // условие выполнение цикла пока истино v4 != result result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) // действие при каждой повторении цикла { v5 = **(_DWORD **)v4; // v5 = адрес группы (v5 теперь является подгруппой *this) v6 = *(_DWORD *)(v5 + 0x6C); // v6 = разрешённых шагов для группы v5 if ( v6 <= a2 ) // если разрешённых шагов меньше например 3, когда попытка пойти на 5, то *(_DWORD *)(v5 + 0x6C) = 0; // присвоить v5 перемещение 0 else // иначе *(_DWORD *)(v5 + 0x6C) = v6 - a2; // присворить v5 разность между разршенными шагами и "сделанными" *(_DWORD *)(v5 + 0x898) = -1; // какое-то интересное смещение +0x898, что означает точно не понятно. // по карайне мере понятно, что оно стаиться в -1, когда v5 было установленно // кол-во разрешённых шагов v4 += 4; // перебираем следующую группу } return result;}int __thiscall sub_10654450(void *this, int a2)Всё-таки я выскажусь по этой таблице - громоздка, запутанная и неудобная. Надо было пользоваться обвёрткой Lua, как я это делал в теме по Lua... Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 29 июня, 2011 Поделиться Опубликовано 29 июня, 2011 А можно узнать источник, интересно посмотреть таблици всяких гуру и проанализировать принцип их работы. На момент когда я начал был уже готовый платный трейнер, меня впечатлили возможности трейнера (в промо версии) которые открываются при покупки трейнера, и я решил повторить что смогу. Может и печальная новость что кто то лучше меня или тебя но все же опыт всегда ценен, и я рад что благодаря вам и этой возможности что предоставила нам любезно игра Shogun2 =) мне удалось узнать больше о процессе создания трейнеров.В следующий раз буду поинтер на деньги искать в ручную, так бы я возможно заметил что при отнятии ОД у отряда проскакивает проверка на поинтер денег игрока.Что то не понятно, у него значение в [iPlayerID] и [pGold] с воздуха берутся? Не вижу чтоб он в них чтонибудь записывал. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 30 июня, 2011 Поделиться Опубликовано 30 июня, 2011 Ссылка на тему человека Recifense, там же есть файл .CT таблицы.В [pGold] есть запись, посмотри внимательно. А вот в [iPlayerID] записи нет, потому что это просто переменная для чтения. В этой переменной идентификатор игрока, он всегда равен единице.По поводу того, что Recifense лучше меня... Скорее всего так и есть, т.к. у него большой опыт в нахождении связей между указателями. Скорее всего, он не работает с декомпиляторами. Это только я так заморачиваюсь. Метод у него, скорее всего, такой. Если он не может сделать один чит, то он делает другой и ищет связи между поинтерами в структурах сделанных читов. Т.е. в его случае из Dessect Data окна он не вылазит вообще и наверняка активно пользуется сканером памяти в поиске адресов и указателей в структурах... так же, скорее всего, он часто ставит бряки на адреса указателей. Указатели эти расположены в структурах, где они характерны только для данной структуры. Мне надо было обратить внимание на смещение +0x44 в структуре "Передвижения" и искать связь этого указателя со структурой где расположен адрес золота моего героя. Ведь и адрес золота, и адрес очков хождения должны обязательно принадлежать герою за которого я играю.Таблица Recifense показала, что надо думать головой в направлении принадлежности адресов к структурам, которые каким-то образом связаны между собой. Т.е. если мы не можем идентифицировать принадлежность адреса очков ходов к герою за которого играем, то надо найти через бряк структуру этого адреса очков ходов и, например, структуру адреса золота и попытаться найти связи между этим структурами...По поводу этой игры. Подобная сложность создания читов почти всегда характерна для похожих игр, где много юнитов Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 2 июля, 2011 Поделиться Опубликовано 2 июля, 2011 Написал луа скрипт для условного бряка на нажитие мышки, а то в олли трасировка плохо работает.Условный бряк на функцию TranslateMessageостлось понять как запустить трейс чтоб он не заходил в посторонии функции. Ссылка на комментарий Поделиться на другие сайты Поделиться
Akama Опубликовано 4 июля, 2011 Поделиться Опубликовано 4 июля, 2011 На счёт бесконечной ходьбы и тд уже давно всё изобретено, вот таблица - изучай...На счёт остального, я так и не въехал зачем тебе отлавливать функции нажатия клавишь, но если не трудно, то объясни для тех, кто в танке )))Shogun2_V110_AOB_V21.zip Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 4 июля, 2011 Поделиться Опубликовано 4 июля, 2011 Akama, уже все давно узнали, что есть такая таблица ) И давно решили изучать её или нет...Отлавливать функции нажатия клавиш надо для работы в отладке, чтобы определить как код игры реагирует на ввод пользователя. Если интересуют подробности, то их нужно искать в отладке... Ссылка на комментарий Поделиться на другие сайты Поделиться
Akama Опубликовано 4 июля, 2011 Поделиться Опубликовано 4 июля, 2011 и это может как-то в игре пригодиться? Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 4 июля, 2011 Поделиться Опубликовано 4 июля, 2011 Это зависит от конкретного случая.Надо подразумевать простую схему. Когда используешь этот способ, то у тебя есть два адреса как минимум одного маршрута выполнения машинного кода. Первая точка это бряк на вводе от пользователя, вторая - бряк на адресе параметра, для которого нужно сделать чит. Соответсвенно, если есть проблемы с созданием чита, то нужно исследовать этот маршрут... Ссылка на комментарий Поделиться на другие сайты Поделиться
Akama Опубликовано 5 июля, 2011 Поделиться Опубликовано 5 июля, 2011 В общем практического применения нету, простое баловство... Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 5 июля, 2011 Поделиться Опубликовано 5 июля, 2011 Akama, не спешил бы ты с выводами так скоро и при любой возможности. Вот практическое применение.Как видно на рисунке указатели были исследованы, а вот как сделать "бесконечное обучение заклинаниям" будет описано ниже благодаря способу о котором идёт речь. Этот способ установил рамки до какого адреса вверх стоит подниматься из call-ов.Более подробно про то как сделать бесконечное обучение заклинаниям.1. Вникаем в суть игры и интерфейс, что не мало важно.Во время изучения заклинания происходят следующие действия.- В книге заклинаний выбираем заклинание- Щёлкаем по кнопке выучить заклинания и только после того как отпустили кнопку ,то вычитается мана и заклинания выучено.2. Раз знаем суть процесса, то находим адрес маны и ставим аппаратный бряк на запись.3. Ставим бряк на обработку сообщения на WM_MousUp. Щелкаем на кнопке заклинаний, прерываемся на адресе работы с сообщением.Снимаем бряк с сообщений и отпускает трейс по ретам.Возвращаемся в игру.Происходит прерывание на бряке маны. Снимаем бряк. Отпускаем игру и тут же находимся на развилке кода, это место можно считать верхнем порогом кода. Т.е. выше него мы дальше не полезем.Итак, определили путь.Начало пути - нажали на кнопку:0040657B . E8 A0D0FFFF CALL Disciple.00403620 - будет началом возможно закрученного пути.Конец - вычитание маны:0065AA15 |. 8910 MOV DWORD PTR [EAX],EDX – конечный путьВновь ставим бряк на запись маны, прерываемся.Теперь мы идем вверх по коду пробегая его глазами, если что-то не находим,то идём выше, каждый раз поднимаясь на уровень выше отмечаем адреса входа в комментариях. Но идти вверх по коду далеко не пришлось. Мы поднялись на один уровень и оказались в этой функции.006CF6DA |. 75 33 JNZ SHORT Disciple.006CF70F //можно исправить на JMP как это сделал SERGANT006CF6DC |. 8B01 MOV EAX,DWORD PTR [ECX]006CF6DE |. 6A 00 PUSH 0006CF6E0 |. 6A 01 PUSH 1006CF6E2 |. 68 A8A47F00 PUSH Disciple.007FA4A8 ; ASCII "Msg_SpellTooMuch"006CF6E7 |. 68 FCA17F00 PUSH Disciple.007FA1FC ; ASCII "Msg_HLIngfo"006CF6EC |. FF90 58020000 CALL NEAR DWORD PTR [EAX+258]006CF6F2 |. 8B0D A478C301 MOV ECX,DWORD PTR [1C378A4]006CF6F8 |. 8B11 MOV EDX,DWORD PTR [ECX]006CF6FA |. 68 0000803F PUSH 3F800000006CF6FF |. 6A 18 PUSH 18006CF701 |. FF92 BC040000 CALL NEAR DWORD PTR [EDX+4BC]006CF707 |. 5F POP EDI ; 25F89E08006CF708 |. 32C0 XOR AL,AL006CF70A |. 5D POP EBP ; 25F89E08006CF70B |. 83C4 10 ADD ESP,10006CF70E |. C3 RET006CF70F |> 8B87 74010000 MOV EAX,DWORD PTR [EDI+174]006CF715 |. 3B87 30010000 CMP EAX,DWORD PTR [EDI+130]006CF71B |. 73 0B JNB SHORT Disciple.006CF728006CF71D |. 8B8F 2C010000 MOV ECX,DWORD PTR [EDI+12C]006CF723 |. 8D0481 LEA EAX,DWORD PTR [ECX+EAX*4]006CF726 |. EB 06 JMP SHORT Disciple.006CF72E006CF728 |> 8D87 3C010000 LEA EAX,DWORD PTR [EDI+13C]006CF72E |> 8B10 MOV EDX,DWORD PTR [EAX]006CF730 |. 53 PUSH EBX006CF731 |. 8B1A MOV EBX,DWORD PTR [EDX]006CF733 |. E8 18E1FFFF CALL Disciple.006CD850006CF738 |. 84C0 TEST AL,AL006CF73A |. 74 09 JE SHORT Disciple.006CF745006CF73C |. 5B POP EBX ; 25F89E08006CF73D |. 5F POP EDI ; 25F89E08006CF73E |. 32C0 XOR AL,AL006CF740 |. 5D POP EBP ; 25F89E08006CF741 |. 83C4 10 ADD ESP,10006CF744 |. C3 RET006CF745 |> 56 PUSH ESI006CF746 |. 8BB7 74010000 MOV ESI,DWORD PTR [EDI+174]006CF74C |. 33C9 XOR ECX,ECX006CF74E |. 8D5D 04 LEA EBX,DWORD PTR [EBP+4]006CF751 |> 3BB7 30010000 /CMP ESI,DWORD PTR [EDI+130]006CF757 |. 73 0B |JNB SHORT Disciple.006CF764006CF759 |. 8B87 2C010000 |MOV EAX,DWORD PTR [EDI+12C]006CF75F |. 8D04B0 |LEA EAX,DWORD PTR [EAX+ESI*4]006CF762 |. EB 06 |JMP SHORT Disciple.006CF76A006CF764 |> 8D87 3C010000 |LEA EAX,DWORD PTR [EDI+13C]006CF76A |> 8B10 |MOV EDX,DWORD PTR [EAX]006CF76C |. 3B4A 24 |CMP ECX,DWORD PTR [EDX+24]006CF76F |. 0F83 87000000 |JNB Disciple.006CF7FC006CF775 |. 3BB7 30010000 |CMP ESI,DWORD PTR [EDI+130]006CF77B |. 73 0B |JNB SHORT Disciple.006CF788006CF77D |. 8B87 2C010000 |MOV EAX,DWORD PTR [EDI+12C]006CF783 |. 8D04B0 |LEA EAX,DWORD PTR [EAX+ESI*4]006CF786 |. EB 06 |JMP SHORT Disciple.006CF78E006CF788 |> 8D87 3C010000 |LEA EAX,DWORD PTR [EDI+13C]006CF78E |> 8B00 |MOV EAX,DWORD PTR [EAX]006CF790 |. 8B50 24 |MOV EDX,DWORD PTR [EAX+24]006CF793 |. 83C0 20 |ADD EAX,20006CF796 |. 3BCA |CMP ECX,EDX006CF798 |. 73 07 |JNB SHORT Disciple.006CF7A1006CF79A |. 8B10 |MOV EDX,DWORD PTR [EAX]006CF79C |. 8D048A |LEA EAX,DWORD PTR [EDX+ECX*4]006CF79F |. EB 03 |JMP SHORT Disciple.006CF7A4006CF7A1 |> 83C0 10 |ADD EAX,10006CF7A4 |> 83F9 FF |CMP ECX,-1006CF7A7 |. 8B00 |MOV EAX,DWORD PTR [EAX]006CF7A9 |. 74 09 |JE SHORT Disciple.006CF7B4006CF7AB |. 83F9 08 |CMP ECX,8006CF7AE |. 7D 04 |JGE SHORT Disciple.006CF7B4006CF7B0 |. 8B13 |MOV EDX,DWORD PTR [EBX]006CF7B2 |. EB 03 |JMP SHORT Disciple.006CF7B7006CF7B4 |> 83CA FF |OR EDX,FFFFFFFF006CF7B7 |> 3BD0 |CMP EDX,EAX006CF7B9 |. 7C 06 |JL SHORT Disciple.006CF7C1006CF7BB |. 41 |INC ECX006CF7BC |. 83C3 0C |ADD EBX,0C006CF7BF |.^ EB 90 \JMP SHORT Disciple.006CF751006CF7C1 |> 8B0D A478C301 MOV ECX,DWORD PTR [1C378A4]006CF7C7 |. 8B01 MOV EAX,DWORD PTR [ECX]006CF7C9 |. 6A 00 PUSH 0006CF7CB |. 6A 01 PUSH 1006CF7CD |. 68 F0A17F00 PUSH Disciple.007FA1F0 ; ASCII "Msg_NoRes"006CF7D2 |. 68 FCA17F00 PUSH Disciple.007FA1FC ; ASCII "Msg_HLIngfo"006CF7D7 |. FF90 58020000 CALL NEAR DWORD PTR [EAX+258]006CF7DD |. 8B0D A478C301 MOV ECX,DWORD PTR [1C378A4]006CF7E3 |. 8B11 MOV EDX,DWORD PTR [ECX]006CF7E5 |. 68 0000803F PUSH 3F800000006CF7EA |. 6A 18 PUSH 18006CF7EC |. FF92 BC040000 CALL NEAR DWORD PTR [EDX+4BC]006CF7F2 |. 5E POP ESI ; 25F89E08006CF7F3 |. 5B POP EBX ; 25F89E08006CF7F4 |. 5F POP EDI ; 25F89E08006CF7F5 |. 32C0 XOR AL,AL006CF7F7 |. 5D POP EBP ; 25F89E08006CF7F8 |. 83C4 10 ADD ESP,10006CF7FB |. C3 RET006CF7FC |> 8B4424 10 MOV EAX,DWORD PTR [ESP+10]006CF800 |. 33ED XOR EBP,EBP006CF802 |. 33DB XOR EBX,EBX006CF804 |> 8B8F 30010000 /MOV ECX,DWORD PTR [EDI+130]006CF80A |. 894424 14 |MOV DWORD PTR [ESP+14],EAX006CF80E |. 8B87 74010000 |MOV EAX,DWORD PTR [EDI+174]006CF814 |. 3BC1 |CMP EAX,ECX006CF816 |. 896C24 1C |MOV DWORD PTR [ESP+1C],EBP006CF81A |. 73 0B |JNB SHORT Disciple.006CF827006CF81C |. 8B8F 2C010000 |MOV ECX,DWORD PTR [EDI+12C]006CF822 |. 8D0C81 |LEA ECX,DWORD PTR [ECX+EAX*4]006CF825 |. EB 06 |JMP SHORT Disciple.006CF82D006CF827 |> 8D8F 3C010000 |LEA ECX,DWORD PTR [EDI+13C]006CF82D |> 8B11 |MOV EDX,DWORD PTR [ECX]006CF82F |. 3B6A 24 |CMP EBP,DWORD PTR [EDX+24]006CF832 |. 0F83 A7000000 |JNB Disciple.006CF8DF006CF838 |. 3B87 30010000 |CMP EAX,DWORD PTR [EDI+130]006CF83E |. 73 0B |JNB SHORT Disciple.006CF84B006CF840 |. 8B8F 2C010000 |MOV ECX,DWORD PTR [EDI+12C]006CF846 |. 8D0481 |LEA EAX,DWORD PTR [ECX+EAX*4]006CF849 |. EB 06 |JMP SHORT Disciple.006CF851006CF84B |> 8D87 3C010000 |LEA EAX,DWORD PTR [EDI+13C]006CF851 |> 8B00 |MOV EAX,DWORD PTR [EAX]006CF853 |. 8B48 24 |MOV ECX,DWORD PTR [EAX+24]006CF856 |. 83C0 20 |ADD EAX,20006CF859 |. 3BE9 |CMP EBP,ECX006CF85B |. 73 06 |JNB SHORT Disciple.006CF863006CF85D |. 8B00 |MOV EAX,DWORD PTR [EAX]006CF85F |. 03C3 |ADD EAX,EBX006CF861 |. EB 03 |JMP SHORT Disciple.006CF866006CF863 |> 83C0 10 |ADD EAX,10006CF866 |> 83FB FC |CMP EBX,-4006CF869 |. 8B00 |MOV EAX,DWORD PTR [EAX]006CF86B |. 74 62 |JE SHORT Disciple.006CF8CF006CF86D |. 83FB 20 |CMP EBX,20006CF870 |. 7F 5D |JG SHORT Disciple.006CF8CF006CF872 |. 8B5424 14 |MOV EDX,DWORD PTR [ESP+14]006CF876 |. 8B32 |MOV ESI,DWORD PTR [EDX]006CF878 |. 8B5424 10 |MOV EDX,DWORD PTR [ESP+10]006CF87C |. 8D4C24 18 |LEA ECX,DWORD PTR [ESP+18]006CF880 |. 51 |PUSH ECX006CF881 |. 6A 00 |PUSH 0006CF883 |. F7D8 |NEG EAX006CF885 |. 50 |PUSH EAX006CF886 |. 56 |PUSH ESI006CF887 |. 52 |PUSH EDX006CF888 |. C74424 2C 0000000>|MOV DWORD PTR [ESP+2C],0006CF890 |. E8 ABB0F8FF |CALL Disciple.0065A940 ; <<<<<<<<<<<<,, + вышли отсюда и смотрим код вверху006CF895 |. 83C4 14 |ADD ESP,14006CF898 |. 84C0 |TEST AL,AL006CF89A |. 74 33 |JE SHORT Disciple.006CF8CF006CF89C |. 8B4424 18 |MOV EAX,DWORD PTR [ESP+18]006CF8A0 |. 8B0D A078C301 |MOV ECX,DWORD PTR [1C378A0]006CF8A6 |. 8B11 |MOV EDX,DWORD PTR [ECX]006CF8A8 |. 6A 00 |PUSH 0006CF8AA |. 8D2C40 |LEA EBP,DWORD PTR [EAX+EAX*2]006CF8AD |. 8B4424 14 |MOV EAX,DWORD PTR [ESP+14]006CF8B1 |. 8B6CA8 04 |MOV EBP,DWORD PTR [EAX+EBP*4+4]006CF8B5 |. 8B80 E4000000 |MOV EAX,DWORD PTR [EAX+E4]006CF8BB |. 6A 00 |PUSH 0006CF8BD |. 55 |PUSH EBP006CF8BE |. 56 |PUSH ESI006CF8BF |. 50 |PUSH EAX006CF8C0 |. 68 F8027F00 |PUSH Disciple.007F02F8 ; ASCII "GetResource"006CF8C5 |. FF92 90020000 |CALL NEAR DWORD PTR [EDX+290]006CF8CB |. 8B6C24 1C |MOV EBP,DWORD PTR [ESP+1C]006CF8CF |> 8B4424 14 |MOV EAX,DWORD PTR [ESP+14]006CF8D3 |. 45 |INC EBP006CF8D4 |. 83C3 04 |ADD EBX,4006CF8D7 |. 83C0 0C |ADD EAX,0C006CF8DA |.^ E9 25FFFFFF \JMP Disciple.006CF804006CF8DF |> 8B4C24 10 MOV ECX,DWORD PTR [ESP+10]006CF8E3 |. 51 PUSH ECX006CF8E4 |. 57 PUSH EDI ; Disciple.01C3FF80006CF8E5 |. E8 B6FCFFFF CALL Disciple.006CF5A0006CF8EA |. A1 A478C301 MOV EAX,DWORD PTR [1C378A4]006CF8EF |. 8B90 E0000000 MOV EDX,DWORD PTR [EAX+E0]006CF8F5 |. 8990 E4000000 MOV DWORD PTR [EAX+E4],EDX006CF8FB |. 8B8F 78010000 MOV ECX,DWORD PTR [EDI+178]006CF901 |. 8B97 7C010000 MOV EDX,DWORD PTR [EDI+17C]006CF907 |. 8B07 MOV EAX,DWORD PTR [EDI] ; Disciple.007FA410006CF909 |. 8BB7 70010000 MOV ESI,DWORD PTR [EDI+170]006CF90F |. 8B9F 74010000 MOV EBX,DWORD PTR [EDI+174]006CF915 |. 83C4 08 ADD ESP,8006CF918 |. 51 PUSH ECX006CF919 |. 52 PUSH EDX006CF91A |. 8BCF MOV ECX,EDI ; Disciple.01C3FF80006CF91C |. FF50 4C CALL NEAR DWORD PTR [EAX+4C]006CF91F |. 8B07 MOV EAX,DWORD PTR [EDI] ; Disciple.007FA410006CF921 |. 53 PUSH EBX006CF922 |. 8BCF MOV ECX,EDI ; Disciple.01C3FF80006CF924 |. 89B7 70010000 MOV DWORD PTR [EDI+170],ESI006CF92A |. FF50 50 CALL NEAR DWORD PTR [EAX+50]006CF92D |. E8 9E060000 CALL Disciple.006CFFD0006CF932 |. E8 C9080000 CALL Disciple.006D0200006CF937 |. 8B0D A478C301 MOV ECX,DWORD PTR [1C378A4]006CF93D |. 85C9 TEST ECX,ECX006CF93F |. 74 0F JE SHORT Disciple.006CF950006CF941 |. 8B11 MOV EDX,DWORD PTR [ECX]006CF943 |. 68 0000803F PUSH 3F800000006CF948 |. 6A 06 PUSH 6006CF94A |. FF92 BC040000 CALL NEAR DWORD PTR [EDX+4BC]006CF950 |> 5E POP ESI ; 25F89E08006CF951 |. 5B POP EBX ; 25F89E08006CF952 |. 5F POP EDI ; 25F89E08006CF953 |. B0 01 MOV AL,1006CF955 |. 5D POP EBP ; 25F89E08006CF956 |. 83C4 10 ADD ESP,10006CF959 \. C3 RET006CF6D6 |. 896C24 08 MOV DWORD PTR [ESP+8],EBP{ int v1; // ebp@1 int v2; // edi@1 char result; // al@2 signed int v4; // ecx@7 int v5; // ebx@7 unsigned int v6; // esi@7 int v7; // eax@9 int v8; // eax@13 int v9; // eax@15 int v10; // eax@16 signed int v11; // eax@18 signed int v12; // edx@20 int v13; // eax@25 signed int v14; // ebx@25 unsigned int v15; // ebp@25 unsigned int v16; // eax@26 int v17; // ecx@27 int v18; // eax@31 int v19; // eax@33 int v20; // eax@34 int v21; // eax@36 int v22; // esi@38 int v23; // eax@1 char v24; // zf@1 int v25; // eax@15 unsigned int v26; // edx@15 unsigned int v27; // ecx@26 int v28; // eax@33 unsigned int v29; // ecx@33 int v30; // esi@41 int v31; // ebx@41 int v32; // eax@41 int v33; // [sp+14h] [bp-10h]@1 int v34; // [sp+18h] [bp-Ch]@26 unsigned int v35; // [sp+20h] [bp-4h]@26 int v36; // [sp+1Ch] [bp-8h]@38 v2 = a1; v23 = (*(int (**)(void))(*(_DWORD *)dword_1C378A4 + 0x34))(); v1 = v23; v24 = *(_DWORD *)(dword_1C378A4 + 0xE4) == *(_DWORD *)(dword_1C378A4 + 0xE0); // ключевое место v33 = v23; if ( v24 ) { (*(int (__stdcall **)(char *, char *, signed int, _DWORD))(*(_DWORD *)dword_1C378A4 + 0x258))( "Msg_HLIngfo", "Msg_SpellTooMuch", 1, 0); (*(int (__stdcall **)(signed int, unsigned int))(*(_DWORD *)dword_1C378A4 + 0x4BC))(24, 0x3F800000u); result = 0; } else { *(_DWORD *)(v2 + 372) >= *(_DWORD *)(v2 + 304); if ( (unsigned __int8)sub_6CD850() ) { result = 0; } else { v6 = *(_DWORD *)(v2 + 372); v4 = 0; v5 = v1 + 4; while ( 1 ) { if ( v6 >= *(_DWORD *)(v2 + 304) ) v7 = v2 + 316; else v7 = *(_DWORD *)(v2 + 0x12C) + 4 * v6; if ( (unsigned int)v4 >= *(_DWORD *)(*(_DWORD *)v7 + 0x24) ) break; if ( v6 >= *(_DWORD *)(v2 + 304) ) v8 = v2 + 316; else v8 = *(_DWORD *)(v2 + 0x12C) + 4 * v6; v25 = *(_DWORD *)v8; v26 = *(_DWORD *)(v25 + 0x24); v9 = v25 + 32; if ( v4 >= v26 ) v10 = v9 + 16; else v10 = *(_DWORD *)v9 + 4 * v4; v11 = *(_DWORD *)v10; if ( v4 == -1 || v4 >= 8 ) v12 = -1; else v12 = *(_DWORD *)v5; if ( v12 < v11 ) { (*(int (__stdcall **)(char *, char *, signed int, _DWORD))(*(_DWORD *)dword_1C378A4 + 600))( "Msg_HLIngfo", "Msg_NoRes", 1, 0); (*(int (__stdcall **)(unsigned int, signed int))(*(_DWORD *)dword_1C378A4 + 0x4BC))(0x18u, 1065353216); return 0; } ++v4; v5 += 12; } v13 = v33; v15 = 0; v14 = 0; while ( 1 ) { v27 = *(_DWORD *)(v2 + 304); v34 = v13; v16 = *(_DWORD *)(v2 + 372); v35 = v15; if ( v16 >= v27 ) v17 = v2 + 316; else v17 = *(_DWORD *)(v2 + 300) + 4 * v16; if ( v15 >= *(_DWORD *)(*(_DWORD *)v17 + 36) ) break; if ( v16 >= *(_DWORD *)(v2 + 304) ) v18 = v2 + 316; else v18 = *(_DWORD *)(v2 + 300) + 4 * v16; v28 = *(_DWORD *)v18; v29 = *(_DWORD *)(v28 + 36); v19 = v28 + 32; if ( v15 >= v29 ) v20 = v19 + 16; else v20 = v14 + *(_DWORD *)v19; v21 = *(_DWORD *)v20; if ( v14 != -4 ) { if ( v14 <= 32 ) { v22 = *(_DWORD *)v34; v36 = 0; if ( (unsigned __int8)SFChangeResourceNum(v33, v22, -v21, 0, &v36) ) { (*(int (__stdcall **)(char *, _DWORD, int, _DWORD, _DWORD, _DWORD))(*(_DWORD *)dword_1C378A0 + 656))( "GetResource", *(_DWORD *)(v33 + 228), v22, *(_DWORD *)(v33 + 12 * v36 + 4), 0, 0); v15 = v35; } } } ++v15; v14 += 4; v13 = v34 + 12; } SFSpellStudent(v2, v33); *(_DWORD *)(dword_1C378A4 + 228) = *(_DWORD *)(dword_1C378A4 + 224); v30 = *(_DWORD *)(v2 + 368); v31 = *(_DWORD *)(v2 + 372); (*(int (__thiscall **)(int, _DWORD, _DWORD))(*(_DWORD *)v2 + 76))( v2, *(_DWORD *)(v2 + 380), *(_DWORD *)(v2 + 376)); v32 = *(_DWORD *)v2; *(_DWORD *)(v2 + 368) = v30; (*(int (__thiscall **)(int, int))(v32 + 80))(v2, v31); sub_6CFFD0(); sub_6D0200(); if ( dword_1C378A4 ) (*(int (__stdcall **)(signed int, unsigned int))(*(_DWORD *)dword_1C378A4 + 1212))(6, 0x3F800000u); result = 1; } } return result;}char __usercall sub_6CF6B0<al>(int a1<eax>)Cтавим бряк на запись маны и поднимаемся выше по коду, каждый раз ставя плюсики на уровень выхода из функции.x1= [[1C378A4]+0xE4] – это значение устанавливается равным [[1C378A4]+0xE0] при изучении заклинанияx2= [[1C378A4]+0xE0] – количество игровых ходов, т.е. не игрока, а именно ходов игры.Если x1 и x2 равны, то нельзя выучить заклинание.x1 до начала самого первого хода в игре равно мусору. После изучения первого заклинания на пример на 5-ом ходу когда x2=5, то x1 становится равным 5. Делаем ход x2 становится равным 6, а x1 остаётся равным 3. Изучаем заклинание x1 становится равным 6.Вывод: нельзя найти отсеиванием, т.к. врядли додумаешься до правил поиска ) Про то, как сделать пользование магией будет скоро в следующем посте. Надо делать почти также. Ставить бряк на Ману использовать заклинание и смотреть выше по коду…Короче что просил Иван Иванови, то сделал.Берём русскую версию CE.\"Подсоединяем\" процесс игрыИдём в отладчик, нажимаем на Автоассемблер.Пишем скрипт ниже.Связываем, сохраняем таблицу. Активируем и играем.//Бесконечное изучение заклинанияDisciplesIII.exe+2CF6DA:>E40000008BE83B91E0000000896C2408YYxxxxxxxx006A0168A8A47F0068FCdb eb 33//Бесконечное использование заклинанияDisciplesIII.exe+27BFD7:>006A01508BCDFF92380600008B5C2418YYxxxxxxxx008B85E0000000898388db 90 90 90 90 90 90//Бесконечная постройка зданийDisciplesIII.exe+2F35E3:>2418508BC78BCDE8xxxxxxxx85F67407YYxxxxxxxx00018B0Dxxxxxxxx85C9db 90 90 90 90 90 90 90[DISABLE]DisciplesIII.exe+2CF6DA:>E40000008BE83B91E0000000896C2408YYxxxxxxxx006A0168A8A47F0068FCdb 75 33DisciplesIII.exe+27BFD7:>006A01508BCDFF92380600008B5C2418YYxxxxxxxx908B85E0000000898388inc [ebx+0000008c] //ff 83 8c 00 00 00 DisciplesIII.exe+2F35E3:>2418508BC78BCDE8xxxxxxxx85F67407YYxxxxxxxx90908B0Dxxxxxxxx85C9mov byte ptr [esi+000000f0],01 //c6 86 f0 00 00 00 01[ENABLE]Чит-код на \"Бесконечное использование заклинания\" было сложно найти ) SERGANT, я трейнер делать не буду, так что вся надежда по видимому только на тебя. Если есть вопросы, то я постараюсь помочь.Ах да, по водову inc [ebx+0000008c]. Эти данные входят в структуру героя. Если кому надо те могут посмотреть рисунок выше и сравнить с этим указателем [[[[DisciplesIII.exe+18378A4]+00122b24]+1*4]+8c], он же и [ebx+0000008c], где ebx был рассчитан, а 8с = 0x22*4 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения