GTA Vice City > Справочная информация

Реверс плагина на примере увеличения лимита img-архивов

(1/1)

xanser:
Бывают случаи, когда авторы создают полезные плагины, но не делятся исходным кодом. Мне например не хочется использовать чужие плагины в своем моде, спрашивать разрешение авторов включать их в свою сборку, поэтому стараюсь все писать сам. Но как раздобыть необходимый адрес, если код закрыт. Если с CLEO-скриптами все просто, их можно открыть и посмотреть, вытащить оттуда все полезное, то с ASI-плагинами поможет только IDA PRO.

Многие знают плагин Img Limit Adjuster, но как он работает.
Сначала пойдем честным путем (я так и сделал). Подключение img-архива происходит в default.dat или gta_vc.dat командой CDIMAGE, отсюда легко это найти в IDA



На рисунке видно, что лимит img-архивов задается не ограничением количества CDIMAGE_COUNT, а размером памяти, выделенной под их названия CDIMAGE_NAMES и соответственно под сам массив указателей CDIMAGES. Получаем максимум 8 архивов, кроме gta3.img, больше просто некуда записать.

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


--- Код: C++ ---void *CDIMAGE_NAMES; CDIMAGE_NAMES = VirtualAlloc(NULL,0x4000,MEM_COMMIT,PAGE_READWRITE);void *CDIMAGES;      CDIMAGES      = VirtualAlloc(NULL,0x1000,MEM_COMMIT,PAGE_READWRITE);
Осталось перенаправить все первоначальные ссылки (их легко увидеть, нажав X в IDA), которые были на 0x6F7488 CDIMAGE_NAMES и 0x6F76D0 CDIMAGES на новые области


--- Код: C++ ---WriteDWORD((DWORD*)0x4081D2,(DWORD)CDIMAGE_NAMES);WriteDWORD((DWORD*)0x40823A,(DWORD)CDIMAGE_NAMES);WriteDWORD((DWORD*)0x408801,(DWORD)CDIMAGE_NAMES);WriteDWORD((DWORD*)0x40818B,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x408199,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x4081C7,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x408215,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x408221,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x40851B,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x4086E1,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x4087E2,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x4087EE,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x40885B,(DWORD)CDIMAGES);WriteDWORD((DWORD*)0x408869,(DWORD)CDIMAGES);
На всякий случай моя процедура WriteDWORD, которая просто пишет в адрес 4 байта


--- Код: C++ ---void WriteDWORD(DWORD *Address, DWORD Value){    DWORD OldProtect;   VirtualProtect(Address,sizeof(DWORD),PAGE_READWRITE,&OldProtect);    *Address = Value;   VirtualProtect(Address,sizeof(DWORD),OldProtect,&OldProtect);}
Теперь лимит img-архивов ограничивается только выделенной под них областью памяти.

Теперь о реверсе существующего плагина IMG Limit Adjuster. Я использовал это, только чтобы проверить свои описанные выше догадки, но те кто не догадаются, смогут с чего-то начать. Можно открыть плагин в IDA, сразу появится основная функция и действительно в ней видно, что автор руководствовался точно такой же логикой, два раза выделяется память VirtualAlloc и дальше перебрасываются на нее все ссылки через VirtualProtect. Это и означает, что адрес, переданный в качестве параметра в VirtualProtect будет меняться, их и смотрим.



Кстати, достаточно выделить память один раз и правильно распределить, по 64 байта под названия, по 4 под указатели.
P.S. А еще лучше обойтись динамическими массивами.

Sektor:
Замечательная статья, думаю многим будет полезна...

xanser:
Единственный момент, который я заметил, что плагин оставляет gta3.img еще и по старому адресу, не знаю зачем, если туда больше нет ссылок. Список изменяемый адресов в точности как у меня. И еще меня смущает функция, вызываемая первой, не знаю что это. Плохо что всякие offset дизассемблируются не всегда правильно, приходится переключать их на более подходящие по смыслу варианты. Но в моем варианте игра запустилась нормально, лимит увеличен, просто смущает какой-то еще штрих.

P.S. Все понял, плагин грузится позднее и не успевает сразу все поменять. Тогда я сделал один в один.

Навигация

[0] Главная страница сообщений

Перейти к полной версии