답변:
간단하게 구현하는 방법.
1. 파스칼 코드 이용해서 구현.
<rad studio 10.3>
type
TMyEnum = (etOne, etTwo, etThree, etFour, etFive);
TMySets = set of TMyEnum;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TRttiSetType(TRttiContext.Create.GetType(TypeInfo(TMySets))).ElementType as TRttiOrdinalType do
begin
var I: Integer;
for I := MinValue to MaxValue do
Memo1.Lines.Add(GetEnumName(Handle, I));
end;
end;
2. C++로 델파이 RTTI 내부구조 직접 액세스해서 구현. (포인터 기초)
32/64 bit 컴파일 모두 지원하도록 구현
<rad studio 10.3>
#include < string >
enum class TMyEnum {etOne, etTwo, etThree, etFour, etFive};
// legacy compiler
// typedef Set < TMyEnum, TMyEnum::etOne, TMyEnum::etFive > TMySets;
using TMySets = Set < TMyEnum, TMyEnum::etOne, TMyEnum::etFive >;
void EnumerateSetTypeDelphiRttiInternal(PVOID pData)
{
PBYTE p = (PBYTE)pData;
p = (PBYTE)(*(ULONG_PTR *&)*(*(p+1) + (p+3))+1), p += *p + 2;
DWORD K = *((DWORD *&)p)++, M = *((DWORD *&)p)++;
for(p += sizeof(p); K <= M; ++K, p += *p + 1)
Form1->Memo1->Lines->Add( std::string((PCHAR)p+1, *p).c_str() );
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnumerateSetTypeDelphiRttiInternal(__delphirtti(TBorderIcons));
EnumerateSetTypeDelphiRttiInternal(__delphirtti(TMySets));
}
델파이로 컴파일된 실행파일이 크기가 큰 것은 다량의 RTTI 정보가 컴파일을 통해서
바이너리에 Emit 되기 때문이고, 이와 같은 델파이 RTTI 정보는 바이너리 곳곳에 산재하면서 상당 부분을 차지해서
해커에게 먹잇 감을 거져 주는 거나 마찬가지 인데...
해킹의 취약성에도 불구하고 델파이가 확장된 RTTI 정보를 생성하고 있는 것은...
Object Inspector를 이용한 Form Design 방식이 RTTI 를 이용해서 구현하고 있기 때문.
RTTI 정보를 확장해서 사용하지 않으면 Object Inspector를 이용한 Form Design 방식이 불가능해서
해킹에 쉽게 노출 될 수 밖에 없는 구조.