Форум: "Потрепаться";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];
ВнизPrivate свойство Найти похожие ветки
← →
Сюткин Павел (2003-05-22 14:43) [0]Как можно изменить свойство класса, которое является private?
← →
MBo (2003-05-22 14:45) [1]Никак.
← →
Palladin (2003-05-22 14:49) [2]На то оно и private, в концепции реализации ООП в Delphi о нем вообще никто знать не должен кроме самого класса...
← →
Юрий Зотов (2003-05-22 15:13) [3]Вероятно, имелось в виду все же поле, а не свойство. Свойства как-то не принято в private запихивать - смысла нет.
Вообще говоря, изменить можно. Ссылка на экземпляр объекта нам всегда известна, а по ней первые 4 байта - ссылка на класс, далее идут поля в порядке их объявления (начиная с самого дальнего предка) и с соответствующим выравниванием. Поэтому, глядя в исходники, можно вычислить смещение поля - и делай с ним что хочешь.
Только делать этого не нужно. Во-первых, получается зависимость от версии исходников (чуть изменили - и привет!), а во-вторых, если возникла такая необходимость, то это говорит о серьезных промахах в проектировании. Вот ТАМ и надо копать.
← →
Ihor Osov'yak (2003-05-22 15:27) [4]> Поэтому, глядя в исходники, можно вычислить смещение поля - и делай с ним что хочешь.
Или написать своего наследника от предка класса - жертвы с аналогичным размещением полей. И публичным методом доступа к этому полю. Потом силовое приведение типов - и дело в шляпе.
Но снова смотрим, причем долго - Юрий Зотов © (22.05.03 15:13)
> Только делать этого не нужно. Во-первых, получается зависимость от версии исходников (чуть изменили - и привет!), а во-вторых, если возникла такая необходимость, то это говорит о серьезных промахах в проектировании. Вот ТАМ и надо копать.
Правда тут оговорка - для способа, придложенного мною, будет критичным только те изменения, где затрагивается размещение полей, идущих перед целевым полем в классе-жертве. Нужно будет синхронно отслеживать изменения в своем классе, который используется для силового приведения.
Ну а в части " то это говорит о серьезных промахах в проектировании. Вот ТАМ и надо копать." ЮЗ абсолютно прав.
← →
Palladin (2003-05-22 15:51) [5]:) ну началось...
Q:на кой черт Borland вводила private и protected?
A:что бы Юрий Зотов и Ihor Osov"yak рассказывали как это обойти...
← →
Сюткин Павел (2003-05-22 15:56) [6]Исходников, к глубочайшему сожалению, нет. Есть dcu и знание того, что поле типа string объявлено как private.
Поставлена задача программным путем достучаться до него и исправить его ошибочное значение.
← →
Palladin (2003-05-22 16:01) [7]а как оно туда попадает?
имхо помоему это смахивает на взлом небесплатного компанента...
← →
MBo (2003-05-22 16:03) [8]Есть ли хотя бы интерфейсная часть, чтобы знать, какое смещение этого поля?
Иначе, если известна строка-неправильное значение, придется сканировать ВАП процесса для ее нахождения, затем область данных объекта для нахождения найденного указателя
← →
Юрий Зотов (2003-05-22 16:06) [9]Имеется ли свойство, связанное с этим полем? Хотя бы read-only, этого уже достаточно:
type
TMyClass = class
private
FMyField: TMyType;
public
property MyField: TMyType read FMyField;
end;
.......
var
P: ^TMyType;
...
P := @MyField;
P^ := NewValue;
...
← →
rounin (2003-05-22 16:11) [10]>Юрий Зотов © (22.05.03 16:06)
> P := @MyField;
Взять адрес свойства???
Или я сильно отстал от жизни, или одно из двух...
← →
Юрий Зотов (2003-05-22 16:16) [11]> rounin (22.05.03 16:11)
Странно выглядит, да? Однако же, работает. Таким образом я переназначал Application.MainForm (правда, не через указатель, а через Read/WriteProcessMemory, но суть от этого не меняется - все равно указывалось "взять адрес свойства").
← →
rounin (2003-05-22 16:17) [12]Действительно, чёрт возьми...
← →
Сюткин Павел (2003-05-22 17:41) [13]Юрий Зотов, Ihor Osov"yak и MBo, большое спасибо за помощь, постараюсь переварить полученную от вас информацию.
Нет, это не взлом, это горькое наследие, оставшееся после работавшего на фирме до меня одного программиста :(((
← →
Сюткин Павел (2003-05-22 18:17) [14]Хм... нашел-таки первоначальные (сырые) исходники модуля.
Поле класса не имеет свойств и назначается в момент создания самого класса.
То есть выхода, полагаю, нет?
← →
MBo (2003-05-22 18:22) [15]см:
>Поэтому, глядя в исходники, можно вычислить смещение поля - и делай с ним что хочешь.
← →
Ihor Osov'yak (2003-05-22 21:08) [16]
2 Сюткин Павел
Класс-жертва :
unit originalUnit;
type
TVictim = class(TAncestorVictim)
private
fField1:TType1;
fField2:TType2;
..
fFieldN:TTypeN;
fTargetField:TTypeTarget;
...
end;
наш юнит
{$HINTS OFF}
TPseudoClass = class(TAncestorVictim)
private
fField1:TType1;
fField2:TType2;
..
fFieldN:TTypeN;
fTargetField:TTypeTarget;
end;
{$HINTS ON}
procedure SetPrivateField(aVictim:TVictim; aVal:TTypeTarget);
begin
TPseudoClass(aVictim).fTargetField := aVal;
end;
или на реальном классе:
program Project1;
{$APPTYPE CONSOLE}
uses
windows,SysUtils,
classes;
type
{$HINTS OFF}
TPseudoClass = class(TStrings)
private
private
FList: PStringItemList;
FCount: Integer;
FCapacity: Integer;
end;
{$HINTS ON}
procedure SetPrivateField(aVictim:TStringList; aVal:integer);
begin
TPseudoClass(aVictim).FCapacity := aVal;
end;
BEGIN
end.
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c