このコードに出くわしたとき、起動時にそれをアンパックするセクションを実行可能ファイルに書き込む単純な実行可能パッカーのコードを調べていました。
void setDistance( unsigned long size )
{
char* set = (((char *)I)+pUnpacker->VirtualAddress);
union
{
short sh[2];
long l;
} conv;
conv.l = size;
conv.sh[0] = 0;
unpacker_set(set, (char *)(&conv.l), 4, TEXT_DISTANCE);
}
サイズは、メモリ内のアンパッカー コードから、アンパックされるセクションの先頭までの距離です。ローダー コードでは、unsigned long として定義されています。一方、 unpacker_set には次のコードがあります。
void inline unpacker_set( char* at, char* what, size_t size, unsigned long sig )
{
DWORD oldprotect;
unsigned char *set = (unsigned char *)at;
while(*((unsigned long*)(set)) != sig)
set++;
if(VirtualProtect(set, size, PAGE_READWRITE, &oldprotect) == TRUE)
for(unsigned i=0; i<size; i++)
*(set+i) = *(what+i);
}
2番目のルーチンがアンパッカーコードの値を置き換えることは理解していますが、なぜユニオンで面倒なことが行われるのか知りたいです。どんな助けでも大歓迎です。