Единицы функции замены

Обычно такого рода сценариям нужен такой параметр, как start, stop, reload ... Вы пробовали? Имеет ли /etc/init.d/uhttpd права на исполнение?

5
задан 22 January 2009 в 14:08
поделиться

5 ответов

Замена функции во времени выполнения является трудной, но обычно технически возможной. "Все", что необходимо сделать:

  • возьмите адрес рассматриваемой функции
  • демонтируйте первые 5 байтов или так (для проверки на инструкцию RET - очень маленькие стандартные программы могут примкнуть к другой стандартной программе, препятствуя тому, чтобы Вы заменили ее),
  • измените его защиту страницы (с VirtualProtect) быть перезаписываемым
  • перепишите первые 5 байтов с инструкцией JMP rel32 (т.е. E9 <offset-to-your-func>)
  • реализуйте свою функцию версии как нормальную, удостоверившись, что она имеет те же аргументы и соглашение о вызовах как функция, которую Вы дразните

Более легкий подход должен был бы связаться против другой версии SysUtils.pas. Это потребует, чтобы Вы также перекомпилировали все единицы в RTL и VCL, которые зависят от SysUtils.pas, но это вероятно вполне немного легче, чем функциональный подход инструментария, описанный выше.

Самый легкий подход является уровнем языка один, где любой, Вы непосредственно не полагаетесь на SysUtils вообще (и так может переключиться в более высоком уровне), или Вы изменяете uses объявление для условного обращения к другой единице.

11
ответ дан 18 December 2019 в 08:31
поделиться

Можно сделать это с MadCodeHook. Используйте HookCode функционируйте, дайте ему адрес функции, которую Вы хотите заменить и адрес функции, которой Вы хотите позвониться вместо этого. Это даст Вам, поддерживают указатель функции, который можно использовать для вызова оригинала и для отсоединения позже. В сущности это реализует средние три шага описания Barry.

Я думаю, что MadCodeHook свободен для персонального использования. Если Вы ищете что-то свободнее, чем которое, можно попытаться найти старую версию средств управления Unicode Tnt. Это использовало тот же метод сцепления для введения поддержки Unicode в часть кода VCL. Вам будет нужна старая версия, потому что более свежие выпуски больше не являются бесплатными. Найдите OverwriteProcedure функция в TntSystem.pas, который является также, где Вы найдете примеры того, как использовать его.

Сцепление кода хорошо, потому что оно не требует, чтобы Вы перекомпилировали RTL и VCL, и оно не включает условную компиляцию для управления, какие функции находятся в объеме. Можно сцепить код из процедуры установки модульного теста, и исходный код никогда не будет знать различия. Это будет думать, что называет оригинал FileExists функция (потому что это), но когда это добирается там, это сразу перейдет к Вашей дразнившей версии вместо этого.

7
ответ дан 18 December 2019 в 08:31
поделиться

Спасибо,

да, было бы замечательно иметь класс TSysUtils, например, вместо этого, что я мог наследоваться со своим MockSysUtils. Но, дело не в этом и огромная кодовая база. Это будет заменено поразрядно, но я задался вопросом, было ли решение быстрого запуска.

Первый подход хорошо для одной функции, возможно, но не в этом случае я предполагаю.

Я пойду для второго подхода.

0
ответ дан 18 December 2019 в 08:31
поделиться

Вы могли также просто добавить единицу, которая только содержит функции, которые Вы хотите дразнить к тестовому пункту использования единицы. Delphi будет всегда использовать функцию от единицы, которая перечислена в последний раз. К сожалению, это потребовало бы, чтобы Вы изменили единицу, которую Вы хотите протестировать.

Ваша Ложная-Sysutils единица:

unit MockSysutils;

interface

function FileExists(...) ...
...
end.

Ваша единица, Вы хотите протестировать:

unit UnitTotest;

interface

uses
  Sysutils,
  MockSysUtils;

...

  if FileExists(...) then

FileExists теперь назовет версию от MockSysutils, а не от Sysutils.

1
ответ дан 18 December 2019 в 08:31
поделиться

Это - немного путь там, но здесь является другой альтернативой.

При создании модульных тестов и основной кодовой базы для движения с ним Вы могли grep все функции, которые Вы хотите заменить и указать единицу для использования

Вместо

fileexists(MyFilename);

Вы могли grep fileexists и заменять

MockTests.fileexists(MyFileName);

Если бы Вы сделали это во время изготовления (использующий автоматизированные инструменты сборки), то это могло бы легко быть сделано и предоставило бы Вам самую большую гибкость. У Вас мог просто быть файл конфигурации, который перечислил все функции, которые будут заменены.

0
ответ дан 18 December 2019 в 08:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: