Доброе время суток всем! Проблемка в следующем. Есть экспортируемая из DLL-ки ф-ия, DLL спроецирована на адресное пространство процесса, виртуальный адрес(ф-ии) естественно имеется. Вопрос, как получить адрес ret-a из этой ф-ии, можно ли как-нибудь через инфу в PE-формате(размер ф-ии или что-нибудь вроде этого) или придется разбираться с самим кодом ф-ии, написав мини-дизассемблер? Sorry если вопрос очень глупый...
zhindos никак дизасмить до рет это изврат и при дизасме можно нарваться на множественные выходы(реты) в зависимости от логики функции ты опиши для чего это нужно сделать, мож способ какой лихой предложат
в частных случаях проблема множественного рет-а решается просто По умолчанию в компиляторе стоит выравнивание структур и функций на 8 байт. Иногда ставят на 4. Выравнивание идет либо nop-ами, либо int 3 Т.е. конец функции ознаменуется "ретом + nop / int 3" Либо же "ret + push ebp" метод отнюдь не универсальный, хотя подходит для большинства системных библиотек. Дизасм конечно же помог бы. Хотя можно и без него проверять сигнатуру.
wsd и при дизасме можно нарваться на множественные выходы(реты) в зависимости от логики функции Да, я так тоже подумал... Нужно определенную ф-ию "заблочить", т.е заменить первые n байтов ф-ии на код возврата. Если calling convention - __cdecl, проблем нет - C3 и все OK. Но если __stdcall - как узнать, ск-ко байтов выталкивать со стека?
zhindos сохранять значение esp на критических участках (до первого пуша) а после вызова восстанавливать
zhindos Стоп. Если мы нашли RETN (байт 0C2h), то вслед за ним должен ведь идти WORD с явным указанием того, сколько байт из стэка выпихивать?
Magnum ты не все случаи учёл видал такое Код (Text): mov dword ptr [esp-4], 0 mov dword ptr [esp-8], offset szText mov dword ptr [esp-12], offset szCapt mov dword ptr [esp-16], MB_OK sub esp, 10h call MessageBox
DEEP С2 может быть не нечалом retn, а продолжением другого опкода Magnum Thanks, только немножко в другом варианте - сохранить esp -> call-> numberOfBytes = esp - savedEsp
zhindos Ну так если у тебя в руках будет способ однозначного определения места, где RETN находится, то кол-во байт тоже однозначно будет правильным... Или я не догоняю? Извиняюсь если что =)
DEEP Ну так если у тебя в руках будет способ однозначного определения места, где RETN находится, то кол-во байт тоже однозначно будет правильным... Конечно. Вся проблема - найти этот способ...
zhindos тебе DEEP хороший вариант вооружись дизасмом длин (они очень маленькие) 1. проверяеш первый байт на 0C2h и если да - следующие слово то что мы искали 2. если это другая комманда - то кормиш дизасму длин и по результаттам перемещаешся на это смещение и опять пункт 1
ну а если тип поглашения не stdcall. немного громоздкий способ, но как вариант - похукать функцию сплйсингом и вернуть то что нужно, типо того Реальная функция proc push offset hook ;< ret ;< код перехвата .... Реальная функция endp hook proc восстановление похуканой функции вызов восстановленой функции установка хука а тут возвращаем что хотим .... hook endp
z0mailbox Ну это обсудили ужо, что по сути не как ты конец не определишь, однозначно и просто. Хотя если это последний рет после него или 0x00 или 0xcc или 0x90 но это не обязательно так, мложно обрабатывать переходы т.е. смотреть кода ф/я может залезть и брать самый последний ret думаю этот вариант будет работать почти везде.
SPA дык это уже почти ИДА-функцыонал скажите лучше зачем это нужно, копировать участки кода? я ЭТО использую только для получения ласт-еррор в ремоут-треде инжектора ну там функцыя в 2 строки, размер берется с запасом и все дела