Форум: "Прочее";
Текущий архив: 2016.05.08;
Скачать: [xml.tar.bz2];
ВнизПятничная головоломка от Розыча Найти похожие ветки
← →
Rouse_ © (2015-08-20 21:22) [0]
program PtrTest;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TTestClass = class
private
FFirst, FSecont, FThird: Integer;
public
function GetParamValue(Index: Integer): Integer;
end;
{ TTestClass }
function TTestClass.GetParamValue(Index: Integer): Integer;
begin
Result := -1;
case Index of
0: Result := FFirst;
1: Result := FSecont;
2: Result := FThird;
end;
end;
var
A: TTestClass;
B: array [0..2] of Int64;
C: array of Integer;
D: string;
pA, pB, pC, pD: Pointer;
begin
try
A := TTestClass.Create;
try
SetLength(C, 3);
D := StringOfChar(#0, 3);
pA := @A;
pB := @B;
pC := @C;
pD := @D;
{ TODO : Реализовать код здесь...
используя только указатели pA, pB, pC и pD
произвести следующие изменения
1. Поле FThird класса А должно принять значение 1
2. B[2] должно равнятся двум
3. С[2] должно равнятся трем
4. D[3] должно равнятся четырем
}
// выводим результат
Writeln(A.GetParamValue(2));
Writeln(B[2]);
Writeln(C[2]);
Writeln(Byte(D[3]));
finally
A.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ": ", E.Message);
end;
Readln;
end.
← →
Rouse_ © (2015-08-20 21:29) [1]Опс, забыл нюанс - она решается без использования дебагера.
(Можно и с помощью его, но смысл теряется)
← →
Игорь Шевченко © (2015-08-20 21:31) [2]Зачем ?
← →
Rouse_ © (2015-08-20 21:33) [3]А зачем вообще нужны задачи? :)
Данный пример показывает как человек умеет работать с памятью и понимает ее адресацию.
← →
Pavia © (2015-08-20 21:47) [4]А что надо сделать?
И честно не понимаю как. Т.е. какие выражения можно использовать и какие операции?
← →
DayGaykin © (2015-08-20 21:55) [5]
TTestClass(pA^).FThird := 1;
PInt64Array(pB)^[2] := 2;
PIntegerArray(pC)^[2] := 3; // Не работает. Как найти @C[0] по @C не знаю. Разница между ними большая.
PString(pD)^[3] := Char(4);
← →
Pavia © (2015-08-20 22:06) [6]
> А зачем вообще нужны задачи? :)Данный пример показывает
> как человек умеет работать с памятью и понимает ее адресацию.
Не понятно что вы хотите увидеть?
Вирт Н. учил структурировать свой код. Поэтому использовать указатели тут не разумно. Тем более так. Если вы хотите посмотреть кто как использует арифметику указателей. Так это от задачи зависит.
Лично я делаю так.
type // Вспомогательные типы
PColor=^TColor;
PAColor=^TAColor;
TAColor=array [0..65535] of TColor; // Своеобразный хак. магические константы могут быть любыми, но порой лучше от 0.
procedure Filter(var Goal:TBitmap; bp:TBitmap);
var
InRow:PAColor; // Указатель на массив Цветов.
OutRow:PAColor;
begin
...
InRow:=Bp.Canvas.ScanLine[y];
Inc(PColor(InRow),X); // Смещение указателя на X*SizeOf(TColor)
a:=0;
for i:=-1 to 1 do
a:=a+InRow[i]; {Смещение указателя на I*SizeOf(TColor) относительно X}
OutRow[x]:=a;
...
Inc(PByte(OutRow), LineLen); // Смещение на заданное число байт. Переход к другой строке. Не обязательно кратный SizeOf(TColor).
...
← →
DayGaykin © (2015-08-20 22:08) [7]А, догнал:
TTestClass(pA^).FThird := 1;
PInt64Array(pB)^[2] := 2;
PIntegerArray(pC^)^[2] := 3;
PString(pD)^[3] := Char(4);
← →
Rouse_ © (2015-08-20 22:10) [8]
> Pavia © (20.08.15 21:47) [4]
> А что надо сделать?
> И честно не понимаю как. Т.е. какие выражения можно использовать
> и какие операции?
Так как мы все программисты, то мы понимаем как данные располагаются в памяти.
Осталось только вспомнить пару нюансов.
> DayGaykin © (20.08.15 21:55) [5]
Молодец, почти попал, подумай.
← →
Pavia © (2015-08-20 22:13) [9]Я бы вместо
pA := @A;
pB := @B;
pC := @C;
pD := @D;
Написал бы так.pA := @A[0];
pB := @B[0];
pC := @C[0];
pD := @D[0];
Просто динамические массивы во FreePascal и Delphi имеют разную структуру. А так не нужно разбирать их заголовок.
← →
Rouse_ © (2015-08-20 22:15) [10]
> Pavia © (20.08.15 22:13) [9]
Напиши :)
← →
DayGaykin © (2015-08-20 22:15) [11]
> Просто динамические массивы во FreePascal и Delphi имеют
> разную структуру
Полагаю, в реальной жизни это никогда не потребуется.
← →
Игорь Шевченко © (2015-08-20 22:20) [12]Rouse_ © (20.08.15 21:33) [3]
> А зачем вообще нужны задачи?
Такие - не знаю, потому и спрашиваю. Вообще любая задача должна чему-то учить для применения в дальнейшем, а тут я не вижу предмета для обучения. Например, лезть в приватные поля класса, хоть через указатели, хоть через что - совершенно дурной тон.
← →
Pavia © (2015-08-20 22:51) [13]Вот в Delphi 7 работает.
type
PAInteger=^TAInteger;
TAInteger=array [0..65535] of Integer;
PAInt64=^TAInt64;
TAInt64=array [0..65535] of Int64;
...
pA := @A;
pB := @B;
pC := @C;
pD := @D;
TTestClass(pA^).FThird:=1;
PAInt64(pB)[2]:=2;
PAInteger(pC^)[2]:=3;
PByte(@PString(pD)^[3])^:=4;
← →
Pavia © (2015-08-20 22:58) [14]А вот если вначале добавить ключик {$H-}, то код ломается.
Интересно, а сразу для всех 4 типов строк такое сделать можно?
← →
Игорь Шевченко © (2015-08-20 23:19) [15]Но тем не менее, я сделал :)
← →
Rouse_ © (2015-08-21 10:25) [16]
> Pavia © (20.08.15 22:58) [14]
> А вот если вначале добавить ключик {$H-}, то код ломается.
>
>
> Интересно, а сразу для всех 4 типов строк такое сделать
> можно?
Нет конечно, для каждой свой подход, в этом и фишка :)
← →
SergP © (2015-08-21 12:02) [17]2 Rouse_
"используя только указатели", это типа так?// для pa я хз
pint64(integer(pb)+2*sizeof(Int64))^:=2;
pinteger(pinteger(pc)^+2*sizeof(integer))^:=3;
pchar(pinteger(pd)^+2*sizeof(Char))^:="4";
← →
SergP © (2015-08-21 12:12) [18]
> 4. D[3] должно равнятся четырем
четырем - это в смысле 4 или "4" ?
← →
Rouse_ © (2015-08-21 12:18) [19]
> SergP © (21.08.15 12:02) [17]
> 2 Rouse_
>
> "используя только указатели", это типа так?
Можно и так. Вот несколько вариантов:pA := Pointer(pA^);
pA := PByte(pA) + SizeOf(Pointer) + 8;
PInteger(pA)^ := 1;
pB := PByte(pB) + 16;
PInteger(pB)^ := 2;
pC := Pointer(pC^);
pC := PByte(pC) + 8;
PInteger(pC)^ := 3;
pD := Pointer(pD^);
pD := PByte(pD) + 4;
PInteger(pD)^ := 4;PInteger(NativeInt(pA^) + 2 * SizeOf(Integer) + SizeOf(Pointer))^ := 1;
PInt64(NativeInt(pB) + 2 * SizeOf(Int64))^ := 2;
PInteger(NativeInt(pC^) + 2 * SizeOf(Integer))^ := 3;
PChar(NativeInt(pD^) + 2 * SizeOf(Char))^ := #4;
← →
Игорь Шевченко © (2015-08-21 12:19) [20]Как-то так. Хотя, повторюсь, задача неинтересная
PIntegerArray(pA^)^[3] := 1;
PByteArray(pB)^[2*SizeOf(Int64)] := 2;
PIntegerArray(pC^)^[2] := 3;
(PString(pD))^[3] := Char(4);
← →
Rouse_ © (2015-08-21 12:21) [21]ЗЫ: резюмируя
вариант от Pavia © (20.08.15 22:51) [13] работает правильно, учитывая 32 и 64 бита.
а вариант от SergP © (21.08.15 12:02) [17] работает только на 32 битах.
← →
Rouse_ © (2015-08-21 12:22) [22]ЗЗЫ: у ИШ ошибка в 1 при 64 битах, не такая уж и не интересная задача :)
← →
Игорь Шевченко © (2015-08-21 12:33) [23]Rouse_ © (21.08.15 12:22) [22]
Да, согласен, но ты уже привел пример, так что исправлять нет смысла.
И все-таки я не понимаю, зачем она нужна, эта задача. За подобные извращения надо сразу поражать в правах.
← →
Rouse_ © (2015-08-21 12:39) [24]:)
Ну почему сразу поражать, просто проверка как человек работает с указателями и как понимает как данные размещаются в памяти, иногда может и пригодится (к примеру у меня прямая работа с данными в памяти в паре мест где нужна была высокая скорость, встречается)
← →
Игорь Шевченко © (2015-08-21 13:01) [25]Rouse_ © (21.08.15 12:39) [24]
Поражать за то, что код непонятен.
> к примеру у меня прямая работа с данными в памяти в паре
> мест
Вот у Саши Шарахова, тут присутствующего, прямая работа тоже встречается, даже в SysUtils включена. Однако, без подобных извратов.
← →
Rouse_ © (2015-08-21 13:26) [26]ну если человек не знает как данные размещены в памяти то ему даже код от Sha не поможет :)
← →
DayGaykin © (2015-08-21 14:02) [27]Я, например, не знаю как поля экземпляров класса в памяти размещаются и где располагается заголовок динамического массива. Это совершенно не мешает мне трудиться.
← →
DayGaykin © (2015-08-21 14:06) [28]Более того, это никак не отражает моего понимания того как работают указатели.
← →
NoUser © (2015-08-21 16:32) [29]> Rouse_ © (20.08.15 21:22) [0] +
Можно было еще и динамический n-мерный массив добавить,
и указать в условии, что присвоение должно быть выполнено с помощью Move.
Ну и на выравнивание полей в записи что-то придумать.
> Pavia © (20.08.15 22:13) [9]
> Просто динамические массивы во FreePascal и Delphi имеют разную структуру.
А поподробнее ?, так как иногда возникает желание переехать на FreePascal.
← →
DayGaykin © (2015-08-21 16:43) [30]
> так как иногда возникает желание переехать на FreePascal.
IDE у фрипаскаля еще хуже чем у Delphi. Плохая идея.
← →
Rouse_ © (2015-08-21 16:56) [31]
> NoUser © (21.08.15 16:32) [29]
> > Rouse_ © (20.08.15 21:22) [0] +
> Можно было еще и динамический n-мерный массив добавить,
Можно, но имх и этого достаточно. Вариантов то можно много так наплодить :)
← →
Rouse_ © (2015-08-21 16:57) [32]
> DayGaykin © (21.08.15 14:02) [27]
> Я, например, не знаю как поля экземпляров класса в памяти
> размещаются и где располагается заголовок динамического
> массива. Это совершенно не мешает мне трудиться.
Естетсвенно, большинству это и не нужно, мне же при написании кода защиты приходится много чего желать, в том числе и шифровать данные созданных классов в нужных местах, поэтому все зависит от поставленных задач.
← →
Игорь Шевченко © (2015-08-21 17:00) [33]
> поэтому все зависит от поставленных задач.
Когда под рукой нет ничего, кроме молотка...
← →
Rouse_ © (2015-08-21 17:09) [34]
> Игорь Шевченко © (21.08.15 17:00) [33]
> Когда под рукой нет ничего, кроме молотка...
Спорно.
← →
Игорь Шевченко © (2015-08-21 17:58) [35]Rouse_ © (21.08.15 17:09) [34]
> мне же при написании кода защиты приходится много чего желать,
> в том числе и шифровать данные созданных классов в нужных
> местах
Это же не моя фраза. Но даже данные созданных классов можно шифровать без извращений, если классы спроектированы корректно. Delphi, например, умеет сохранять данные созданных классов в dfm, в этот же механизм вполне можно встроить все, что угодно, в том числе и шифрование
← →
Rouse_ © (2015-08-21 18:50) [36]
> Игорь Шевченко © (21.08.15 17:58) [35]
> Это же не моя фраза. Но даже данные созданных классов можно
> шифровать без извращений, если классы спроектированы корректно.
> Delphi, например, умеет сохранять данные созданных классов
> в dfm, в этот же механизм вполне можно встроить все, что
> угодно, в том числе и шифрование
Классно рассказал - в теории оно наверное так и выглядит :)
Нет, Игорь, все гораздо проще и сложнее.
Взламывать твое приложение будут не в DFM а правкой памяти запущенного экземпляра приложения. Это же открытая книга - правь что хочешь (вопрос как от этого защититься).
А сам этот тест один из моих стандартных, которые проходили люди при приеме к нам в коллектив на вакансию разработчика VM под 64 бита.
Видишь как все просто иногда бывает :)
← →
Игорь Шевченко © (2015-08-21 19:04) [37]Rouse_ © (21.08.15 18:50) [36]
> разработчика VM под 64 бита
Это что ?
> Взламывать твое приложение будут не в DFM а правкой памяти
> запущенного экземпляра приложения. Это же открытая книга
> - правь что хочешь (вопрос как от этого защититься).
Да, я понимаю, что у тебя все вопросы так или иначе связаны с взломом, тут мы в разных сферах совсем.
← →
Masterucs © (2015-08-21 19:15) [38]Rouse_, неужели таки нашли тебе помощника?! )
← →
Sha © (2015-08-21 19:31) [39]> Rouse_ © (21.08.15 18:50) [36]
> А сам этот тест один из моих стандартных...
Кстати, Саш, мысль мелькнула после задачи про тип DayTime.
Можно добавить еще один уровень виртуализации при хранении чисел.
Представлять в системе с переменным основанием и хранить как integer ли int64.
Можно и арифметику свою сделать)
← →
Rouse_ © (2015-08-21 19:39) [40]
> Игорь Шевченко © (21.08.15 19:04) [37]
> Это что ?
Разработка виртуальной машины под 64 бита.
> Masterucs © (21.08.15 19:15) [38]
> Rouse_, неужели таки нашли тебе помощника?! )
Нет, не получилось, не смогли найти человека с устраивающей меня квалификацией.
Поэтому вакансия открыта.
> Sha © (21.08.15 19:31) [39]
> Можно добавить еще один уровень виртуализации при хранении
> чисел.
> Представлять в системе с переменным основанием и хранить
> как integer ли int64.
> Можно и арифметику свою сделать)
У меня в виртуалке троичная система счисления используется, кстати по твоей подсказке, ну и плюс шифрование :)
← →
DayGaykin © (2015-08-21 22:39) [41]А как код для этой VM создается?
← →
Rouse_ © (2015-08-22 01:01) [42]Декомпилируем машкод, строим графы, анализируем векторы графов для рассчета порога виртуализации (грубо чтобы незначащий инкремент в цикле не отнимал 90 процентов в пикода на развертке цикла, к примеру), генерируем машкод с заглушками на местах оффсетоф, потом обфусцируем в несколько проходов, результат идет на компилер ВМ.
Финальная машина не сильно принципиальна, я обычно стековый стакан использую на стрелке Пирса, но при должном опыте даже на брейнфак можно заточить
← →
Германн © (2015-08-22 01:08) [43]
> DayGaykin © (21.08.15 22:39) [41]
>
> А как код для этой VM создается?
← →
Германн © (2015-08-22 01:10) [44]
> Rouse_ © (22.08.15 01:01) [42]
>
> Декомпилируем машкод, строим графы, анализируем векторы
> графов для рассчета порога виртуализации (грубо чтобы незначащий
> инкремент в цикле не отнимал 90 процентов в пикода на развертке
> цикла, к примеру), генерируем машкод с заглушками на местах
> оффсетоф, потом обфусцируем в несколько проходов, результат
> идет на компилер ВМ.
> Финальная машина не сильно принципиальна, я обычно стековый
> стакан использую на стрелке Пирса, но при должном опыте
> даже на брейнфак можно заточить
Это просто шедевр!
:)
← →
Inovet © (2015-08-22 01:31) [45]Статья у тебя была на эту тему. Помнится, я тогда опознал Брейнфак, хотя, был бы другой, может быть, и другой бы за него принял.:)
← →
Rouse_ © (2015-08-22 02:22) [46]Ты видимо про нее: http://habrahabr.ru/post/218887/
Правда, это статья про взлом, а не про защиту :)
← →
Inovet © (2015-08-22 02:39) [47]> [46] Rouse_ © (22.08.15 02:22)
Дык, две стороны одного процесса.
← →
Pavia © (2015-08-22 11:16) [48]Удалено модератором
← →
Rouse_ © (2015-08-22 11:18) [49]Удалено модератором
← →
Rouse_ © (2015-08-22 12:08) [50]Удалено модератором
← →
Rouse_ © (2015-08-22 12:20) [51]Удалено модератором
← →
Rouse_ © (2015-08-22 12:24) [52]Перенес новую задачку в новую ветку, дабы не потерялась :)
← →
Pavia © (2015-08-22 12:31) [53]Удалено модератором
← →
Rouse_ © (2015-08-22 12:36) [54]
> Pavia © (22.08.15 12:31) [53]
Да, помню, но появились новые люди, поэтому твой пост со ссылкой на решение убил, думаю новичкам будет интересно :)
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2016.05.08;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.002 c