извините пожалуйста может ламерский вопрос, но всетаки оч интересно... Почему когда читаешь данные из секции кода они считываются в правильном порядке, а когда из данных наоборот. Например если мы записали по адресу принадлежащему секции кода 12345678h, то в памяти будет 78563412h... и это естественно, и когда мы делаем call или читаем в регистр, то получаем 12345678h. А если адрес принадлежит секции данных, то при чтении 78563412h... Объясните в чем фишка
DeeoniS Объясните подробнее как вы проводили этот эксперимент, т.е. как записывался и читался DWORD в/из секцию кода и данных соответственно.
вот кусок кода .data _proc dd 0h ;....... .code ;это записываем call getdata ;edi указывает на _proc stosd ;это читаем mov eax,dword ptr _proc ;или так call _proc
DeeoniS Ну, вот, набираю в Olly: Код (Text): MOV EAX,12345678 LEA EDI,DWORD PTR DS:[40D000] STOS DWORD PTR ES:[EDI] XOR EAX,EAX MOV EAX,DWORD PTR DS:[40D000] ; тут EAX == 12345678 LEA EDI,DWORD PTR CS:[40C101] STOS DWORD PTR ES:[EDI] XOR EAX,EAX MOV EAX,DWORD PTR CS:[40C101] ; опять EAX == 12345678 Никакой разницы!
вот тогда программа с исходниками, она просто ищет адреса API, находит ExitProcess и вызывает его парольна архив 12345 _1351586475__proga.rar
DeeoniS В вашем коде часто встречаются инструкции с операндами вроде Код (Text): mov dword ptr [ebp+offset ker],eax Но ebp всегда равен нулю, так зачем его вообще использовать? Теперь по существу: Код (Text): @@Offsetz label byte Вам не кажется что логичнее было бы написать так: Код (Text): @@Offsetz label dword
это программа лишь тестовая и использование ebp были обоснованы. Если использовать @@Offsetz label dword эфект остается темже. И всетаки мне непонятна природа этого "явления"
DeeoniS Где именно проявляется баг? Код (Text): ; GetAPIs push esi push edi call GetAPI pop edi pop esi stosd ; Тут? В этом месте по адресу _FindFirstFileA запишется двойное слово, которое возвращает GetAPI. Кстати, а это ничего что значение ECX изменяется в GetAPI? А где это записывается в секции кода?
баг проявляется в основном модуле программы push 0h call _ExitProcess если _ExitProcess (и др) определено в .data, то вызов происходит по адресу 20746573, а если в .code то вызов правилен 73657420(точка входа в ExitProcess). сами ф-ии из gapi.asm 100% рабочии. ECX должен изменяться. Забыл одну вещь сказать, при перекомпиляции надо поставить атрибут секции кода чтоб писать можно было, по умолчанию ведь нельзя... 2Quantum>А где это записывается в секции кода? этого вопроса не понял
DeeoniS Я могу найти только одно правдоподобное об"яснение : ты путаешь две "записи" : call adress и ее вид в виде последовательности байт, как данных. В этой последовательности адрес действительно вывернут "наизнанку" - это наследие 86-го при переходе от 8 к 16 битам, а потом уже и 32.
запусти прогу в архиве и ты увидишь что когда делается call адреса из переменной _ExitProcess выкидывает ошибку что память не может быть "read"...
Чудес в природе не бывает. Чтение и запись в память всегда выполняются одинаково независимо от того как обозвать секцию. Так что, если прога выдает ошибку, значит и есть ошибка в алгоритме - надо искать где, но лень ... PS: А вообще-то похоже все элементарно. Заглянув в Олю видим, что что wsprintf затирает все твои адреса и в итоге на момент call _ExitProcess на месте адреса лежит строка. В Win9х, так вообще получаем недопустимую операцию.
Отладчиком надо пользоваться. 73 65 74 20 - это совсем не адрес, а текст твоего сообщения : set is 79430000h..FindFirst "set " - 73-s 65-e 74-t 20- Поправь : buffer dd (длина/4)? Ты буфером все затер.
Пока PS дописывал, valterg все разъяснил Вот только интересно, действительно мусор из текста совпал с зеркальной записью адреса, или это просто невнимательность (в 9х ес-но ничего общего, т.к. кернеловские адреса начинаются с BFF...)
и точно буфер все затер... а я что-то на адрес особо внимания не обратил. Ну теперь точно зато такую ошибку не сделаю. Спасибо