Здравствуйте. Это задача на переплнение буфера. В моей программе после переполняющегося буфера идут несколько переменных, которые надо затереть для того, чтобы изменить адрес возврата. Но возникла одна проблема: одна из переменный (по адресу ebp+adata_p) сразу же после переполнения используется вот-так: ( программа на Делфях, а сама переменная хранит адрес объекта TStream и всегда храниться в разных местах памяти) Код (Text): ;здесь происходит переполнение mov eax, [ebp+adata_p]; eax = ад.пер. TStream mov edx, [eax]; таблица функций call dword ptr [edx]; eax=TStream.GetSize; Если я затираю эту переменныю, сробатывает иксепшн. Может кому-нибудь придет в голову как можно использовать эту констукцию, чтобы по цепочке вызвать, то, что нужно. Или, как бы затереть ее так, чтобы без иксепшинов. Че-то в голову пока ниче не лезет... Возможет еще такой вариант: кто-нибудь может знает такую функцию, которую можно вызвать подобным образом, так, чтобы как говориться без иксепшинов...
если по простому, то задача в том, чтобы чтото засунуть в стек вместо этой переменной, чтобы: 1 - не было иксепшина 2 - желательно на выходе, eax<8000 PS почему происходят иксупшины мне очень даже понятно, по этому поводу я много перепробовал, находил даже такую цепочку, что вызовы шли именно в TStream.GetSize, но безрезультатно, так, как я заранее не знаю где нахадиться моя переменная типа TStream...
это все дело находится в обработчике от TUDPServer при приходе датаграммы, программа чата, под UDP протокол. Буфер переполняется при приеме пакета примерно так: Код (Text): var arr:array[1..8000] of byte; str: TStream; .... begin .... data.ReadBuffer(arr,adata.Size); //здесь тот код, который я приводил >A_Must_Loll намек конечно понял, но жить то как-то надо... идею класса на делфи не усек (или эта издевка такая), хотелось бы ченить конструктивное... ищу пока другие переполнения...
>A_Must_Loll ну так, я и херачу больше размера буфера, и дальше прога мирно умирает, записывая в свой лог ошибку при чтении UDP. я это дело трассирую и натыкаюсть как раз на ту проблему о которой пишу: сразу после буфера в стеке лежит ссылка на этот гребаный TStream, и если я ее затру чем попало, сробатывает иксепшин, обработчик которого и убивает прогу. код который использует эту ссылку на TStream я уже приводил. для полного счастья мне нужен такой адресок в памяти, который можно три раза разименовать и потом сделать call туда, это ясно из фрагмента кода выше...
zag2art А тебе не приходило в голову спросить про свою проблему на форуме по дельфи? Кто его знает как дельфи шлет UDP. Может ты какие-нибудь свойсва (TStream и TUDPServer)неправильно установил - это луше всего знают те кто работает с этими объктами. А низкоуровневое програмирование это ближе к API.
zag2art > "для полного счастья мне нужен такой адресок в памяти, который можно три раза разименовать" Ну дык покапайся в импорте - наверняка найдешь GetLastError, GetCurrentThreadID и т.п. функции без параметров. Смещаешь адрес на 2 байта чтобы обойти JMP и получаешь свои три безопасных разименования. Правда не факт, что после этого еще на что-нибудь не нарвешься
zag2art > "активно этим занимаюсь (я так понимаю не все JMP для этого подойдут?)" Не понял, о чем это ты Если прога у тебя под рукой, то грузишь ее в Олю, делаешь Search for Names и с вероятностью 99.9(9)% находишь ссылку на GetLastError. Это адрес из таблицы импорта (секция .idata), по которому лежит адрес самой функции GetLastError. Тебе нужен не этот адрес, а адрес JMP из секции CODE (в дельфях все вызовы импортируемых функций идут через джампы JMP m32, опкод FF25). Поэтому делаешь Find references to import и в первой строчке получаешь адрес этого JMP, переходишь по Follow in Disassembler и убеждаешься в том, что это действительно JMP по адресу в idata. Готово, твой искомый адрес равен адресу инструкции JMP плюс 2 байта. Можешь писать его в стек на место переменной strm:TStream и смотреть что будет дальше )) (А дальше видимо будет не менее интересно, т.к. по кр.мере в конце функции д.б. вызов strm.Free ) Ес-но вместо GetLastError можно использовать другие апишные функции без параметров (GetCurrentThreadID и т.п, GetActiveWindow и т.д.)