Здравствуйте Сутки бьюсь с проблемой: как вызвать процедуру из ДЛЛ'ки? Суть: Есть программа - сервер онлайн игры. Исходников нету Есть .map файл в котором я нашел функцию: Code (Text): 0001:00152800 ?NpcDeviasGuard@@YAHPAUOBJECTSTRUCT@@0@Z 00553800 f NpcTalk.obj В олли нашел данный оффсет. Возникло желание его изменить Как я понял: ГеймСервер делает Call на оффсет где расположена команда JMP на функцию(00553800) где описана функция - реакция этого НПЦ на "тыкание" на него В Длл'ке есть функция: Code (Text): NewNPC Proc Local PlayerID:DWord Local Map:DWord Local X:DWord Local Y:DWord Mov Eax, DWord Ptr Ss:[Ebp + 8] Mov Edx, DWord Ptr Ds:[Eax] Mov PlayerID, Edx Mov Map, 0 Mov X, 98H Mov Y, 34H Mov Eax, Y Push Eax Mov Ecx, X Push Ecx Mov Edx, Map Push Edx Mov Eax, PlayerID Push Eax Call gObjTeleport Ret NewNPC EndP Dll'ку хукнул: Code (Text): 005D903D . 72 65 73 65 61>ASCII "research.dll",0 005D904A 00 DB 00 005D904E . 4E 65 77 4E 50>ASCII "NewNPC",0 005D9055 00 DB 00 005D9063 > 68 3D905D00 PUSH GameServ.005D903D ; |/FileName = "research.dll" 005D9068 . FF15 F4BC8C0C CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; |\LoadLibraryA 005D906E . 68 4E905D00 PUSH GameServ.005D904E ; |hModule = 005D904E 005D9073 . FF15 F0BC8C0C CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress 005D9079 .^E9 171FFCFF JMP GameServ.0059AF95 (Пустые оффсеты и nop стер) Дак вот как вызвать функцию NewNPC из DLL'ки, на месте старой? Спасибо, надеюсь на вашу помощь
tagegor > Dll'ку хукнул ... Ничего не понял, однако, KERNEL32.GetProcAddress требует два параметра, у тебя только второй.
Да я вроде разобрался, поправил ГетПроц, но, блин, ексепшн вылетает Code (Text): 005D908E > 68 3D905D00 PUSH GameServ.005D903D ; /FileName = "research.dll" 005D9093 . FF15 F4BC8C0C CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; \LoadLibraryA 005D9099 . 68 5B905D00 PUSH GameServ.005D905B ; /ProcNameOrOrdinal = "LeInit" 005D909E . 50 PUSH EAX ; |hModule 005D909F . FF15 F0BC8C0C CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress 005D90A5 . A3 911F4000 MOV DWORD PTR DS:[401F91],EAX 005D90AA .^E9 E61EFCFF JMP GameServ.0059AF95 Пишет что нельзя записать по адресу 401F91... Как быть?
tagegor > нельзя записать по адресу 401F91 Секция кода? Если да, то обычно она имеет атрибуты чтение+исполнение, надо ERW.
Я подменяю вызов Функции по адресу 401F91 Своей функцией находящейся в ДЛЛке, адрес чей я получаю через ГетПроцАдресс Я изменил EP на загрузку моей ДЛЛки, тоесть сразу при загрузке дллки меняется Инструкция JMP "00521BF2", по адресу 401F91, на JMP "оффсет из ДЛЛки"
ERW Погуглил, не нашел что это такое... Не обьясните? Вот строчка которую я хочу подменить: "00401F91 $ E9 6A181500 JMP GameServ.00553800" Скорее всего секция кода
tagegor Меня интересует код после этого перехода JMP GameServ.0059AF95 и почему адрес процедуры "LeInit" запихнули в 401F91, ведь в оригинальном коде адрес этой процедуры передается как-раз в 59AF95.
Ексепшн вылетает до него Это переход на оригинальную точку загрузки сервера. Тоесть я вырезал часть, изменил еп. Тоесть сначала грузится либа, потом начинается код самого сервера
crypto Нет, вы меня неправильно поняли. Я опишу понятнее. 1. Есть Длл'ка, в ней 4 функции: а. Инициализация дллки б. LeInit в. NewNPC г. ChangeThisCall: Code (Text): ChangeThisCall Proc BaseAddr:DWord, MyProcAddr:DWord Mov Eax, BaseAddr Mov Edx, MyProcAddr Sub Edx, Eax Add Edx, -5 ;Add Eax, 1 Mov DWord Ptr Ds:[Eax], Edx Ret ChangeThisCall EndP При загрузке ГеймСеврер, вызывает функцию LeInit, та в свою очередь вызывает ChangeThisCall, меняя вызов оффсета 401F91, на оффсет DLL'ки. Дак вот когда я пишу в память(тоесть меняю оффсет) мне кидает ексепшн, о том что нельзя прописать по адресу 401F91... Исходников ГеймСервера нету
Ну во-первых секция .text была только на read Во-вторых, моя ДЛЛ'ка подгружалась второй(перед ней еще одна) Ну и включил виртуалпротект