Гость bronis Опубликовано 23 июня, 2011 Поделиться Опубликовано 23 июня, 2011 Игра: Shogun 2: Total WarВерсия: v1.1.0 Build 3444Жанр: Strategy (Real-time / Turn-based) / 3DСперва я нашел адреса отвечающие за очки действия для нескольких отрядов, тем самым "заморозив" их мы уже получаем бесконечный ход.Но в таком случае будут 2 недостатка 1: Нужно будет искать адрес для каждого нового юнита. 2: Адреса всех юнитов изменятся после загрузки.Поскольку меня интересует не сам чит а процесс его создания, я решил продолжить поиски и посредством бряков на запись нашел инструкцию которая отнимает у нас ОД-Очки Действия:Начало функции Shogun2.dll+22C9F0...1. mov edx,[esi]2. mov eax,[edx]3. mov edx,[eax+6C] // помещает значение ОД в edx4. cmp edx,edi5. jle 9. // переход на инструкцию mov [eax+6C],00000000 в случае если по завершению хода юнита не остается ОД6. sub edx,edi // edx = очки действия юнита, edi = кол-во потраченых очков7. mov [eax+6C],edx // помещаем по адресу eax+6c итоговое кол-во ОД8. jmp UIFileInPtr::~UIFileInPtr+1C33E // переход к подготовке выхода из функции а далее и сам выход9. mov [eax+6C],00000000 // помещает в ячейку Очков Действия юнита 0...Отметим 2 интересных нам андреса:1. Shogun2.dll+22CA12 // mov [eax+6C],edx2. Shogun2.dll+22CA17 // mov [eax+6C],00000000Поставив бряки на данные инструкции мы сможем найти структуры юнитов и их ОД, в том числе и вражеские юниты (кроме агентов)Цели: Создать инжект код на бесконечный ход с фильтром только для своих юнитов, проблема в том что не удается найти отличительную черту по которой можно было бы составить условие тем самым отсеяв всех лишних юнитов. Что я только не пытался делать, пытался анализировать код в обратном порядке в надежде понять как игра получает адреса на структуры юнитов но ничего не вышло. Пытался сравнивать структуры вражеских юнитов и моих с целью найти какие ни будь байты по которым можно было б отличить своих от чужих но опять же ничего не получилось. Может кто ни будь знает какой ни будь способ 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 23 июня, 2011 Поделиться Опубликовано 23 июня, 2011 Спасибо за оформленный вопрос (мне понравилось). Сегодня я не смогу ответить... так что наверно до завтра. Ссылка на комментарий Поделиться на другие сайты Поделиться
Ac1d Опубликовано 23 июня, 2011 Поделиться Опубликовано 23 июня, 2011 Если я не понял вопрос, то извините. Я бы сделал так:1. Нашёл адрес ходов2. Боставил бы бряк на чтение3. Из всех возможных инструкций постарался узнать с какими адресами они работают4. Повезёт если есть инстр. отвечающая за мой ход. Другая отвечающая за ход врага.5. Если одна отвечает за ходы меня и врага, то тут надо уже делать фильтр(что я собственно и не умею делать)Что у вас? 5ый случай или 4ый? Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 23 июня, 2011 Поделиться Опубликовано 23 июня, 2011 Нашел в вашей статье пример на эту тему, и удалось найти описываемую там функцию она тоже читает адрес дальности хода и работает только с игроком. Сейчас пытаюсь в ней что ни будь найти.Medieval 2: Total WarДля того чтобы трейнер был универсальным, нужно вытащить _pID из инструкции типа А. _pID должен указывать на то, что объекты расы наши. Инструкцию берём такую, которая работает при наведении курсора мыши на только нашего юнита, это как раз та инструкция которая читала адрес дальности хождения юнита. Она читает только юниты нашей расы.Код: Бряк сработал на Shogun2.dll+61DDA558D5DD8A - 8B 87 B0080000 - mov eax,[edi+000008B0]58D5DD90 - 85 C0 - test eax,eax58D5DD92 - 74 04 - je 58D5DD9858D5DD94 - 8B 00 - mov eax,[eax]58D5DD96 - EB 02 - jmp 58D5DD9A58D5DD98 - 33 C0 - xor eax,eax58D5DD9A - 85 C0 - test eax,eax58D5DD9C - 0F95 C1 - setnc cl58D5DD9F - 88 8E C4000000 - mov [esi+000000C4],cl>>58D5DDA5 - 8B 57 6C - mov edx,[edi+6C] // место останова58D5DDA8 - 89 96 C8000000 - mov [esi+000000C8],edx58D5DDAE - 8B 07 - mov eax,[edi]58D5DDB0 - 8B 50 38 - mov edx,[eax+38]58D5DDB3 - 8B CF - mov ecx,edi58D5DDB5 - FF D2 - call edx58D5DDB7 - 8B 48 64 - mov ecx,[eax+64]58D5DDBA - 85 C9 - test ecx,ecx58D5DDBC - F3 0F10 05 A023B959 - movss xmm0,[59B923A0] : [(float)1.0000]58D5DDC4 - 74 21 - je 58D5DDE758D5DDC6 - 83 39 00 - cmp dword ptr [ecx],00Регистры и СтекIzmalkoffИнструкций работающих с адресами очков действия (игрока и врагов) для ряда юнитов которых я рассматриваю всего 2 шт и они находятся в одной функции, я их описал в первом посте. А остальные что читатют ячейки данных с очками действия я в данный момент рассматриваю на предмет интересностей =) Ссылка на комментарий Поделиться на другие сайты Поделиться
Ac1d Опубликовано 23 июня, 2011 Поделиться Опубликовано 23 июня, 2011 png_get_io_chunk_name+C785 - уберите галочку с Show module adress. В окне отладчика Ctrl+M Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 23 июня, 2011 Поделиться Опубликовано 23 июня, 2011 png_get_io_chunk_name+C785 - уберите галочку с Show module adress. В окне отладчика Ctrl+MОна у меня и так не стоит, и этот "глюк" который как уже оказалось вовсе не глюк проявлял себя только при копи пасте. Помогло снятие галочки Show symbols в меню View, но всеравно спасибо Фильтр написать не проблема, сложно найти в структуре указатель на то что она пренадлежит игроку, ну или искать надо не в структуре, собственно в этом и сложность.В отчаянии решил отвлечся и написал код инжект на анлимит денег с филтром. Работает с версией: v1.1.0 Build 3444[ENABLE]alloc(_inj,2048)label(_back)label(_exit)_inj:pushfpushadmov edx,[Shogun2.dll+019C0D94]mov edx,[edx+041C]mov edx,[edx+08]mov edx,[edx+24]mov edx,[edx+04]add edx,478mov eax,ecxadd eax,0000046Ccmp eax,edxjne short _backmov dword ptr [ecx+0000046C],#12345_back:popadpopfmov eax,[ecx+0000046C]jmp _exit"Shogun2.dll"+840D0:jmp _injnop_exit:[DISABLE]dealloc(_inj)"Shogun2.dll"+840D0:mov eax,[ecx+0000046C]Shogun2.dll+61DDA5 Чертертый пост в попытках найти код в котором формируется указатель на структуру юнита я дошел инструкции(Shogun2.dll+65765E) которая извлекает указатель из стека, но к сожалению олли в моей винде не работает должным образом =( защита виндоуз закрывает процес при атаче его из олли, хотел поставить условный бряк но не судьба. Лимит моего мозга исчерпан, уже не соображаю, чем больше смотрю в код тем больше понимаю что ничего не понимаю - ушел спать. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 В посте номер 4. Есть строка кода:58D5DD9F - 88 8E C4000000 - mov [esi+000000C4],clОпределите какие адреса проскакивают в квадратных скобках. Это можно сделать из меню дизассемблера функцией "Find out what addresses this code accesses".Если адрес будет проскакивать один, то это хорошо. Если больше двух, то ищем указатель уровня выше (который что-то писал в esi). На адрес указателя "уровня выше" ставим бряк на доступ и определяем прервавшиеся инструкции. На них также определяем проскакивающие адреса... Если найдётся один адрес, то к нему можно обращаться как фильтру...Может быть я запутанно написал, но пока ничем больше помочь не могу. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 Если адрес будет проскакивать один, то это хорошо. Если больше двух, то ищем указатель уровня выше (который что-то писал в esi). На адрес указателя "уровня выше" ставим бряк на доступ и определяем прервавшиеся инструкции. На них также определяем проскакивающие адреса... Если найдётся один адрес, то к нему можно обращаться как фильтру...Может быть я запутанно написал, но пока ничем больше помочь не могу.Еще как запутано =) Но тем неменее я признателен хотяб за такие наставления!К сожалению адресов проскакивающих в функции mov [esi+000000C4],cl оказалось больше двух, вот только я не совсем понял что дальше делать. Стал просматривать код выше на предмет записи чего либо в ESI или по его адресу который он формерует, нашел запись по адресу esi+44 колво юнитов в отряде, и решил уточнить что такое "указатель уровня выше". Мне надо искать указатель на адрес ESI как при поиске поинтера? или надо искать все что ранее записывалось в ESI и на эти инструкции ставить такойже бряк на доступ? Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 В сам ESI данные помещаются из стека, и в основном в [esi+xxx] записываются разные данные. А волнует меня то что адреса которые проскакивают через этот esi разные даже для одного и тогоже юнита, я так пологаю что в esi помещается адрес копии структуры данных юнита и эта копия меняет свое расположение чуть ли не каждые 10 сек, может я ошибаюсь и это не копия но во всяком случае адреса через esi всегда разные таким образом просканил гдето штук 30 инструкций в которых использовалось esi и всегда всплывали разные адреса. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 Там гед я писал слово "уровень" это относилось к некоторому указателю в цепочки указателей...Код игры прекрасно знает кто пользователь, а кто Бот. Это нужно всегда помнить.Ищите зацепки в коде, в бряках на уровнях указателей, в структурах указателей. По крайне мере ищите цепочку указателей до статического адреса (он должен быть зелёным в CE) и не проиграйте.Ещё один вариант это просто сравнивать структуры по адресам уровней указателей своих выбранных отрядов и отрядов бота. Выясните какие данные позволяют Вам передвигать Ваших юнитов и не позволяют командовать отрядами ботов. Я говорю сейчас про условную карту Мира, а не карту где войска могут захватывать замок...Могу посоветовать установить игру по которой я делал статью и попытаться сделать также. Понимаю, наверно, это сложно, но ничего более точного и толкового подсказать не могу. Просто сейчас у меня нет возможность установить игру. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 24 июня, 2011 Поделиться Опубликовано 24 июня, 2011 Спасибо.Немного отвлекся и решил дописать инжект на деньги, дополнил его перехватом еще 3 функций которые отвечают за: снятие денег за постройки и тд, добавление денег за отмену построек и тд, добавление денег нолооблажение за ход. Понимаю что это совершенно бесмыслено(не бессмертие делаем же) но зато потренеровался.[ENABLE]alloc(_inj,2048)label(_back)label(_exit_sub)label(_exit_add)label(_exit_addc)label(_exit_chk)_inj:pushfpushadmov esi,ecxmov ecx,00000003jmp _inj+2Apushfpushadmov esi,ebxmov ecx,00000002jmp _inj+2Apushfpushadmov ecx,00000001jmp _inj+2Apushfpushadmov ecx,00000000mov edx,[Shogun2.dll+019C0D94]mov edx,[edx+041C]mov edx,[edx+08]mov edx,[edx+24]mov edx,[edx+04]add edx,478mov eax,esiadd eax,0000046Ccmp eax,edxjne short _backmov dword ptr [esi+0000046C],#12345cmp ecx,01jb +1Cja +0Dcmp ecx,03je +1Dpopadpopfjmp _exit_addcmp ecx,03je +10popadpopfjmp _exit_addcpopadpopfjmp _exit_subpopadpopfmov eax,[ecx+0000046C]jmp _exit_chk_back:cmp ecx,01jb +28ja +13cmp ecx,03je +2Fpopadpopfadd [esi+0000046C],edijmp _exit_addcmp ecx,03je +1Cpopadpopfadd [ebx+0000046C],edxjmp _exit_addcpopadpopfsub [esi+0000046C],edxjmp _exit_subpopadpopfmov eax,[ecx+0000046C]jmp _exit_chk"Shogun2.dll"+5A4EBD:jmp _inj+18nop_exit_add:"Shogun2.dll"+54D1A:jmp _inj+0Cnop_exit_addc:"Shogun2.dll"+619585:jmp _inj+22nop_exit_sub:"Shogun2.dll"+840D0:jmp _injnop_exit_chk:[DISABLE]dealloc(_inj)"Shogun2.dll"+5A4EBD:add [esi+0000046C],edi"Shogun2.dll"+54D1A:add [ebx+0000046C],edx"Shogun2.dll"+619585:sub [esi+0000046C],edx"Shogun2.dll"+840D0:mov eax,[ecx+0000046C]Нашел указатель на активного(выделеного мышкой) юнита [[[[[[shogun2.dll+16AB314]+EAX*8+04]+33C]+50]+0С]+6C]=Очки действия выделеного своего/вражеского юнита. На EAX влеяет какой юнит выделен в данный момент, проблема в том что я с горем по поломам добрался до этого EAX и наивно полагая что он статичен сделал перезапуск игры(Беда в том что указатель я искал изучая код в обратном порядке). В общем щас придется еще раз все перерывать и найти EAX, а затем я планирую выяснить откуда он берется. Подозвераю что этот EAX что то вроде ID обьекта Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 25 июня, 2011 Поделиться Опубликовано 25 июня, 2011 Не забывайте, что одновременно с Cheat Engine есть инструменты OllyDbg(удобный отладчик в пошаговой отладке и установки условных бряков), IDA + Hex-Rays(анализирование дизассемблерного кода и декомпилирование), RecSudio(декомпилирование), Function Hacker (перехват тех или иных функций), MHS... В последней программе есть удобная функция просматривания и составления цепочек указателей....В Cheat Engine есть LUA engine, который поможет ставить бряки и удобно снимать показания регистров в лог... Так же в CE есть инструмент трассировщика с условием прерывания. Этот трейсер может показать огромное дерево иерархии вызовов кода... В CE есть сканер указателей и dessect data tool позволит просматривать и сравнивать структуры. Так же повторюсь, если очень трудно искать всю цепочку указателя и нужно найти лишь частичный путь это цепочки, то важно определять сколько и какие адреса проскакивают в квадратных скобках инструкций работающие с указателями уровней. Cheat Engine это умеет делать, пример этого я приводил выше.Сами понимаете, что учиться овладеть этим далеко непросто. Можно использовать только OllyDbg, ставив условные бряки при выходе из call-а, по методу из статьи Never Winter Nigth. У Cheat Engine есть сканер указателей. Его лучше не использовать, потому что он может найти неправильный указатель руководствуясь поиском указателей через вычитание и сложение смещений, когда могут быть и другие операции... и быть на 100% уверенным в том, что этот указатель будет всегда работать нельзя. У некоторого пользователя в какой-то момент этот указатель может "сбиться". Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 25 июня, 2011 Поделиться Опубликовано 25 июня, 2011 Спасибо, но знать что эти програмы есть недостаточно к примеру IDA вообще мне не по зубам пока что, столько опций что там есть мне пока не переварить и лиш запутают меня. OllyDbg у меня выдает ошибку ntdll.DbgBreakPoint на винде Win 7 64bit. Только CE может порадовать меня в последнее время, и благодоря этому я уже довольно комфортно себя в нем ощущаю. Нашел чему равен EAX=921 только вот пока понять откуда он берется я не могу. По поводу автоматического скана указателей в CE, сканил минут 20 при том что я ему задал возможные оффсеты, и в итоге ни одного указателя не насканилось =) видать потому что указатель частично по формуле вычисляется или я не на "правильную" сигнатуру искал указатель. Конечно бывали случаи что авто поиск помогал, но в этот раз даже до отсева указателей не дошло.Примерно таким же методом я и нашел этот указатель. Нашел адрес - поставил бряк - нашел [адрес1+смещение1] - запомнил в каком регистре лежит адрес1 и анализирую код выше вплоть до начала функции на наличие инструкции mov адрес1,[адрес2+смещение2] или просто mov адрес1,адрес2(чтоб не потерять след) ну или чтонибудь в этом духе, дойдя до начала функции я смотрю в стек и ищу адрес выхода или же жму Execute till return(иногда функия нарочно изменяет esp - в таком случае Execute till return может вывести не туда, поэтому я анализирую стек перед тем как что либо сделать). Перейдя в следующиую функцию я смотрю что выше, найдя чтонибудь интересненькое - ставлю условный бряк и запускаю F9, далее анализирую код по такому же принципу. Если что то пошло не так, возвращаюсь и смотрю если что то было упущено.ПС: В CE не загружается драйвер DBVM, хотя в настройках запуска неподписаные драйвера включил и при попыдки CE подгрузить драйвер винда зависает намертво.Ответ Dark Byte: These are 2 bugreports (dbvmloading, and kernelmode debugging with dbvm not actually loaded) But let's start with the basic one, dbvm (which is what kernelmode relies upon to exist, seeing from the dump it crashes on DR access, which means the interrupt was not captured by dbvm) when you launch dbvm using the about screen. What kind of crash happens? BSOD? Complete freeze? Automatic reboot? Make sure you do not have any virtual machine running at the time of launching dbvm (no vmware, no xp-mode, etc...) Also, what is the name of your cpu (e.g intel core i7 920 etc...)Есть какиенибудь способы проверить запущена ли у меня какая ни будь виртуальная машина?(no vmware, no xp-mode, etc...) Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 25 июня, 2011 Поделиться Опубликовано 25 июня, 2011 >>OllyDbg у меня выдает ошибку ntdll.DbgBreakPoint на винде Win 7 64bitУ меня OllyDbg запускается под Win7 64. У меня две версии OllyDbg, та которая с нашего сайта и последняя с официального сайта OllyDbg. И та и та запускается. Сначала надо запустить игру в конном режиме,а после аттачить его из OllyDbg из меню файла. Если будут остановки из-за исключений, то пропускать их по подсказкам внизу окна Olly или же настроить пропуск исключение из настроек Olly.По повод IDA, всё-таки советую с ним разобраться... он может гораздо удобнее показать код стрелками и связанными блоками, но только после того как будет проанализирован весь исполняемый файл... Так декомпиляция Arrays по горячей клавише F5 покажет псевдокод в удобном представлении. Можно довольно быстро сориентироваться поступает ли указатель прямо из функции или указатель извлекается внутри функции. Тоже самое правда с ошибками делает RecStudio.По поводу DBVM и ошибок из-за виртуальных машин ничего сказать не могу. У меня DBVM не работал лишь один раз при комиляции Cheat Engine из SDK... Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 Просто, и сердито. Бескоенчный ход для всех Своих кроме агентов. Работает, но к сожалению не на той основе которой хотелось бы.[ENABLE]alloc(_inj,2048)label(_ret)_inj:mov [eax+6C],3E7mov edx,[eax]mov ecx,eaxmov eax,[edx+5C]jmp _ret"Shogun2.dll"+12F5C32:jmp _injnopnop_ret:[DISABLE]dealloc(_inj)"Shogun2.dll"+12F5C32:mov edx,[eax]mov ecx,eaxmov eax,[edx+5C]Тот поинтер оказался вобще какойто непобедимый.EAX=EBX-((EBX/[Shogun2.dll+16AB314+4])*[Shogun2.dll+16AB314+4]) // тоесть EAX равен остатку EBX после деления на [Shogun2.dll+16AB314+4][[[[[[Shogun2.dll+16AB314]+EAX*8+04]+33C]+50]+0С]+6C]Но как я уже понял этот поинтер совсем не нужен, надо будет еще посмотреть в этой функции "Shogun2.dll"+12F5C32 должен быть фильтр. До этого я толком не разобравшить взял функцию которая как мне казалось работает только с моими объектами, а эту пропустил мимо. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 О, неплохо ты в этом во всём шаришь...Я установил эту игру, думал быстро разберусь, а не тут-то было (сейчас дел навалом, может быть на недели попробую копнуть).Вот что я предполагаю:Пользователь: Группа1 юнитов на карте: Unit_ID: + ..: +44: одинаковый указатель для "Пользователя" +6c: очки действия // либо здесь конец структуры _+B8: одинаковый указатель для "Пользователя" // либо здесь конец структуры Группа2 юнитов на карте: Unit_ID: + ..: +44: одинаковый указатель для "Пользователя" +6c: очки действия // либо здесь конец структуры _+B8: одинаковый указатель для "Пользователя" // либо здесь конец структуры .... ГруппаN юнитов на карте: Unit_ID: + ..: +44: одинаковый указатель для "Пользователя" +6c: очки действия // либо здесь конец структуры _+B8: одинаковый указатель для "Пользователя" // либо здесь конец структуры БотN: Группа1 юнитов на карте: Unit_ID: + ..: +44: одинаковый указатель для БотN +6c: очки действия // либо здесь конец структуры _+B8: одинаковый указатель для БотN // либо здесь конец структуры Группа2 юнитов на карте: Unit_ID: + ..: +44: одинаковый указатель для БотN +6c: очки действия // либо здесь конец структуры _+B8: одинаковый указатель для БотN // либо здесь конец структуры .... ГруппаN юнитов на карте: Unit_ID: + ..: +44: одинаковый указатель для БотN +6c: очки действия // либо здесь конец структуры _+B8: одинаковый указатель для БотN // либо здесь конец структуры Одна инструкция Shogun2.dll+68DEB2 - 89 50 6C - mov [eax+6C],edxработает со всеми адресами ОД (очками действия). У меня много мыслей как поступить дальше, но пока я ничего писать не буду, т.к. могу запутать. Да, и предполагаю, что указатель в виде скобок написать не получиться, потому что его часть по идее может рассчитываться функцией с логическим условием. Например, перебирать такие-то элементы в пока не дойдём до конца массива и возвратить количество элементов в массиве. Если одна группа сдвинулась на шаг, то очки хода у остальных отнимаются. if (group.move){ anyGroup = getGroups(group) anyGroup.decreaseMove(group.lastMove)}Я уверен, что должен быть почти такой код, а это значит, что скорее всего надо больше внимания обращать на функции и её аргументы. Т.е. надо искать по всему стеку в моменты бряков такие функции , которые работают с группой после хода одной группы... Лучше не заморачиваться с указателямя, а заморачиваться с функциями в дереве вызовов... Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 // Обработчик события клика мышкиvoid OnBtnClick(object sender, MouseArgs args){ GameObject gameObject = nil; // Выбираем объект под курсором мышки gameObject = GetObjectFromMouse(args.x, args.y, argz.z); if (gameObject == nil) // если объекта нет, то проверить был ли выделен объект поьзователя { // Последний выделенныйобъект gameObject = GetlastSelectGameObj(); // Если объект пользователя (!!! вот в этом месте определяется что групаа принадлежит пользователю) if (IsUser(gameObject)) { // то попытаться перенести объект, в данном случае "объект это отряд войска" // в этой функции, где-то там будет проверка на оставшиеся ходы и вычет ходов из остальных отрядов TryMove(gameObject,args.x, args.y, argz.z); } // Если объект не пользователя, то выход return; } seelct(gameObject); // подсветка объекта //...}void TryMove(gameObject,args.x, args.y, argz.z){ //... group = gameObject as GroupClass; //... if (group.move(args.x, args.y, argz.z)) { anyGroup = getGroups(group) anyGroup.decreaseMove(group.lastMove) } // ...}В отладчике надо найти то место, где я отметил восклицательными знаками. Там где выясняется может ли отряд ходить потому что принадлежит пользователю. В OllyDbg надо поставить бряк на обработку щелчка мышки... один бряк поставить на запись очков передвижения... Сделать автоматический трейс по ретам до последнего бряка, и затем отпустить процесс чтобы узнать пересечение участков... и тогда должны выйти под call-ом. Посомтрим выше и должны увидеть код условия о передвижения отряда который принадлежит только нашему герою. написал в теории как смог... Я проверю эту теорию, когда выделю на это время... Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 (изменено) Под пунктом 1: Указатель меняется при перезапускеПод пунктом 2: Адрес на функцию в Shogun2.dll он для всех оденаковый -всегдаПервые 3 - отряда игрока, последние 3 - отряда разных 3-ех ботовСменили фракцию/перезапуск и данные уже не те.Под пунктом 1: Указатель меняется при перезапускеПод пунктом 2: В конечном счете что я там нарыл так это указатель на пренадлежность юнита к фракции. (сразу после String идет пару нуле, а у ботов какие-то цифры - проверял тоже не сработало, при перезапуске или смене фракции все может изменится)Первые 3 - отряда игрока, последние 3 - отряда разных 3-ех ботовСменили фракцию/перезапуск и данные уже не те.Уже все пересравнивал и ничего статичного не нашел.Может это и можно использовать но я понятия не имею как.В OllyDbg надо поставить бряк на обработку щелчка мышки...Подскажите пожалуйста как поставить бряк на обработку щелчка мышки, именно такой о котором идет реч. Изменено 27 июня, 2011 пользователем bronis Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 По поводу указателей, которые ты привёл на картинке я знаю что они меняются с перезапуском игры. Я не акцентировал внимание на это. Это просто небольшая зацепка для дальнейших поисков статичных указателей и "постоянных фильтров". Но пока я не попробовал метод об определении кто свой, а кто чужой с помощью бряка на щелок мышки, лучше с фильтрами не возиться. Я попробую завтра.Как ставить бряк на клик мышью?!Тут полная статья о клике на кнопку, хотя не важно на что кликать... Но лучше чтобы я это сделал, потому что у меня опыта больше. Так что до завтра. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость bronis Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 Я попробую завтра.Спасибо.if (group.move){ anyGroup = getGroups(group) anyGroup.decreaseMove(group.lastMove)}Я уверен, что должен быть почти такой код, а это значит, что скорее всего надо больше внимания обращать на функции и её аргументы. Т.е. надо искать по всему стеку в моменты бряков такие функции , которые работают с группой после хода одной группы... Лучше не заморачиваться с указателямя, а заморачиваться с функциями в дереве вызовов... Может вам понадобится функция упомянутая выше, при выдилении своих армий читает структуры отрядов. Не уверен что это имено то о чем вы говорили, но все же. Shogun2.dll+12F5C32 // Непрерывно читает структуру отряда чей показатель очков действия больше остальных в отряде,// а когда отряд начинает перемещение - функция считывает структуры остальных отрядов.ОффТопик: Вопрос.Извиняюсь что не по теме, хочу задать 2 вопроса по поводу olly v1.10 с офф сайта, слышал у вас есть сборка вашего форума но на самом фурме в разделе олли ее не нашел. 1. Можно ли исправить случай когда олли не распознает команду? А то из за них трассировка прерывается.Проблема именно в самом Olly потому что CE с ней прекрасно справляется! Еще не понятно как все работало до запуска трасировки, никаких таких глюков небыло.2. Также трассировка встает намертво по не понятным причинам на инструкции, а когда нажемаешь паузу то остановка происходит в ntdll на скриншоте в нижней часте - видно. Если нажать step over или step into то дебугер переходит в режим Running.если снова нажать паузу а затем Run то остановимся на бряке который установила трассировка.Это защита такая от трассировки? Как ее обойти подскажите пожалуйста.ПС:Настройки исключений в олли.Но и без этих всех галочек проблема остается. Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 27 июня, 2011 Поделиться Опубликовано 27 июня, 2011 Ребят, вы чего? О_____О Кто же в ИГРЕ пытается обработать подобные нажатия??? В играх, по крайней мере, в большинстве, используется DirectInput (dinput.dll), на него и надо делать хук. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 28 июня, 2011 Поделиться Опубликовано 28 июня, 2011 Откуда такая информация что в большинстве? Лично я в Дисайплс 3 когда-то давно именно таким способом что-то делал и всё работало. На Чемаксе мои посты есть по этому поводу. И никаких хуков на ДайректИнпут я не ставил.//bronis, по заданному вопросу отвечу позже Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 28 июня, 2011 Поделиться Опубликовано 28 июня, 2011 Да, немного оговорился ) Скажем так, в большинстве современных игр применяется DirectInput Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 28 июня, 2011 Поделиться Опубликовано 28 июня, 2011 Это в теории его должны применять в большинстве. На практике могут и не писать такую поддержку, а могут даже наоборот "перестараться" и добавить опцию включения и отключения аппаратного курсора для мышки. Насколько я предполагаю если эта поддержка выключения, то клики будут обрабатываться стандартно от сообщений обрабатываемых в функции привязанной к окну....По теме...Перевел я на псевдокод функцию уменьшающие шаги:int __thiscall sub_10654450(void *this, int a2) void *this - указатель на некоторую структуру Пользователя или бота int a2 - кол-во шагов которое желает выполнить *this return - наверно значение ошибки...Функция перебирает группы привязанные к *this и отнимает шаги перемещения.Эта функция находиться в окрестностях адреса вычитания очков перещения:Shogun2.dll+68DEB2 - 89 50 6C - mov [eax+6C],edxint __thiscall sub_10654450(void *this, int a2){ 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 Cheat_SetPointMove(void *unit, int a2){ int result; // eax@1 char *v3; // ecx@1 int v4; // esi@1 int v5; // eax@2 int v6; // edx@2 v3 = (char *)unit + 148; v4 = *((_DWORD *)v3 + 5); for ( result = v4 + 4 * *((_DWORD *)v3 + 4); v4 != result; result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) { v5 = **(_DWORD **)v4; v6 = *(_DWORD *)(v5 + 0x6C); if ( v6 <= 1000000 ) *(_DWORD *)(v5 + 0x6C) = a2; *(_DWORD *)(v5 + 0x898) = -1; v4 += 4; } return result;}Эта функция обязательно пригодиться, когда при инициализации чита нужно чтобы сарзу всем героям Пользователя дать необходимое кол-во очков например 500000.void units = GetPlayerObjects();Cheat_SetPointMove(void &units, 500000);Дальше нужно не вызывать функцию sub_10654450 если units принадлежит не Player.Для этого нужно изменить sub_10654450:int __thiscall sub_10654450(void *this, int a2){ int result; // eax@1 char *v3; // ecx@1 int v4; // esi@1 int v5; // eax@2 int v6; // edx@2 // инъекция пвсевод-кода void playerUnits = GetPlayerObjects(); if (playerUnits==this) { Cheat_SetPointMove(playerUnits,500000) return; } //===================== 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;}Чтобы функцию перевести на машинныкод, лучше скопироват старую в машинном коде и изменить её.Дальше исследовать пока нет времени. Надо идти вверх по call-ам и разобраться с указателем ecx передаваемым в функцию sub_10654450... Фактически мы должны дойти до развилки имеет ли право идти игрок. Там должен быть код определения игрока. Если это игрок, если его очки хода больше 0, то разрешить ему перемещение.Возможно, будет сложно. Например, один поток который собирает сообщение от ДайректИнпут запишет некоторой новое событие в в некотурую очередь собщений о том что надо пердвинуть отряд, а другой поток будет читать эту очередь...Ладно, дальше будет видно.Что касается вопросов по OllyDbg. OllyDbg видимо снёс Xipho. Поэтому этот вопрос прямо к нему у нас была OllyShadow.Иногда OllyDbg не может обрабатывать инструкции и неизбежно придётся перезагружать процесс игры. И это касается трейсинга. Возможно не повезло. А возможно стоит поставить игнор исключений в настройках. Долго об этом писать.movq вообще интресная инструкция связанная с глюками. Если например она работать с адресом не кратным "как это говорят параграфу", то что-то будет нестабильное... Я думаю если можно как-то в трейсинге отметить что такой-то участок не трейсить, то предлагаю это сделать.По пункту два. Это обычное явление... более прокомментировать как решить проблему с трассировкой не могу, т.к. без понятия. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 28 июня, 2011 Поделиться Опубликовано 28 июня, 2011 Ликбез.На карте Мира могут быть войска Пользователя и ботов. За Пользователя играет Пользователь, за остальных компьютер.Все войска Пользователя разделим на Армии в составе которой есть руководитель. Именно Армии мы можем передвигать на карте Мира.Армию можно делить на отряды по классам: конница, лучники и т.п.Каждый отряд имеет коэффициент усталости. От него зависит дальность хода. Таким образом в Армии быстрые отряды не могут идти дальше чем медленные отряды.Итак, когда Пользователь передвигает Армию, то код игры смотрит принадлежит ли Армия пользователю, если нет, то идти не разрешается, если да, то код игры перебирает отряды и двигает их на расстояние указанное пользователем с вычетом сделанных ходов ранее и вычитом усталости самого уставшего отряда. Если вы что-то не поняли или запутались просто поиграйте в игру и всё поймете. Конница не может оставить лучников в армии, если двигается вся армия...Путь Вхождений моего героя из глубины вверх.Три функции ниже связаны с объектом пользователя или бота и параметром а2 - шагов сколько Армия должна сделать. Именно Армия. При чём неавжно какая армия. И в этих трёх функция не определяется сравнение с Армией пользователя или Бота. Да и важно понимать, что псевдокод может отображать не все параметры передаваемые в функцию.int __thiscall sub_10654450(void *this, int a2){ 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; result = *((_DWORD *)v3 + 5) + 4 * *((_DWORD *)v3 + 4) ) { v5 = **(_DWORD **)v4; // v5 - отряд в Армии v6 = *(_DWORD *)(v5 + 0x6C); if ( v6 <= a2 ) *(_DWORD *)(v5 + 0x6C) = 0; else *(_DWORD *)(v5 + 0x6C) = v6 - a2; // Запись вычитанных шагов shogun2.dll+68DEB2 *(_DWORD *)(v5 + 0x898) = -1; v4 += 4; } return result;}int __thiscall sub_1068B2D0(void *this, int a2){ int result; // eax@1 int i; // edi@1 int v4; // esi@1 void *v5; // edi@1 int v6; // eax@2 v5 = this; (*(void (__stdcall **)(int))(*(_DWORD *)this + 152))(v5, a2); // MasterGH Вхождение 4 в sub_10654450 shogun2.dll+68B2e4 v4 = *((_DWORD *)v5 + 32); result = *((_DWORD *)v5 + 31); for ( i = v4 + 4 * result; v4 != i; v4 += 4 ) { v6 = (*(int (**)(void))(***(_DWORD ***)v4 + 20))() - a2; _ECX = 0; __asm { sets cl } result = (*(int (__stdcall **)(int))(***(_DWORD ***)v4 + 40))((_ECX - 1) & v6); } return result;}void __thiscall sub_103BB8B0(int this, int a2){ int v2; // edi@1 int v3; // esi@1 int v4; // eax@2 int v5; // ecx@5 int v6; // eax@7 v2 = a2; v3 = this; if ( a2 ) { v4 = *(_DWORD *)(this + 700); if ( v4 && *(_DWORD *)v4 ) { if ( v4 ) v5 = *(_DWORD *)v4; else v5 = 0; v6 = sub_104E7A10(v5); if ( a2 >= 0 ) { if ( v6 < a2 ) v2 = v6; } else { v2 = 0; } sub_1068B2D0(v3, v2); // MasterGh вхождение 3 (в sub_1068B2D0) shogun2.dll+3bb900 *(_DWORD *)(v3 + 28) = (*(int (__thiscall **)(int))(*(_DWORD *)v3 + 20))(v3); } else { sub_103670F0(a2); } }}int __thiscall sub_103D8D20(int this){ int result; // eax@1 int v2; // edi@1 __int16 v4; // cx@1 int v6; // eax@1 int v8; // eax@2 int v9; // ecx@2 int v10; // eax@2 _ESI = this; v4 = *(_WORD *)(this + 60); __asm { movq xmm0, qword ptr [esi+24h] } v6 = *(_DWORD *)(_ESI + 44); __asm { movq qword ptr [esi+40h], xmm0 xorps xmm0, xmm0 } *(_WORD *)(_ESI + 76) = v4; *(_DWORD *)(_ESI + 72) = v6; __asm { movss dword ptr [esi+54h], xmm0 movss dword ptr [esi+50h], xmm0 } result = sub_100E0B70(_ESI); v2 = result; if ( result ) { // _ESI - это армия, а (result + 28) это расстояние хода при этом в структуре _ESI уже записаны координаты перемещения (*(void (__stdcall **)(_DWORD))(*(_DWORD *)_ESI + 40))(*(_DWORD *)(_ESI, result + 28)); // MasterGH вхождение 2 ()sub_103BB8B0 shogun2.dll+3D8D61 (**(void (__thiscall ***)(_DWORD, _DWORD))v2)(v2, 1); v10 = *(_DWORD *)(_ESI + 96); v9 = *(_DWORD *)v10; *(_DWORD *)v10 = **(_DWORD **)v10; v8 = *(_DWORD *)(_ESI + 96); if ( *(_DWORD *)v8 ) { *(_DWORD *)(*(_DWORD *)v8 + 4) = v8; result = sub_10F4F0A0(v9); } else { *(_DWORD *)(_ESI + 92) = v8; result = sub_10F4F0A0(v9); } } return result;}int __userpurge sub_10255060<eax>(int a1<ecx>, double a2<st0>, int a3, int a4, char a5){ int v5; // eax@1 char v7; // zf@4 int v8; // ecx@8 int v9; // ecx@10 char v10; // bl@12 int v11; // edi@14 int v12; // ecx@15 int v13; // ecx@17 void (__thiscall *v14)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@17 int result; // eax@19 int v16; // eax@20 int v17; // edx@20 int v18; // ecx@20 int v19; // ebx@23 void (__thiscall *v20)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@27 __int16 v26; // cx@28 __int16 v29; // dx@29 int v30; // eax@29 int v31; // ecx@29 int (__thiscall *v32)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@30 char v33; // al@31 char v34; // zf@32 int v35; // ecx@38 int v36; // eax@40 char v37; // al@44 int v38; // ecx@44 int v39; // edx@44 int v40; // eax@44 int v42; // ecx@44 int v43; // edx@44 int v47; // eax@45 int v48; // ecx@49 int v49; // edx@49 int v50; // eax@49 int v52; // ecx@49 int v53; // edx@49 char v57; // al@52 int v58; // eax@63 char v59; // zf@63 int v60; // edi@64 int v61; // eax@70 int v62; // edi@74 int v63; // ecx@83 int v64; // ebx@83 int v65; // eax@90 int v66; // eax@91 int v68; // eax@94 int v69; // eax@95 int v70; // eax@97 int v71; // edi@97 int v72; // eax@100 int v73; // ebx@101 int v74; // eax@103 int v77; // eax@105 int v78; // ebx@105 int v79; // edi@105 int v80; // eax@108 int v81; // edx@108 int (__thiscall *v82)(_DWORD); // eax@108 int v83; // eax@108 int v86; // eax@110 int v90; // eax@116 int v91; // eax@117 int v92; // ecx@120 __int16 v94; // dx@120 int v95; // eax@120 int v96; // ecx@120 int v98; // ecx@121 void (__thiscall *v100)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@121 int v101; // ecx@121 signed int v102; // ecx@122 signed int v107; // edi@134 int v112; // ecx@141 int *v113; // eax@145 int v114; // eax@146 int *v115; // eax@149 int v116; // eax@150 int v117; // eax@152 int v118; // edi@152 int v119; // eax@155 int v120; // ebx@156 int v121; // eax@158 int v122; // eax@160 int v123; // ebx@160 int v124; // edi@160 int v125; // eax@163 int v126; // edx@163 int (*v127)(void); // eax@163 int v128; // eax@163 int v129; // eax@164 int v134; // ecx@173 int v135; // eax@173 __int16 v136; // dx@173 int v137; // ecx@173 void (__thiscall *v138)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@173 int v139; // ecx@173 int v144; // edi@176 int v150; // eax@177 int v151; // eax@178 int v152; // ecx@180 int v153; // ecx@181 int v154; // eax@184 int v155; // eax@185 int v156; // eax@188 int v157; // edx@189 int v158; // eax@191 int v159; // eax@191 int v160; // eax@192 int v161; // eax@194 char v162; // bl@197 void (__thiscall *v163)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@201 int v164; // edi@202 int v165; // eax@202 int v166; // ecx@203 char v168; // zf@207 int v172; // eax@211 __int16 v174; // cx@211 int v175; // edx@211 int v176; // eax@211 int v178; // eax@213 __int16 v179; // cx@213 int v182; // eax@214 __int16 v183; // dx@214 int v189; // ecx@220 __int16 v190; // dx@220 char v191; // al@221 int v192; // ebx@221 int v194; // ecx@222 int v198; // eax@227 signed int v199; // edi@230 int v200; // eax@232 int v201; // ecx@233 int v202; // ecx@239 int v204; // edx@244 int v209; // edx@246 int v213; // ecx@247 int v214; // esi@251 void (__thiscall *v215)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // edx@255 char v219; // [sp-8h] [bp-B4h]@44 signed int v220; // [sp-4h] [bp-B0h]@27 char v221; // [sp+0h] [bp-ACh]@27 char v222; // [sp+4h] [bp-A8h]@44 __int64 v223; // [sp+8h] [bp-A4h]@27 __int64 v224; // [sp+10h] [bp-9Ch]@27 int *v225; // [sp+18h] [bp-94h]@44 __int64 v226; // [sp+28h] [bp-84h]@4 __int64 v227; // [sp+30h] [bp-7Ch]@28 __int64 v228; // [sp+38h] [bp-74h]@19 __int64 v229; // [sp+40h] [bp-6Ch]@27 __int64 v230; // [sp+48h] [bp-64h]@19 int v231; // [sp+50h] [bp-5Ch]@222 int v232; // [sp+54h] [bp-58h]@28 int v233[2]; // [sp+58h] [bp-54h]@34 int v234[2]; // [sp+60h] [bp-4Ch]@28 int v235; // [sp+68h] [bp-44h]@28 int v236; // [sp+6Ch] [bp-40h]@28 int v237; // [sp+70h] [bp-3Ch]@17 int v238; // [sp+74h] [bp-38h]@17 __int64 v239; // [sp+78h] [bp-34h]@28 int v240; // [sp+80h] [bp-2Ch]@29 __int64 v241; // [sp+84h] [bp-28h]@14 float v242; // [sp+8Ch] [bp-20h]@29 __int64 v243; // [sp+90h] [bp-1Ch]@93 int v244; // [sp+98h] [bp-14h]@93 __int64 v245; // [sp+9Ch] [bp-10h]@110 int v246; // [sp+A4h] [bp-8h]@110 int v247; // [sp+A8h] [bp-4h]@2 _ESI = a1; v5 = *(_DWORD *)(*(_DWORD *)(a1 + 32) + 692); if ( v5 ) v247 = *(_DWORD *)v5; else v247 = 0; v7 = *(_BYTE *)(a1 + 124) == 0; BYTE4(v226) = 0; if ( !v7 ) { if ( !(unsigned __int8)sub_1061F3E0(a1 + 128) ) { BYTE4(v226) = 1; *(_BYTE *)(_ESI + 124) = 0; } if ( *(_BYTE *)(_ESI + 124) ) { v215 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32); v232 = 0; v233[0] = 0; v215(_ESI, 2, &v232, 0, 0); LOBYTE(v228) = 0; HIDWORD(v228) = 0; v230 = 17179869188i64; result = a3; *(_DWORD *)a3 = 2;LABEL_256: __asm { movq xmm0, [esp+90h+var_74] movq qword ptr [eax+4], xmm0 } v229 = 51539607552i64; __asm { movq xmm0, [esp+90h+var_6C] movq qword ptr [eax+0Ch], xmm0 movq xmm0, qword ptr [esp+2Ch] movq qword ptr [eax+14h], xmm0 } *(_DWORD *)(result + 28) = 15; return result; } } v8 = *(_DWORD *)(_ESI + 156); if ( v8 ) (*(void (**)(void))(*(_DWORD *)v8 + 12))(); v9 = *(_DWORD *)(_ESI + 156); v10 = v9 && !(unsigned __int8)(*(int (**)(void))(*(_DWORD *)v9 + 16))(); v11 = sub_100E0B70(_ESI); LODWORD(v241) = v11; if ( v10 ) { sub_105B9910((char *)&v226 + 4, 0, 0); v12 = *(_DWORD *)(_ESI + 156); if ( v12 ) { (**(void (***)(void))v12)(); sub_101B70A0(*(_DWORD *)(_ESI + 156)); } *(_DWORD *)(_ESI + 156) = 0; (*(void (__thiscall **)(int, _DWORD))(*(_DWORD *)_ESI + 28))(_ESI, 0); v14 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32); v237 = 0; v238 = 0; v14(_ESI, 1, &v237, 0, 0); v13 = *(_DWORD *)(_ESI + 156); if ( v13 ) { (**(void (***)(void))v13)(); sub_101B70A0(*(_DWORD *)(_ESI + 156)); *(_DWORD *)(_ESI + 156) = 0; } LOBYTE(v228) = 0; HIDWORD(v228) = 0; v230 = 17179869188i64; result = a3; *(_DWORD *)a3 = 1; goto LABEL_256; } v16 = *(_DWORD *)(_ESI + 92); v18 = *(_DWORD *)(_ESI + 96); v17 = 0; if ( v16 == v18 ) goto LABEL_259; do { v16 = *(_DWORD *)(v16 + 4); ++v17; } while ( v16 != v18 ); if ( v17 ) v19 = *(_DWORD *)(*(_DWORD *)(_ESI + 92) + 8); elseLABEL_259: v19 = 0; if ( sub_100E0B70(_ESI) == v19 && !*(_DWORD *)(_ESI + 156) ) { (*(void (__stdcall **)(_DWORD))(*(_DWORD *)_ESI + 28))(0); v20 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32); v237 = 0; v238 = 0; v20(_ESI, 1, &v237, 0, 0); LOBYTE(v228) = 0; HIDWORD(v228) = 0; __asm { movq xmm0, [esp+90h+var_74] } v230 = 17179869188i64; _EAX = &v221; __asm { movq qword ptr [eax], xmm0 } v229 = 51539607552i64; __asm { movq xmm0, [esp+0ACh+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+48h] } v220 = 1; __asm { movq qword ptr [eax+10h], xmm0 } sub_100E6380(a3, v220, *(__int64 *)&v221, v223, v224, 15); return a3; } v26 = *(_WORD *)(_ESI + 60); __asm { movq xmm0, qword ptr [esi+24h] } _EBX = _ESI + 36; v235 = *(_DWORD *)(_ESI + 44); WORD2(v227) = v26; __asm { movq qword ptr [esp+90h+var_4C], xmm0 } (*(void (__thiscall **)(int, int *))(*(_DWORD *)v11 + 32))(v11, &v232); HIDWORD(v239) = (*(int (__thiscall **)(int, _DWORD))(*(_DWORD *)v11 + 36))(v11, *(_DWORD *)(_ESI + 32)); BYTE3(v236) = 0; if ( BYTE4(v226) ) { __asm { movq xmm0, qword ptr [esi+80h] } v29 = *(_WORD *)(_ESI + 140); v30 = *(_DWORD *)(_ESI + 144); v235 = *(_DWORD *)(_ESI + 136); v31 = *(_DWORD *)(_ESI + 148); __asm { movq qword ptr [esp+90h+var_4C], xmm0 movss xmm0, dword ptr [esi+98h] } WORD2(v227) = v29; HIDWORD(v239) = v30; __asm { movss [esp+90h+var_20], xmm0 } v240 = v31; } else { v32 = *(int (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)v11 + 64); ++*(_DWORD *)(v11 + 36); v240 = v32(v11, a4, v234, (char *)&v227 + 4, (char *)&v236 + 3); (*(void (__thiscall **)(int))(*(_DWORD *)v11 + 44))(v11); v242 = a2; } v33 = sub_10571DF0(v234, _ESI + 36); if ( !v33 || (v34 = WORD2(v227) == *(_WORD *)(_ESI + 60), BYTE4(v241) = 0, !v34) ) BYTE4(v241) = 1; v233[1] = 0; BYTE4(v226) = HIDWORD(v239) != 12; if ( !BYTE3(v236) ) goto LABEL_61; if ( !(HIDWORD(v239) != 12) ) goto LABEL_68; if ( v33 || v240 != 2 ) {LABEL_61: if ( !BYTE4(v226) || v240 == 3 ) goto LABEL_68; goto LABEL_63; } v35 = *(_DWORD *)(_ESI + 32); if ( *(_BYTE *)(v35 + 419) ) { if ( *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(v35 + 396) + 8) + 5420) + 160) == _ESI ) { v36 = ((int (*)(void))sub_101F4F90)(); LOBYTE(v36) = !(_BYTE)v36 && (v36 = sub_1026C750(*(_DWORD *)(_ESI + 32)), !(_BYTE)v36); v38 = *(_DWORD *)(_ESI + 32); v39 = *(_DWORD *)(*(_DWORD *)(v38 + 396) + 8); *(float *)&v225 = 3.402823466385289e38; HIDWORD(v224) = v36; v40 = sub_1042BF80(v38, v39); __asm { movq xmm0, qword ptr [esp+98h+var_4C] } v42 = v235; v43 = *(_DWORD *)(_ESI + 44); LODWORD(v224) = v40; _EAX = &v222; __asm { movq qword ptr [eax], xmm0 movq xmm0, qword ptr [ebx] } HIDWORD(v223) = v42; _EAX = &v219; __asm { movq qword ptr [eax], xmm0 } v37 = sub_1060ADE0(v219, v220, v43, v222, v223, HIDWORD(v223), v224, HIDWORD(v224), (char)v225); } else { v47 = ((int (*)(void))sub_101F4F90)(); LOBYTE(v47) = !(_BYTE)v47 && (v47 = sub_1026C750(*(_DWORD *)(_ESI + 32)), !(_BYTE)v47); v48 = *(_DWORD *)(_ESI + 32); v49 = *(_DWORD *)(*(_DWORD *)(v48 + 396) + 8); *(float *)&v225 = 3.402823466385289e38; HIDWORD(v224) = v47; v50 = sub_1042BF80(v48, v49); __asm { movq xmm0, qword ptr [esp+98h+var_4C] } v52 = v235; v53 = *(_DWORD *)(_ESI + 44); LODWORD(v224) = v50; _EAX = &v222; __asm { movq qword ptr [eax], xmm0 movq xmm0, qword ptr [ebx] } HIDWORD(v223) = v52; _EAX = &v219; __asm { movq qword ptr [eax], xmm0 } v37 = sub_10157500(v219, v220, v53, v222, v223, HIDWORD(v223), v224, HIDWORD(v224), (char)v225); } BYTE4(v226) = v37; if ( !v37 ) { if ( v232 ) { v57 = sub_10697F40(*(_DWORD *)(_ESI + 32), v232, 3.402823466385289e38); } else { if ( !v233[0] ) goto LABEL_68; v57 = sub_10206660(*(_DWORD *)(_ESI + 32), v233[0], 3.402823466385289e38); }LABEL_60: BYTE4(v226) = v57; goto LABEL_61; } } else { BYTE4(v226) = sub_106BA160(_ESI, _ESI + 36, (int)v234, 3.402823466385289e38); if ( !BYTE4(v226) ) { if ( v232 ) { v57 = sub_103B31E0(_ESI, *(_DWORD *)(_ESI + 32), v232, 3.402823466385289e38); } else { if ( !v233[0] ) goto LABEL_68; v57 = sub_10678EA0(_ESI, *(_DWORD *)(_ESI + 32), v233[0], 3.402823466385289e38); } goto LABEL_60; } }LABEL_63: v59 = (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v241 + 4))() == 0; v58 = *(_DWORD *)(_ESI + 156); if ( v59 ) { v225 = &v233[1]; HIDWORD(v224) = HIDWORD(v241); } else { v60 = HIDWORD(v241); v237 = 0; v238 = 0; BYTE4(v226) = sub_10559C70(_ESI, v234, HIDWORD(v239), &v237, v58, SBYTE4(v241), &v233[1]); if ( BYTE4(v226) ) goto LABEL_68; v58 = *(_DWORD *)(_ESI + 156); v225 = &v233[1]; HIDWORD(v224) = v60; } BYTE4(v226) = sub_10144A00(_ESI, v234, HIDWORD(v239), &v232, v58, HIDWORD(v224), v225);LABEL_68: if ( !BYTE4(v241) ) goto LABEL_221; if ( (unsigned __int8)sub_10571DF0(v234, _ESI + 36) ) goto LABEL_114; v61 = *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8); if ( *(_DWORD *)(*(_DWORD *)(v61 + 5420) + 160) != _ESI ) { if ( v233[1] == 3 ) { v92 = v235; __asm { movq xmm0, qword ptr [esp+90h+var_4C] } v94 = WORD2(v227); v95 = HIDWORD(v239); __asm { movq qword ptr [esi+80h], xmm0 } *(_DWORD *)(_ESI + 136) = v92; v96 = v240; *(_WORD *)(_ESI + 140) = v94; *(_DWORD *)(_ESI + 144) = v95; *(_DWORD *)(_ESI + 148) = v96;LABEL_121: __asm { movss xmm0, [esp+90h+var_20] } v100 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32); v225 = 0; HIDWORD(v224) = 0; LODWORD(v224) = &v232; HIDWORD(v223) = 2; v101 = _ESI; *(_BYTE *)(_ESI + 124) = 1; __asm { movss dword ptr [esi+98h], xmm0 } v100(v101, HIDWORD(v223), v224, HIDWORD(v224), v225); LOBYTE(v228) = 0; HIDWORD(v228) = 0; v98 = 0; v230 = 17179869188i64; _EAX = &v221; v220 = 2; goto LABEL_122; } if ( v233[1] != 1 && (v233[1] != 2 || (unsigned __int8)sub_106AC630(*(_DWORD *)(v61 + 5428))) ) goto LABEL_114; __asm { movq xmm0, qword ptr [esp+90h+var_4C] movq [esp+90h+var_1C], xmm0 } v244 = v235; if ( v233[1] == 1 && !(unsigned __int8)(*(int (__thiscall **)(_DWORD, __int64 *))(*(_DWORD *)v241 + 60))(v241, &v243) ) { BYTE4(v226) = 0; goto LABEL_114; } v225 = *(int **)(_ESI + 32); sub_103CCAB0(v225); if ( *(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5420) + 160) || v233[1] == 1 && !(unsigned __int8)sub_100C9AB0(&v243, HIDWORD(v239)) ) { __asm { movq xmm0, qword ptr [esp+90h+var_4C] } v134 = v235; v135 = HIDWORD(v239); v136 = WORD2(v227); v225 = 0; __asm { movq qword ptr [esi+80h], xmm0 movss xmm0, [esp+94h+var_20] } *(_DWORD *)(_ESI + 136) = v134; v137 = v240; *(_DWORD *)(_ESI + 144) = v135; HIDWORD(v224) = 0; *(_WORD *)(_ESI + 140) = v136; v138 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32); LODWORD(v224) = &v232; *(_DWORD *)(_ESI + 148) = v137; HIDWORD(v223) = 2; v139 = _ESI; *(_BYTE *)(_ESI + 124) = 1; __asm { movss dword ptr [esi+98h], xmm0 } v138(v139, HIDWORD(v223), v224, HIDWORD(v224), v225); LOBYTE(v228) = 0; HIDWORD(v228) = 0; __asm { movq xmm0, [esp+90h+var_74] } v229 = 51539607552i64; v230 = 17179869188i64; _EAX = &v221; __asm { movq qword ptr [eax], xmm0 movq xmm0, [esp+0ACh+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+48h] } v220 = 2; __asm { movq qword ptr [eax+10h], xmm0 } sub_100E6380(a3, v220, *(__int64 *)&v221, v223, v224, 15); sub_103D7930(v238); return a3; } sub_103D7930(v238); v107 = 2; if ( v233[1] == 2 ) { if ( v232 ) { _EAX = sub_101FFC00(v232); __asm { movq xmm0, qword ptr [eax] movq [esp+90h+var_1C], xmm0 } v244 = *(_DWORD *)(_EAX + 8); } else { if ( v233[0] ) { _EAX = (*(int (**)(void))(*(_DWORD *)v233[0] + 72))(); __asm { movq xmm0, qword ptr [eax] movq [esp+90h+var_1C], xmm0 } v244 = *(_DWORD *)(_EAX + 8); } } if ( (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32)) || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) ) { v112 = *(_DWORD *)(_ESI + 156); if ( !v112 || (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v112 + 44))() ) { if ( !(dword_119076D8 & 2) ) { dword_119076D8 |= 2u; dword_119076BC = 0; dword_119076C0 = 0; dword_119076C4 = 0; atexit(sub_11338E60); } v113 = *(int **)(*(_DWORD *)(_ESI + 32) + 692); if ( v113 ) v114 = *v113; else v114 = 0; v237 = v114; sub_1008A5C0(&v237); if ( v232 ) { v115 = *(int **)(v232 + 692); if ( v115 ) v116 = *v115; else v116 = 0; v237 = v116; sub_1008A5C0(&v237); v118 = *(_DWORD *)(_ESI + 32); v237 = v232; v117 = *(_DWORD *)(v232 + 692); if ( v117 ) LODWORD(v227) = *(_DWORD *)v117; else LODWORD(v227) = 0; v119 = *(_DWORD *)(v118 + 692); if ( v119 ) v120 = *(_DWORD *)v119; else v120 = 0; v121 = (*(int (__thiscall **)(int))(*(_DWORD *)_ESI + 36))(_ESI); sub_1061B980(v120, v227, v118, v237, &unk_119076B8, v121); } else { if ( v233[0] ) { v237 = (*(int (**)(void))(*(_DWORD *)v233[0] + 16))(); sub_1008A5C0(&v237); v124 = *(_DWORD *)(_ESI + 32); v122 = *(_DWORD *)(v124 + 692); v123 = v233[0]; if ( v122 ) LODWORD(v227) = *(_DWORD *)v122; else LODWORD(v227) = 0; v125 = (*(int (__thiscall **)(int))(*(_DWORD *)_ESI + 36))(_ESI); v126 = *(_DWORD *)v123; v225 = (int *)v125; v127 = *(int (**)(void))(v126 + 16); HIDWORD(v224) = &unk_119076B8; LODWORD(v224) = v123; HIDWORD(v223) = v124; v128 = v127(); sub_10505740(v227, v128, HIDWORD(v223), v224, HIDWORD(v224), v225); } } v129 = *(_DWORD *)(_ESI + 156); __asm { movq xmm0, qword ptr [esp+90h+var_4C] movq [esp+90h+var_10], xmm0 } v246 = v235; if ( v129 ) { if ( *(_DWORD *)(v129 + 8) ) { _EAX = sub_10628480(&v237); __asm { movq xmm0, qword ptr [eax] movq [esp+90h+var_10], xmm0 } v246 = *(_DWORD *)(_EAX + 8); } } sub_10197970(&v243, &v245, &unk_119076B8); dword_119076C0 = 0; v107 = 2; } } } sub_1060F240(_ESI, &v243, v233[1]); if ( !(unsigned __int8)(*(int (**)(void))(*(_DWORD *)v241 + 4))() || v233[1] != v107 || (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32)) || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) ) goto LABEL_114; goto LABEL_172; } if ( !BYTE4(v226) ) goto LABEL_114; if ( v233[1] == 3 || !v233[1] ) { sub_100FF540(_ESI); goto LABEL_114; } v62 = v241; if ( (unsigned __int8)(*(int (__thiscall **)(_DWORD))(*(_DWORD *)v241 + 4))(v241) && v233[1] == 2 ) { if ( (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32)) || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) ) { if ( !(unsigned __int8)sub_105B8700(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428)) ) goto LABEL_81; if ( sub_104034F0(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428)) != *(_DWORD *)(_ESI + 32) ) { v62 = v241; goto LABEL_81; } }LABEL_172: *(_BYTE *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5420) + 180) = 1; goto LABEL_114; }LABEL_81: if ( (unsigned __int8)sub_101F4F90(*(_DWORD *)(_ESI + 32)) || (unsigned __int8)sub_1026C750(*(_DWORD *)(_ESI + 32)) ) { v63 = *(_DWORD *)(_ESI + 156); v64 = 0; if ( !v63 || (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v63 + 44))() ) { if ( (v233[1] == 2 || (unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v62 + 4))(v62)) && (unsigned __int8)sub_105FD3D0(2) ) { if ( !(dword_119076D8 & 1) ) { dword_119076D8 |= 1u; dword_119076CC = 0; dword_119076D0 = 0; dword_119076D4 = 0; atexit(sub_11338E80); } v65 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692); if ( v65 ) v66 = *(_DWORD *)v65; else v66 = 0; LODWORD(v227) = v66; sub_1008A5C0(&v227); __asm { movq xmm0, qword ptr [esp+90h+var_4C] movq [esp+90h+var_1C], xmm0 } v244 = v235; if ( v232 ) { v68 = *(_DWORD *)(v232 + 692); if ( v68 ) v69 = *(_DWORD *)v68; else v69 = 0; LODWORD(v227) = v69; sub_1008A5C0(&v227); v71 = *(_DWORD *)(_ESI + 32); v237 = v232; v70 = *(_DWORD *)(v232 + 692); if ( v70 ) LODWORD(v227) = *(_DWORD *)v70; else LODWORD(v227) = 0; v72 = *(_DWORD *)(v71 + 692); if ( v72 ) v73 = *(_DWORD *)v72; else v73 = 0; v74 = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)_ESI + 36))(_ESI); sub_1061B980(v73, v227, v71, v237, &unk_119076C8, v74); _EAX = sub_101FFC00(v232); __asm { movq xmm0, qword ptr [eax] movq [esp+90h+var_1C], xmm0 } v244 = *(_DWORD *)(_EAX + 8); } else { if ( !v233[0] ) {LABEL_110: v86 = *(_DWORD *)(_ESI + 156); __asm { movq xmm0, qword ptr [esp+90h+var_4C] movq [esp+90h+var_10], xmm0 } v246 = v235; if ( v86 != v64 ) { if ( *(_DWORD *)(v86 + 8) != v64 ) { _EAX = sub_10628480(&v237); __asm { movq xmm0, qword ptr [eax] movq [esp+90h+var_10], xmm0 } v246 = *(_DWORD *)(_EAX + 8); } } sub_10197970(&v243, &v245, &unk_119076C8); dword_119076D0 = v64; goto LABEL_114; } v237 = (*(int (**)(void))(*(_DWORD *)v233[0] + 16))(); sub_1008A5C0(&v237); v78 = *(_DWORD *)(_ESI + 32); v77 = *(_DWORD *)(v78 + 692); v79 = v233[0]; if ( v77 ) LODWORD(v227) = *(_DWORD *)v77; else LODWORD(v227) = 0; v80 = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)_ESI + 36))(_ESI); v81 = *(_DWORD *)v79; v225 = (int *)v80; HIDWORD(v224) = &unk_119076C8; LODWORD(v224) = v79; v82 = *(int (__thiscall **)(_DWORD))(v81 + 16); HIDWORD(v223) = v78; v83 = v82(v79); sub_10505740(v227, v83, HIDWORD(v223), v224, HIDWORD(v224), v225); _EAX = (*(int (**)(void))(*(_DWORD *)v233[0] + 72))(); __asm { movq xmm0, qword ptr [eax] movq [esp+90h+var_1C], xmm0 } v244 = *(_DWORD *)(_EAX + 8); } v64 = 0; goto LABEL_110; } } }LABEL_114: if ( (unsigned __int8)(*(int (__thiscall **)(_DWORD))(*(_DWORD *)_ESI + 36))(_ESI) ) { if ( !(unsigned __int8)sub_10571DF0(v234, _ESI + 36) ) { v90 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692); if ( v90 ) v91 = *(_DWORD *)v90; else v91 = 0; if ( !(unsigned __int8)sub_10453D70(v91) ) { __asm { movss xmm0, ds:dword_113C3980 cvtsi2ss xmm1, [esp+90h+var_4C+4] mulss xmm1, xmm0 movss [esp+90h+var_3C], xmm1 cvtsi2ss xmm1, [esp+90h+var_44] mulss xmm1, xmm0 movss [esp+90h+var_38], xmm1 } v144 = sub_104CA9E0(&v237); if ( v144 ) { v150 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692); if ( v150 ) v151 = *(_DWORD *)v150; else v151 = 0; v152 = *(_DWORD *)(v144 + 248); if ( v152 ) v153 = *(_DWORD *)v152; else v153 = 0; if ( (unsigned __int8)sub_105DE830(v153, v151) ) { v154 = *(_DWORD *)(v144 + 248); if ( v154 ) v155 = *(_DWORD *)v154; else v155 = 0; if ( !(unsigned __int8)sub_10453D70(v155) ) { v156 = *(_DWORD *)(v144 + 248); if ( v156 ) v157 = *(_DWORD *)v156; else v157 = 0; v159 = sub_103573E0(v157); sub_10643AA0(v159); v158 = *(_DWORD *)(*(_DWORD *)(_ESI + 32) + 692); if ( v158 ) v160 = *(_DWORD *)v158; else v160 = 0; v161 = sub_103573E0(v160); sub_10643AA0(v161); } } } } } } v225 = *(int **)(_ESI + 32); sub_105403B0(v225); (*(void (__thiscall **)(int, _DWORD))(*(_DWORD *)_ESI + 28))(_ESI, 0); LOBYTE(v227) = 0; if ( (unsigned __int8)sub_101758E0(v234, _ESI) ) { BYTE4(v226) = 0; LOBYTE(v227) = 1; } v162 = 0; if ( sub_10D28370(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428) + 84) != 1 ) { if ( !BYTE4(v226) ) goto LABEL_200; if ( (unsigned __int8)sub_1061F3E0(v234) ) { v172 = v235; __asm { movq xmm0, qword ptr [esp+90h+var_4C] } v174 = WORD2(v227); v175 = HIDWORD(v239); __asm { movq qword ptr [esi+80h], xmm0 } *(_DWORD *)(_ESI + 136) = v172; v176 = v240; *(_WORD *)(_ESI + 140) = v174; *(_DWORD *)(_ESI + 144) = v175; *(_DWORD *)(_ESI + 148) = v176; goto LABEL_121; } if ( a5 ) { __asm { movq xmm0, qword ptr [esi+24h] } v178 = *(_DWORD *)(_ESI + 44); *(float *)(_ESI + 84) = *(float *)(_ESI + 80); v179 = *(_WORD *)(_ESI + 60); __asm { movq qword ptr [esi+40h], xmm0 } *(_DWORD *)(_ESI + 72) = v178; *(_WORD *)(_ESI + 76) = v179; } __asm { movq xmm0, qword ptr [esp+90h+var_4C] } v182 = v235; v183 = WORD2(v227); __asm { movq qword ptr [esi+24h], xmm0 movss xmm0, [esp+90h+var_20] } *(_DWORD *)(_ESI + 44) = v182; *(_WORD *)(_ESI + 60) = v183; *(_DWORD *)(_ESI + 172) = 0; _EAX = *(_DWORD *)(_ESI + 156); __asm { movss dword ptr [esi+50h], xmm0 } if ( _EAX ) { __asm { comiss xmm0, dword ptr [eax+0Ch] } if ( !(_CF | _ZF) ) __asm { movss dword ptr [eax+0Ch], xmm0 } } if ( *(_BYTE *)(_ESI + 62) == 1 || v240 == 2 || v240 == 3 ) { __asm { movq xmm0, qword ptr [esi+24h] } v189 = *(_DWORD *)(_ESI + 44); *(float *)(_ESI + 84) = *(float *)(_ESI + 80); v190 = *(_WORD *)(_ESI + 60); __asm { movq qword ptr [esi+40h], xmm0 } *(_BYTE *)(_ESI + 62) = 0; *(_DWORD *)(_ESI + 72) = v189; *(_WORD *)(_ESI + 76) = v190; }LABEL_221: v192 = v241; v191 = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)v241 + 4))(v241); if ( v191 ) // MASTERGH возможно ключевой момент, возможно условия выделеная ли Армия пользователя? { while ( 1 ) //mastergh возможно цикл когда Выделена Армия пользователя { (*(void (__thiscall **)(int, __int64 *))(*(_DWORD *)v192 + 16))(v192, &v228); __asm { movq xmm0, [esp+90h+var_74] } v194 = v231; _EAX = &v221; __asm { movq qword ptr [eax], xmm0 movq xmm0, [esp+0ACh+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+48h] movq qword ptr [eax+10h], xmm0 } sub_10339480(v221, *(_DWORD *)&v222, v223, HIDWORD(v223), v224, HIDWORD(v224), v194); if ( !HIDWORD(v230) ) { v102 = v231; _EAX = &v221; v220 = 3; goto LABEL_123; } if ( (_BYTE)v228 ) { __asm { movq xmm0, [esp+90h+var_74] } v204 = v231; _EAX = &v221; __asm { movq qword ptr [eax], xmm0 movq xmm0, [esp+0ACh+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+48h] movq qword ptr [eax+10h], xmm0 } v225 = (int *)v204; v220 = 4; goto LABEL_124; LABEL_230; // masterGH - выход на LABEL_124 } if ( HIDWORD(v230) == 3 ) { sub_103D8D20(_ESI); // mastergh - кщё функция v102 = v231; _EAX = &v221; v220 = 5; goto LABEL_123; // masterGH - выход на LABEL_123 } if ( HIDWORD(v230) == 1 || HIDWORD(v229) != 12 ) break; sub_103D8D20(_ESI); // mastergh (1 вхождение) (в sub_103D8D20) : shogun2.dll+25635e v198 = sub_100E0B70(_ESI); v192 = v198; if ( v198 && !(unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v198 + 4))(v198) ) { v191 = v192 == sub_1031A3A0(_ESI); goto LABEL_230; // masterGH - выход на LABEL_230 } } sub_103D8D20(_ESI); // mastergh функция __asm { movq xmm0, [esp+90h+var_74] } v209 = v231; _EAX = &v221; __asm { movq qword ptr [eax], xmm0 movq xmm0, [esp+0ACh+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+48h] movq qword ptr [eax+10h], xmm0 } v225 = (int *)v209; v220 = 6; goto LABEL_124; // mastergh выход на LABEL_124 }LABEL_230: v199 = 0; if ( v191 ) v199 = 1; v200 = sub_1031A3A0(_ESI); if ( v192 == v200 ) { v201 = *(_DWORD *)(_ESI + 156); if ( v201 ) { v200 = (*(int (**)(void))(*(_DWORD *)v201 + 20))(); if ( (_BYTE)v200 ) v199 = 1; } } if ( BYTE4(v241) || v199 == 1 ) { LOBYTE(v200) = BYTE4(v241) == 0; (*(void (__thiscall **)(int, signed int, int *, int, _DWORD))(*(_DWORD *)_ESI + 32))(_ESI, v199, &v232, v200, 0); } v202 = *(_DWORD *)(_ESI + 156); if ( v202 && (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v202 + 4))() ) { if ( (unsigned __int8)sub_101B70A0(*(_DWORD *)(_ESI + 156)) ) *(_DWORD *)(_ESI + 156) = 0; } else { v213 = *(_DWORD *)(_ESI + 156); if ( !v213 || (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v213 + 16))() ) { if ( v192 == sub_1031A3A0(_ESI) ) { v214 = *(_DWORD *)(_ESI + 156); if ( v214 ) { if ( (unsigned __int8)(*(int (__thiscall **)(int))(*(_DWORD *)v214 + 24))(v214) ) v199 = 1; } } } else { sub_101B70A0(*(_DWORD *)(_ESI + 156)); *(_DWORD *)(_ESI + 156) = 0; } } HIDWORD(v228) = 0; v98 = 0; v230 = 17179869188i64; _EAX = &v221; LOBYTE(v228) = 0; v220 = v199;LABEL_122: LODWORD(v229) = v98; v102 = 15; HIDWORD(v229) = 12;LABEL_123: __asm { movq xmm0, [esp+0B0h+var_74] movq qword ptr [eax], xmm0 movq xmm0, [esp+0B0h+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+4Ch] movq qword ptr [eax+10h], xmm0 } *((_DWORD *)_EAX + 6) = v102;LABEL_124: sub_100E6380(a3, v220, *(__int64 *)&v221, v223, v224, v225); return a3; } v162 = 1;LABEL_200: sub_1059DCD0( (char *)&v226 + 4, 0, v227, *(_BYTE *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5420) + 61), 0); if ( BYTE5(v226) ) { v163 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)_ESI + 32); v225 = 0; HIDWORD(v224) = 0; LODWORD(v224) = &v232; HIDWORD(v223) = 0; } else { v164 = *(_DWORD *)_ESI + 32; v165 = sub_105B8700(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(*(_DWORD *)(_ESI + 32) + 396) + 8) + 5428)); v163 = *(void (__thiscall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))v164; v225 = (int *)v165; HIDWORD(v224) = 0; LODWORD(v224) = &v232; HIDWORD(v223) = 1; } v163(_ESI, HIDWORD(v223), v224, HIDWORD(v224), v225); v166 = *(_DWORD *)(_ESI + 156); if ( v166 ) (**(void (***)(void))v166)(); if ( !v162 ) { v225 = *(int **)(_ESI + 32); sub_100554B0(v225); } HIDWORD(v228) = 0; LOBYTE(v228) = 0; __asm { movq xmm0, [esp+90h+var_74] } v168 = BYTE5(v226) == 0; v229 = 51539607552i64; v230 = 17179869188i64; _EAX = &v221; __asm { movq qword ptr [eax], xmm0 movq xmm0, [esp+0ACh+var_6C] movq qword ptr [eax+8], xmm0 movq xmm0, qword ptr [esp+48h] movq qword ptr [eax+10h], xmm0 } v225 = (int *)15; if ( v168 ) { sub_100E6380(a3, 1, *(__int64 *)&v221, v223, v224, v225); result = a3; } else { sub_100E6380(a3, 0, *(__int64 *)&v221, v223, v224, v225); result = a3; } return result;} Осталось только проверить в отладке моё предположение о том выделен лы был игрок. Но это я сделаю не сегодня. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения