такая ситуация: есть в одном ПО функция (экспортируется из длл), которая вызывается довольно часто... в ПО внедряется код (машинный код x86/x64)... в пролог функции ставится трамплин на внедренный код... код должен выполниться только один раз, до полезной нагрузки кодом происходит удаление трамплина и восстановления замененных байт функции... но все портит тот факт, что в ПО может быть несколько потоков... то есть примерно в 50% случаев до того, как внедренный код успеет восстановить оригинальный пролог функции, эту функцию успевает вызвать другой поток (а ведь код должен выполниться не более одного раза)... плюс в том, что известно, что если из функции вернуть 0, то ничего страшного с другим потоком не произойдет, а так же известно, что функция stdcall в x86 и fastcall в x64... вопрос в том, как грамотно сделать заглушку, чтобы при втором и последующих попытках прохождениях кода из функции возвращался 0 (как вернуть ноль я знаю, вопрос именно в заглушке)... и ещё одно условие: при внедрении код можно только исполнять и читать, права на запись самого себя у кода нет... как бы вы решали такую задачу? ЗЫ чем меньше размер кода заглушки - тем лучше... ЗЗЫ хоть и были фразы про машинный код, лучше предлагайте решение на ассемблере... так понятнее...
Код (Text): mov eax, [original_func_ptr] xchg eax, [p] jmp eax hook_code: ...... p dd hook_code при первом прохождении в eax будет адрес hook_code, при последующих - original_func_ptr
нет, ну можно было бы сделать по какому-либо механизму синхронизации, но к сожалению это займет существенное количество байт... к тому же объект синхронизации нужно делать именованным для задачи... дело в том, что второй и более проход по коду может сделать только другой поток (со своим контекстом)...
Тогда можно сделать глобальную переменную и при первом проходе выставить её, а потом перепрыгивать. Смотреть в сторону Код (Text): lock cmp [addr],0 lock cmove [addr],1 je kudanado кмове, только надо выбрать подходящий.
Rel Код (Text): p dd hook_code это глобальная переменная, одна для всех потоков xchg eax, [p] обеспечивает атомарный доступ, этому коду пофиг на потоки %)
Ну, если немного пошевелить мозгами, то становится понятно, что он лучше изза своей красоты и простоты. Мой код смотрится рядом с ним довольно неуклюже, также как и пост Clerkа