Pull to refresh
24
0
Send message
Используется при защите соединений с базами данных (сфера информационных технологий). В двух словах: при перехвате функции создания соединения с MSSQL-сервером выполняется функциональность дополнительной двухфакторной аутентификации для последующего зашифрования/расшифрования передаваемых данных «на-лету».
Да, только оно датируется 2006 годом. И многие вещи там устарели.
Спасибо! При изучении внутреннего строения CLR я в основном пользовался анализом ассемблерного кода. Все переходники были изучены таким образом, но обобщить их (особенно понять логику FixupPrecode) мне помогла следующая ссылка:
https://github.com/dotnet/coreclr/blob/775003a4c72f0acc37eab84628fcef541533ba4e/Documentation/botr/method-descriptor.md
Замечу, правда, что приведенный по ссылке метод не является переносимым (т.е. может работать не всегда). И вот почему:

1) Иногда поток управления проходит через переходник, минуя адрес в таблице слотов;
2) Способ определения адреса слота в таблице MethodTable может изменяться с каждой версией CLR;
3) Вызов

RuntimeHelpers.PrepareMethod(methodToReplace.MethodHandle);

не всегда гарантирует выполнение JIT-компиляции;

4) Переходники могут не быть FixupPrecode (особенно для NGen-модулей).
1) Отличия следующих команд для различных платформ только в размерности адреса.

int* inj = (int*)methodToInject.MethodHandle.Value.ToPointer() + 2;
long* inj = (long*)methodToInject.MethodHandle.Value.ToPointer()+1;

только в размерности адреса.

2) Следующие строки (скорее всего) получают адреса слотов в таблице MethodTable (см. приведенную картинку)

int* inj = (int*)methodToInject.MethodHandle.Value.ToPointer() + 2;
int* tar = (int*)methodToReplace.MethodHandle.Value.ToPointer() + 2;

3) Следующие строки определяют адрес переходника FixupPrecode после компиляции для двух функций

byte* injInst = (byte*)*inj;
byte* tarInst = (byte*)*tar;

4) Следующие строки

int* injSrc = (int*)(injInst + 1);
int* tarSrc = (int*)(tarInst + 1);

в командах jmp NativeCode (см. описание FixupPrecode после компиляции) находят смещение сгенерированного кода относительно окончания самих команд (которые занимают 5 байт);

5) Следующая строка вычисляет относительное смещение сгенерированного внедряемого кода относительно окончания команды jmp NativeCode для перехватываемого кода(!!!) и записывает его в команду jmp NativeCode для перехватываемого кода

*tarSrc = (((int)injInst + 5) + *injSrc) — ((int)tarInst + 5);

Таким образом, в переходнике команда jmp NativeCode(Source) заменяется на jmp NativeCode(Inject)

6) В Release-версии адрес напрямую заменяется в слотах таблицы MethodTable;
Команда mov eax, imm для x86 содержит 4-байтовый операнд imm по смещению 1 от начала команды (которая занимает 5 байт).
Команда mov rax, imm для x64 содержит 8-байтовый операнд imm по смещению 2 от начала команды (которая занимает 10 байт).
Способ вызова через переходники не меняется с самого начала CLR (указанный способ можно мониторить в исходниках CLR на github).
Единственное, что приходится учитывать — не изменилась ли реализация ThePreStub, поскольку способ поиска PrestubWorker основывается на том, что ThePreStub не вызывает других функций, кроме PrestubWorker. Функции ThePreStub нет в исходниках (поскольку она реализована на ассемблере), приходится проверять на практике.
В планах написать такую же библиотеку для Mono под Linux-ые платформы.
Нет, именно(!!!) mov ebp, ebp.
Команда смысла не несет, а используется в качестве идентифицирующего признака переходника.
Да, для простоты в примере приведен класс для одного метода.
Но в этом же классе можно перехватить сколько угодно методов для произвольных классов.
Для этого в функции GetTypes нужно указать все требуемые классы, а в функции OnLoad
(в зависимости от принятого класса) перехватить сколько угодно его функций.
Пока, особо не афишируясь, используется в промышленных разработках, где необходимо перехватывать функции .NET.
Например, при перехвате обращений к базе данных SqlServer для обеспечения безопасного соединения.
Да, любые методы, которые можно получить через reflection.

Information

Rating
Does not participate
Registered
Activity