> Яб предложил прибавить к esp 4 после call и что-то слишком > заумно получаеться... Я бы сделал так: > void Stub(char *str) > { > char buf[16384]; > > memcpy(APIAddress, pbOpcode, 5); > _asm push str > _asm call APIAddress > _asm add esp,4 > } > > Компилятор включает проверку esp только в Debug версии(cmp > esp,ebp _chkesp). Так что в Release баг есть но не виден
это то все понятно, все правильно конечно, но это верно ТОЛЬКО для одной конкретной функции, а если мне нужно произвольную функцию перехватить?!
1) Спасибо всем кто помогал мне постигать тайны программинга :)
вот теперь возникла несколько другая праблем....
Задача такая: после перехвата вызова и передачи управления на мою stub-функцию мне нужно внутри этой stub после некоторых действий опять вернуть управление действительной функции так, как будто бы никакого перехвата не было ... как это осуществлять(в общих словах если можно)?!
1)
2)
...
н)
если ты перехватываешь управление на первом же байте api, то на регистры кажется можно забить
т.е. нужно только стек в прежнее состояние вернуть
т.е. если ты перехватывал с помощью jmp, то и возвращаться нужно jmp на следующую команду
если call, то ret
не забудь только какие-нить переменные свои в стеке
чуть не забыл :)
ты же переписываешь несколько байт кода перехватываемой функции :)
т.е. тебе нужно както выполнить те действия, которые там делались без тебя :)
в общем случае это если и возможно сделать, то трудно
но для конкретной функции можно подумать...
(тут и на регистры нельзя забивать) :)
лучше придумать другой способ подмены функции
например (не для kernel32.dll):
используй \delayload:name.dll
и вставь свой обработчик загрузки (см. msdn)
вместо правильного адреса вернёшь свой адрес
так тебе не прийдётся переписывать код dll
насчет delayload:name.dll спасибо! я об этой фиче не знал ... нужно разобраться.
Но мне нужна именно таким способом который я указал...
т.е. делаем следующее:
1) пишем 5ть байт(call MyStubProc) на место первых 5и байт перехватываемой функции
2) когда эта перехватываемая функция фызывается, то вместо неё исполняется наша stub
3) внутри stub делаем свои дела
4) внутри stub продолжаем выполнение перехваченной функции
5) завершаем stub
трудности представляютЬ 4) и 5) пункты
4) ....... тут простым ret явно не отделаться...для того чтобы спокойно передать управление перехваченной функции нужно так откорректировать стек чтобы он был как до перехвата чтобы параметры не заглючили... даже если я вычислю адрес начала параметров в стеке и запихаю его в стек перед вызовом то все равно глючит :((( ..я ща здохну! ... как это мона сделать а?!
ЗЫ: странно зарегистрился а пароль не пришел
ЗЗЫ: СофтАйс сука падаетв 2000!
> 1) пишем 5ть байт(call MyStubProc) на место первых 5и байт > перехватываемой функции > 2) когда эта перехватываемая функция фызывается, то вместо > неё исполняется наша stub > 3) внутри stub делаем свои дела > 4) внутри stub продолжаем выполнение перехваченной функции > 5) завершаем stub > > трудности представляютЬ 4) и 5) пункты > 4) ....... тут простым ret явно не отделаться...для того > чтобы спокойно передать управление перехваченной функции > нужно так откорректировать стек чтобы он был как до > перехвата чтобы параметры не заглючили... даже если я > вычислю адрес начала параметров в стеке и запихаю его в > стек перед вызовом то все равно глючит :((( ..я ща здохну! > ... как это мона сделать а?!
Predlagayu sdelat` tak: ti menyaesh 5 bait no sna4ala nado ih sohranit` => delaem global`nuy peremennuy BYTE oldopcode[5], zatem pered tem kak ti postavish svoi 5 bait skopiruy ih v etu peremennuy, a v stub pri vihode skopiruy ih obratno, kone4no togda polu4aetsya 4to stub vizivaet`sya odin raz. Plus sa4em delat` call? lu4she jmp na stub i essno jmp obratno na na4alo f-cii. Is4o lu4she postavit` tot kod kotoriy ti zamenyaesh k sebe no togda nado znat` dlinu komand kotorie ti zamenyaesh obi4no navernoe doljno bit` 4to-to vrode
55 push ebp
8BE5 mov esp,ebp
a dalshe hz 4to mojet bit`....
Esli nado dlya odnoy konkretnoy f-cii to mojno posmotrt` vru4nuy 4to-tam skajem tam mojet bit` 4to-to vrode
55 push ebp
8BE5 mov esp,ebp
BF0100000 mov eax,1
dlina 3-h komand = 1+2+5=8 bait sootvetsvenno zapominaem ih i v konce stub vipolnyaem(stek doljen bit` normal`niy ego nado sohranyat` esli ti delaesh call to nado izvle4` adres vozvrata a vosvrashat`sya iz f-cii 4erez jmp) potom delaem jmp mimo etih kommand i vse doljno bit` noraml`no.
delayload - только с 6 версии VC (в 5 кажется ещё не было)
ты используешь JMP, значит и возвращаться ты должен по JMP (или сам пихай нужный адрес в стек, а потом RET)
посмотри какие команды ты переписываешь, тогда поймёшь почему после возврата не работает старая функция (может быть ты даже не целое количество команд переписываешь - тогда там дальше вообще бред будет)
слушай может посмотришь исходнрик а?! а то чёта у меня прога вылетает грит с esp какая то фигня.. хотя я вроде все сделал... там совсем немного кода...
Хмм плохая идея реализовывать Stub на C :(, лучше asm и подключить ее из obj. Вот сделал на сях но пример непригляден L(
int _cdecl main(int argc, char* argv[]){
char str1[]="Suxx";
DWORD dwOldFlags=0;
PBYTE pbAPI=(PBYTE)trap001;// берем адрес функции которую
// нам надо перехватить
goto JMP1;
//Пропускаем енто пока
Stub:
//Тут нам надо только лишь скопировать оригинальные байты и прыгнуть туда. Со стеком извращаться не надо....
MessageBox(NULL,"Now run original func","Trap",0);
memcpy(APIAddress, pbOpcode, 5);
_asm{
jmp APIAddress
}
JMP1:
APIAddress=(tagAPIAddr)pbAPI;
memcpy(pbOpcode,pbAPI,5);
// записываем вызов нашей заглушки ...
> Хмм плохая идея реализовывать Stub на C :(, лучше asm и > подключить ее из obj. Вот сделал на сях но пример > непригляден L( > > int _cdecl main(int argc, char* argv[]){ > > char str1[]="Suxx"; > DWORD dwOldFlags=0; > PBYTE pbAPI=(PBYTE)trap001;// берем адрес функции которую > // нам надо перехватить > > goto JMP1; > //Пропускаем енто пока > Stub: > //Тут нам надо только лишь скопировать оригинальные байты и > прыгнуть туда. Со стеком извращаться не надо.... > MessageBox(NULL,"Now run original func","Trap",0); > memcpy(APIAddress, pbOpcode, 5); > _asm{ > jmp APIAddress > } > > JMP1: > > APIAddress=(tagAPIAddr)pbAPI; > memcpy(pbOpcode,pbAPI,5); > // записываем вызов нашей заглушки ... > > if(!VirtualProtect(pbAPI,4096,PAGE_READWRITE,&dwOldFlags)) > { > MessageBox(NULL,"Error!","Error",MB_OK); > exit(-1); > } > > _asm mov edi,pbAPI > _asm mov [BYTE PTR edi],0xE9 > _asm lea eax,Stub > _asm sub eax,edi > _asm sub eax,5 > _asm mov [DWORD PTR edi+1],eax > > trap001(str1); > > return 0; > }
хммм ... а куда деваться, именно на С нужно написать ... я конечно могбы использовать __declspec(naked) но мне нужно внутри Stub поработать с переменными ... так вот, в твоем примере тоже глюк со стеком, при выходе из Stub отладчик ругается кривой ESP, я переделал код функции Stub, теперь все ОК, но! при выходе из main отладчик серавно ругается на кривой ESP, но когда я компилю как релиз никаких глюков или это пока?! .. если релиз не выдает ошибок можно ли положить на эту проблему или всетаки дрючиться дальше?!
> Яб предложил прибавить к esp 4 после call и что-то слишком > заумно получаеться... Я бы сделал так: > void Stub(char *str) > { > char buf[16384]; > > memcpy(APIAddress, pbOpcode, 5); > _asm push str > _asm call APIAddress > _asm add esp,4 > } > > Компилятор включает проверку esp только в Debug версии(cmp > esp,ebp _chkesp). Так что в Release баг есть но не виден
это то все понятно, все правильно конечно, но это верно ТОЛЬКО для одной конкретной функции, а если мне нужно произвольную функцию перехватить?!
[win32] вот исходный код, он глючит :(((22.10.01 03:35 Автор: Heromantor Статус: Незарегистрированный пользователь
> > это то все понятно, все правильно конечно, но это > верно > > ТОЛЬКО для одной конкретной функции, а если мне нужно > > произвольную функцию перехватить?! > > Надо знать параметры для этой ф-ции скажем для trap001 > можно сделать так: > typedef void (*tagAPIAddr)(char *); > > а в Stub вызывать не callом а просто > APIAddress(str); > тогда компилятор все сделает сам. Без прототипа никак :( > > И все-же непонятно почему ESP поганится... это не то :(((( ... а ESP поганится из-за того что там навороченные переходы если в отладчике смотреть, но вот с такой корректировкой стека работает ...