Привет! Изучаю метод сплайсинга и столкнулся со следующими вопросами: допустим нужно установить перехват на процедуру, которая начинается следующим кодом Код (Text): jmp m1 ;2 байта m3: xor eax,eax ;2 байта jmp m2 ;2 байта m1: add eax,5 ;3 байта m2: В этом случае надо сохранить первые 3 команды (6 байт) и поверх них записать jmp XXXX. Вот тут-то и начинаются приколы. Что бы сохранить правильность кода нам надо пересчитать все относительные переходы. Начинаем пересчитывать - первый jmp не трогаем, он действуе в пределах переносимого кода, второй jmp из ближнего превращается в дальний, т.к. скорее всего код будет переноситься за пределы 127 байт, и уже занимает не 2 байта, а 5!!!!!!!! И вот теперь надо пересчитать первый jmp, т.к. длина второго изменилась. Такие случаи конечно маловероятны, но все же хочется получить универсальный метод перехвата. Самый простой способ решения этой проблемы, который пришел мне в голову, – это преобразовать все переходы в дальние, что бы за ранее знать их длину, пересчитать их и сохранить полученный код. Может кто-то этим занимался и у него уже есть готовый перечень команд, которые используют относительный переход. (jmp, je, ja, jb……). Если есть таковые - помогите, плз.
т.н. rel'ы... JMP (EB/E9) CALL (E8) Jcc (7x/0F 8x) LOOP (E2) LOOPNZ (E0) LOOPZ (E1) JECXZ (E3) все вроде.
Немного уточню _BC_: (исходник - мануалы AMD/Intel) Код (Text): E8 xx xx xx xx CALL Jz (near) E9 xx xx xx xx JMP Jz (near) EB xx JMP Jb (short) 7x xx Jcc Jb (short) 0F 80 xx xx xx xx Jcc Jz (near) E0 xx LOOPNZ Jb (short) E1 xx LOOPZ Jb (short) E2 xx LOOP Jb (short) E3 xx JECXZ Jb (short)
может проще выяснить куда ведет jmp/call в начале перехватываемой функции и вписывать свой jmp туда ? то есть в твоем случае записать jmp (на новый код) по адресу m1 а не в самом начале функции. я так делал в случае когда нужную функцию уже перехватили до нас (таким же методом). P.S. интересно бывают функции которые начинаются с Jcc ?
Практика показывает что достаточно обрабатывать только jmp и call с rel32 смещениями, так как ни в одной dll других команд в начале экспортируемых функций нет.