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

[Shogun 2: Total War] Бесконечный ход


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

Игра: 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] // помещает значение ОД в edx
4. cmp edx,edi
5. 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],edx

2. Shogun2.dll+22CA17 // mov [eax+6C],00000000

Поставив бряки на данные инструкции мы сможем найти структуры юнитов и их ОД, в том числе и вражеские юниты (кроме агентов)

Цели: Создать инжект код на бесконечный ход с фильтром только для своих юнитов, проблема в том что не удается найти отличительную черту по которой можно было бы составить условие тем самым отсеяв всех лишних юнитов. Что я только не пытался делать, пытался анализировать код в обратном порядке в надежде понять как игра получает адреса на структуры юнитов но ничего не вышло. Пытался сравнивать структуры вражеских юнитов и моих с целью найти какие ни будь байты по которым можно было б отличить своих от чужих но опять же ничего не получилось. Может кто ни будь знает какой ни будь способ

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

Если я не понял вопрос, то извините. Я бы сделал так:

1. Нашёл адрес ходов

2. Боставил бы бряк на чтение

3. Из всех возможных инструкций постарался узнать с какими адресами они работают

4. Повезёт если есть инстр. отвечающая за мой ход. Другая отвечающая за ход врага.

5. Если одна отвечает за ходы меня и врага, то тут надо уже делать фильтр(что я собственно и не умею делать)

Что у вас? 5ый случай или 4ый?

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

Нашел в вашей статье пример на эту тему, и удалось найти описываемую там функцию она тоже читает адрес дальности хода и работает только с игроком. Сейчас пытаюсь в ней что ни будь найти.

Medieval 2: Total War

Для того чтобы трейнер был универсальным, нужно вытащить _pID из инструкции типа А. _pID должен указывать на то, что объекты расы наши.

Инструкцию берём такую, которая работает при наведении курсора мыши на только нашего юнита, это как раз та инструкция которая читала адрес дальности хождения юнита. Она читает только юниты нашей расы.

Код: Бряк сработал на Shogun2.dll+61DDA5


58D5DD8A - 8B 87 B0080000 - mov eax,[edi+000008B0]
58D5DD90 - 85 C0 - test eax,eax
58D5DD92 - 74 04 - je 58D5DD98
58D5DD94 - 8B 00 - mov eax,[eax]
58D5DD96 - EB 02 - jmp 58D5DD9A
58D5DD98 - 33 C0 - xor eax,eax
58D5DD9A - 85 C0 - test eax,eax
58D5DD9C - 0F95 C1 - setnc cl
58D5DD9F - 88 8E C4000000 - mov [esi+000000C4],cl
>>58D5DDA5 - 8B 57 6C - mov edx,[edi+6C] // место останова
58D5DDA8 - 89 96 C8000000 - mov [esi+000000C8],edx
58D5DDAE - 8B 07 - mov eax,[edi]
58D5DDB0 - 8B 50 38 - mov edx,[eax+38]
58D5DDB3 - 8B CF - mov ecx,edi
58D5DDB5 - FF D2 - call edx
58D5DDB7 - 8B 48 64 - mov ecx,[eax+64]
58D5DDBA - 85 C9 - test ecx,ecx
58D5DDBC - F3 0F10 05 A023B959 - movss xmm0,[59B923A0] : [(float)1.0000]
58D5DDC4 - 74 21 - je 58D5DDE7
58D5DDC6 - 83 39 00 - cmp dword ptr [ecx],00

Регистры и Стек

1308830799-clip-3kb.png1308830881-clip-4kb.png

Izmalkoff

Инструкций работающих с адресами очков действия (игрока и врагов) для ряда юнитов которых я рассматриваю всего 2 шт и они находятся в одной функции, я их описал в первом посте. А остальные что читатют ячейки данных с очками действия я в данный момент рассматриваю на предмет интересностей =)

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

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:
pushf
pushad
mov edx,[Shogun2.dll+019C0D94]
mov edx,[edx+041C]
mov edx,[edx+08]
mov edx,[edx+24]
mov edx,[edx+04]
add edx,478
mov eax,ecx
add eax,0000046C
cmp eax,edx
jne short _back
mov dword ptr [ecx+0000046C],#12345
_back:
popad
popf
mov eax,[ecx+0000046C]
jmp _exit

"Shogun2.dll"+840D0:
jmp _inj
nop
_exit:

[DISABLE]
dealloc(_inj)
"Shogun2.dll"+840D0:
mov eax,[ecx+0000046C]

Shogun2.dll+61DDA5 Чертертый пост в попытках найти код в котором формируется указатель на структуру юнита я дошел инструкции(Shogun2.dll+65765E) которая извлекает указатель из стека, но к сожалению олли в моей винде не работает должным образом =( защита виндоуз закрывает процес при атаче его из олли, хотел поставить условный бряк но не судьба. Лимит моего мозга исчерпан, уже не соображаю, чем больше смотрю в код тем больше понимаю что ничего не понимаю - ушел спать.

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

В посте номер 4. Есть строка кода:

58D5DD9F - 88 8E C4000000     		- mov [esi+000000C4],cl

Определите какие адреса проскакивают в квадратных скобках. Это можно сделать из меню дизассемблера функцией "Find out what addresses this code accesses".

image3005.jpg

Если адрес будет проскакивать один, то это хорошо. Если больше двух, то ищем указатель уровня выше (который что-то писал в esi). На адрес указателя "уровня выше" ставим бряк на доступ и определяем прервавшиеся инструкции. На них также определяем проскакивающие адреса... Если найдётся один адрес, то к нему можно обращаться как фильтру...

Может быть я запутанно написал, но пока ничем больше помочь не могу.

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

Если адрес будет проскакивать один, то это хорошо. Если больше двух, то ищем указатель уровня выше (который что-то писал в esi). На адрес указателя "уровня выше" ставим бряк на доступ и определяем прервавшиеся инструкции. На них также определяем проскакивающие адреса... Если найдётся один адрес, то к нему можно обращаться как фильтру...

Может быть я запутанно написал, но пока ничем больше помочь не могу.

Еще как запутано =) Но тем неменее я признателен хотяб за такие наставления!

К сожалению адресов проскакивающих в функции mov [esi+000000C4],cl оказалось больше двух, вот только я не совсем понял что дальше делать. Стал просматривать код выше на предмет записи чего либо в ESI или по его адресу который он формерует, нашел запись по адресу esi+44 колво юнитов в отряде, и решил уточнить что такое "указатель уровня выше". Мне надо искать указатель на адрес ESI как при поиске поинтера? или надо искать все что ранее записывалось в ESI и на эти инструкции ставить такойже бряк на доступ?

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

В сам ESI данные помещаются из стека, и в основном в [esi+xxx] записываются разные данные. А волнует меня то что адреса которые проскакивают через этот esi разные даже для одного и тогоже юнита, я так пологаю что в esi помещается адрес копии структуры данных юнита и эта копия меняет свое расположение чуть ли не каждые 10 сек, может я ошибаюсь и это не копия но во всяком случае адреса через esi всегда разные таким образом просканил гдето штук 30 инструкций в которых использовалось esi и всегда всплывали разные адреса.

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

Там гед я писал слово "уровень" это относилось к некоторому указателю в цепочки указателей...

Код игры прекрасно знает кто пользователь, а кто Бот. Это нужно всегда помнить.

Ищите зацепки в коде, в бряках на уровнях указателей, в структурах указателей. По крайне мере ищите цепочку указателей до статического адреса (он должен быть зелёным в CE) и не проиграйте.

Ещё один вариант это просто сравнивать структуры по адресам уровней указателей своих выбранных отрядов и отрядов бота. Выясните какие данные позволяют Вам передвигать Ваших юнитов и не позволяют командовать отрядами ботов. Я говорю сейчас про условную карту Мира, а не карту где войска могут захватывать замок...

Могу посоветовать установить игру по которой я делал статью и попытаться сделать также. Понимаю, наверно, это сложно, но ничего более точного и толкового подсказать не могу. Просто сейчас у меня нет возможность установить игру.

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

Спасибо.

Немного отвлекся и решил дописать инжект на деньги, дополнил его перехватом еще 3 функций которые отвечают за: снятие денег за постройки и тд, добавление денег за отмену построек и тд, добавление денег нолооблажение за ход. Понимаю что это совершенно бесмыслено(не бессмертие делаем же) но зато потренеровался.


[ENABLE]
alloc(_inj,2048)
label(_back)
label(_exit_sub)
label(_exit_add)
label(_exit_addc)
label(_exit_chk)

_inj:
pushf
pushad
mov esi,ecx
mov ecx,00000003
jmp _inj+2A
pushf
pushad
mov esi,ebx
mov ecx,00000002
jmp _inj+2A
pushf
pushad
mov ecx,00000001
jmp _inj+2A
pushf
pushad
mov ecx,00000000
mov edx,[Shogun2.dll+019C0D94]
mov edx,[edx+041C]
mov edx,[edx+08]
mov edx,[edx+24]
mov edx,[edx+04]
add edx,478
mov eax,esi
add eax,0000046C
cmp eax,edx
jne short _back
mov dword ptr [esi+0000046C],#12345
cmp ecx,01
jb +1C
ja +0D
cmp ecx,03
je +1D
popad
popf
jmp _exit_add
cmp ecx,03
je +10
popad
popf
jmp _exit_addc
popad
popf
jmp _exit_sub
popad
popf
mov eax,[ecx+0000046C]
jmp _exit_chk

_back:
cmp ecx,01
jb +28
ja +13
cmp ecx,03
je +2F
popad
popf
add [esi+0000046C],edi
jmp _exit_add
cmp ecx,03
je +1C
popad
popf
add [ebx+0000046C],edx
jmp _exit_addc
popad
popf
sub [esi+0000046C],edx
jmp _exit_sub
popad
popf
mov eax,[ecx+0000046C]
jmp _exit_chk

"Shogun2.dll"+5A4EBD:
jmp _inj+18
nop
_exit_add:

"Shogun2.dll"+54D1A:
jmp _inj+0C
nop
_exit_addc:

"Shogun2.dll"+619585:
jmp _inj+22
nop
_exit_sub:

"Shogun2.dll"+840D0:
jmp _inj
nop
_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 обьекта

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

Не забывайте, что одновременно с 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% уверенным в том, что этот указатель будет всегда работать нельзя. У некоторого пользователя в какой-то момент этот указатель может "сбиться".

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

Спасибо, но знать что эти програмы есть недостаточно к примеру 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...)

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

>>OllyDbg у меня выдает ошибку ntdll.DbgBreakPoint на винде Win 7 64bit

У меня OllyDbg запускается под Win7 64. У меня две версии OllyDbg, та которая с нашего сайта и последняя с официального сайта OllyDbg. И та и та запускается. Сначала надо запустить игру в конном режиме,а после аттачить его из OllyDbg из меню файла. Если будут остановки из-за исключений, то пропускать их по подсказкам внизу окна Olly или же настроить пропуск исключение из настроек Olly.

По повод IDA, всё-таки советую с ним разобраться... он может гораздо удобнее показать код стрелками и связанными блоками, но только после того как будет проанализирован весь исполняемый файл... Так декомпиляция Arrays по горячей клавише F5 покажет псевдокод в удобном представлении. Можно довольно быстро сориентироваться поступает ли указатель прямо из функции или указатель извлекается внутри функции. Тоже самое правда с ошибками делает RecStudio.

По поводу DBVM и ошибок из-за виртуальных машин ничего сказать не могу. У меня DBVM не работал лишь один раз при комиляции Cheat Engine из SDK...

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

Просто, и сердито. Бескоенчный ход для всех Своих кроме агентов. Работает, но к сожалению не на той основе которой хотелось бы.


[ENABLE]
alloc(_inj,2048)
label(_ret)

_inj:
mov [eax+6C],3E7
mov edx,[eax]
mov ecx,eax
mov eax,[edx+5C]
jmp _ret

"Shogun2.dll"+12F5C32:
jmp _inj
nop
nop
_ret:

[DISABLE]
dealloc(_inj)
"Shogun2.dll"+12F5C32:
mov edx,[eax]
mov ecx,eax
mov 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 должен быть фильтр. До этого я толком не разобравшить взял функцию которая как мне казалось работает только с моими объектами, а эту пропустил мимо.

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

О, неплохо ты в этом во всём шаришь...

Я установил эту игру, думал быстро разберусь, а не тут-то было (сейчас дел навалом, может быть на недели попробую копнуть).

Вот что я предполагаю:

Пользователь:
Группа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)
}

Я уверен, что должен быть почти такой код, а это значит, что скорее всего надо больше внимания обращать на функции и её аргументы. Т.е. надо искать по всему стеку в моменты бряков такие функции , которые работают с группой после хода одной группы... Лучше не заморачиваться с указателямя, а заморачиваться с функциями в дереве вызовов...

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


// Обработчик события клика мышки
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-ом. Посомтрим выше и должны увидеть код условия о передвижения отряда который принадлежит только нашему герою. написал в теории как смог... Я проверю эту теорию, когда выделю на это время...

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

Под пунктом 1: Указатель меняется при перезапуске

Под пунктом 2: Адрес на функцию в Shogun2.dll он для всех оденаковый -всегда

Первые 3 - отряда игрока, последние 3 - отряда разных 3-ех ботов

1309171657-clip-13kb.png

Сменили фракцию/перезапуск и данные уже не те.

1309170920-clip-6kb.png

Под пунктом 1: Указатель меняется при перезапуске

Под пунктом 2: В конечном счете что я там нарыл так это указатель на пренадлежность юнита к фракции. (сразу после String идет пару нуле, а у ботов какие-то цифры - проверял тоже не сработало, при перезапуске или смене фракции все может изменится)

Первые 3 - отряда игрока, последние 3 - отряда разных 3-ех ботов

1309171810-clip-28kb.png

Сменили фракцию/перезапуск и данные уже не те.

1309170957-clip-6kb.png

Уже все пересравнивал и ничего статичного не нашел.

Может это и можно использовать но я понятия не имею как.

В OllyDbg надо поставить бряк на обработку щелчка мышки...

Подскажите пожалуйста как поставить бряк на обработку щелчка мышки, именно такой о котором идет реч.

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

По поводу указателей, которые ты привёл на картинке я знаю что они меняются с перезапуском игры. Я не акцентировал внимание на это. Это просто небольшая зацепка для дальнейших поисков статичных указателей и "постоянных фильтров". Но пока я не попробовал метод об определении кто свой, а кто чужой с помощью бряка на щелок мышки, лучше с фильтрами не возиться. Я попробую завтра.

Как ставить бряк на клик мышью?!

25.png

Тут полная статья о клике на кнопку, хотя не важно на что кликать... Но лучше чтобы я это сделал, потому что у меня опыта больше. Так что до завтра.

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

Я попробую завтра.

Спасибо.


if (group.move)
{
anyGroup = getGroups(group)
anyGroup.decreaseMove(group.lastMove)
}

Я уверен, что должен быть почти такой код, а это значит, что скорее всего надо больше внимания обращать на функции и её аргументы. Т.е. надо искать по всему стеку в моменты бряков такие функции , которые работают с группой после хода одной группы... Лучше не заморачиваться с указателямя, а заморачиваться с функциями в дереве вызовов...

Может вам понадобится функция упомянутая выше, при выдилении своих армий читает структуры отрядов. Не уверен что это имено то о чем вы говорили, но все же.

Shogun2.dll+12F5C32 // Непрерывно читает структуру отряда чей показатель очков действия больше остальных в отряде,
// а когда отряд начинает перемещение - функция считывает структуры остальных отрядов.

ОффТопик: Вопрос.

Извиняюсь что не по теме, хочу задать 2 вопроса по поводу olly v1.10 с офф сайта, слышал у вас есть сборка вашего форума но на самом фурме в разделе олли ее не нашел.

1. Можно ли исправить случай когда олли не распознает команду? А то из за них трассировка прерывается.

1309223758-clip-6kb.png

Проблема именно в самом Olly потому что CE с ней прекрасно справляется! Еще не понятно как все работало до запуска трасировки, никаких таких глюков небыло.

1309223862-clip-4kb.png

2. Также трассировка встает намертво по не понятным причинам на инструкции, а когда нажемаешь паузу то остановка происходит в ntdll на скриншоте в нижней часте - видно. Если нажать step over или step into то дебугер переходит в режим Running.

1309225223-clip-9kb.png

если снова нажать паузу а затем Run то остановимся на бряке который установила трассировка.

1309225540-clip-6kb.png

Это защита такая от трассировки? Как ее обойти подскажите пожалуйста.

ПС:

Настройки исключений в олли.

1309224187-clip-15kb.png

Но и без этих всех галочек проблема остается.

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

Ребят, вы чего? О_____О Кто же в ИГРЕ пытается обработать подобные нажатия??? В играх, по крайней мере, в большинстве, используется DirectInput (dinput.dll), на него и надо делать хук.

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

Откуда такая информация что в большинстве? :) Лично я в Дисайплс 3 когда-то давно именно таким способом что-то делал и всё работало. На Чемаксе мои посты есть по этому поводу. И никаких хуков на ДайректИнпут я не ставил.

//bronis, по заданному вопросу отвечу позже

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

Это в теории его должны применять в большинстве. На практике могут и не писать такую поддержку, а могут даже наоборот "перестараться" и добавить опцию включения и отключения аппаратного курсора для мышки. Насколько я предполагаю если эта поддержка выключения, то клики будут обрабатываться стандартно от сообщений обрабатываемых в функции привязанной к окну....

По теме...

Перевел я на псевдокод функцию уменьшающие шаги:

int __thiscall sub_10654450(void *this, int a2)

void *this - указатель на некоторую структуру Пользователя или бота

int a2 - кол-во шагов которое желает выполнить *this

return - наверно значение ошибки...

Функция перебирает группы привязанные к *this и отнимает шаги перемещения.

Эта функция находиться в окрестностях адреса вычитания очков перещения:

Shogun2.dll+68DEB2 - 89 50 6C - mov [eax+6C],edx


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; // условие выполнение цикла пока истино 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 вообще интресная инструкция связанная с глюками. Если например она работать с адресом не кратным "как это говорят параграфу", то что-то будет нестабильное... Я думаю если можно как-то в трейсинге отметить что такой-то участок не трейсить, то предлагаю это сделать.

По пункту два. Это обычное явление... более прокомментировать как решить проблему с трассировкой не могу, т.к. без понятия.

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

Ликбез.

На карте Мира могут быть войска Пользователя и ботов. За Пользователя играет Пользователь, за остальных компьютер.

Все войска Пользователя разделим на Армии в составе которой есть руководитель. Именно Армии мы можем передвигать на карте Мира.

Армию можно делить на отряды по классам: конница, лучники и т.п.

Каждый отряд имеет коэффициент усталости. От него зависит дальность хода. Таким образом в Армии быстрые отряды не могут идти дальше чем медленные отряды.

Итак, когда Пользователь передвигает Армию, то код игры смотрит принадлежит ли Армия пользователю, если нет, то идти не разрешается, если да, то код игры перебирает отряды и двигает их на расстояние указанное пользователем с вычетом сделанных ходов ранее и вычитом усталости самого уставшего отряда. Если вы что-то не поняли или запутались просто поиграйте в игру и всё поймете. Конница не может оставить лучников в армии, если двигается вся армия...

Путь Вхождений моего героя из глубины вверх.

Три функции ниже связаны с объектом пользователя или бота и параметром а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);
else
LABEL_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;
}

Осталось только проверить в отладке моё предположение о том выделен лы был игрок. Но это я сделаю не сегодня.

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

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

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

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