실행파일이 있는데 그 안에 DLL과 또다른 새끼 EXE를 내장하고 있는 프로그램을
만드는 것은 아주 쉬운 일입니다.
DLL과 EXE 같은 것을 내장해야 할 필요성이 있는 경우가 간혹씩 있기 때문에,
한번 구성해 봤습니다. DLL을 시스템 디렉토리에 비밀스럽게(?) 생성해서 사용할때 라던지
프로그램 동작 방식을 숨기고 싶을때 가끔씩 필요하기도 합니다.
그렇지만 이 내용은 그냥 평범한 것이고 팁이라고 하기도 그저그런 수준이죠.
빌더에서 이 예제를 하나 만들어 두는 것도 좋을 것 같아서 작업한 파일을 모두 묶어서 올려 둡니다.
빌더에서 이 작업을 하려면 MyRes.RC 파일을 하나 만드는 것이 우선이겠죠.
지정한 파일을 리소스로 만들어 EXE에 포함시키기 위해서이죠.
MyDLL DLL MyDLL.dll
MyEXE EXE MyEXE.exe
내용은 이 2줄이면 충분합니다.
첫째줄은 리소스에 MyDLL 이라는 명칭을 가지고 형식은 DLL 이며, 내장을 위해 지정한 파일명은 MyDLL.dll 입니다.
둘째줄도 마찬가지.
이 RC 파일을 프로젝트에 포함시켜 컴파일하면 MyRes.res가 생성되고 이 안에 지정한 dll 과 exe가 들어가고
이는 최종적으로 실행파일과 하나로 통합됩니다.
실행파일이 만들어지고 빈 디렉토리에 실행파일을 옮겨 놓고 실행하면
DLL와 EXE를 각각 생성합니다.
DLL은 윈도우가 설치된 폴더에 생성되고, EXE는 현재 폴더에 생성됩니다.
그리고 이 둘을 핸들링하는데 소스는 아래와 같습니다.
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
struct TM
{
HINSTANCE hDLL;
} m;
//---------------------------------------------------------------------------
// 리소스에서 지정한 데이타를 파일로 저장한다.
bool SaveFileFromResource(char *name, char *type, char *save_filename)
{
bool r = false;
TResourceStream *st;
try
{
st = new TResourceStream((int)HInstance, name, type);
st->SaveToFile(save_filename);
r = true;
}
__finally
{
delete st;
}
return r;
}
// rc로 내포한 실행화일을 찾아서 윈도우즈 디렉토리에 C:\windows 또는
// c:\winnt 등의 폴더에 생성한다.
//
bool SaveFileFromResource_SaveToWindowsFolder(char *name, char *type, char *save_filename)
{
char file[201];
GetWindowsDirectory(file, 200);
strcat(file, "\\");
strcat(file, save_filename);
return SaveFileFromResource(name, type, file);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
SaveFileFromResource_SaveToWindowsFolder("MyDLL", "DLL", "MyTestDLL.dll");
SaveFileFromResource("MyEXE", "EXE", "MyEXE.exe");
m.hDLL = LoadLibrary("MyTestDLL.dll");
if (m.hDLL == NULL)
{
Edit1->Text = "MyTestDLL.dll이 로드 안되네요.";
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
#if 0 // 이건 표준방식
typedef char* __stdcall (*TFnWhoAreYou)();
TFnWhoAreYou WhoAreYou = (TFnWhoAreYou)GetProcAddress(m.hDLL, "WhoAreYou");
if (WhoAreYou)
{
Edit1->Text = WhoAreYou();
}
#else // 이건 트릭 그러나 잘 동작함
void* WhoAreYou = GetProcAddress(m.hDLL, "WhoAreYou");
if (WhoAreYou)
{
char *res;
asm call WhoAreYou;
asm mov res, eax;
Edit1->Text = res;
}
#endif
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
FreeLibrary(m.hDLL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
WinExec("MyEXE.exe", SW_HIDE);
}
//---------------------------------------------------------------------------
첨부 파일에는 여기에 사용된 모든 파일과 코드가 들어 있습니다.
참고하세요.