원리를 간단히 설명하면 스테가노그래피(Steganography)임.

실행 파일을 포함해서 이미지나 사운드, 동영상 같은 바이너리 파일은 대부분 헤더에 크기 정보를 가지고 있어서

파일 맨 뒤에 어떤 내용을 추가하든 파일 자체의 기능에 전혀 영향을 주지 않는 경우가 많아.

EXE 파일(PE 포맷)도 마찬가지라서 이 프로그램은 그 원리를 이용해서 파일 맨 뒤에 메시지 내용을 써 넣고 시그너쳐를 넣는 방식으로

구현됨 :)


아래는 그 소스 코드. 그냥 프갤에 재미로 올리려고 대충 발코딩으로 짠 거니 코딩 스타일이나 버그 같은 걸로

지적하는 사람은 없길 :p


#include <stdio.h>

#include <windows.h>

#pragma warning(disable: 4996)

 

#define EXE_FOOTER_SIGNATURE  0xDEADBEEF

typedef struct {

        int     iMessageLen;

        int iSignature;

} EXE_FOOTER, *PEXE_FOOTER;

 

char *readall(FILE *fp, long *readsize = NULL);

 

int main(int argc, char *argv[]) {

        CHAR szExePath[MAX_PATH];

        GetModuleFileNameA(NULL, szExePath, MAX_PATH);

 

        FILE *fp = fopen(szExePath, "rb");

        if (!fp) return 1;

 

        EXE_FOOTER foot;

        fseek(fp, -8, SEEK_END);

        fread(&foot, sizeof(EXE_FOOTER), 1, fp);

        if (foot.iSignature == EXE_FOOTER_SIGNATURE) {

               fseek(fp, -(8 + foot.iMessageLen), SEEK_END);

               char *msg = new char[foot.iMessageLen + 1];

               fread(msg, sizeof(char), foot.iMessageLen, fp);

               msg[foot.iMessageLen] = '\\0';

               printf("Message\\n====================================\\n%s\\n", msg);

               getchar();

               return 0;

        }

 

        if (argc != 3) {

               fprintf(stderr, "Message Compiler v1.0\\n\\n"

                       "Usage: %s <msgfile> <outfile>\\n\\nParameters:\\n"

                       "\\t<msgfile>: 메시지가 담긴 텍스트 파일(ANSI encoding)을 지정합니다.\\n"

                       "\\t<outfile>: 빌드된 실행파일이 저장될 파일 이름을 입력합니다.\\n", argv[0]);

               return 1;

        }

 

        long lEXELen;

        char *exe = readall(fp, &lEXELen);

        fclose(fp);

 

        FILE *fp_text = fopen(argv[1], "rb");

        if (!fp_text) {

               fprintf(stderr, "[!] An error occurred while opening file %s!\\n", argv[1]);

               return 1;

        }

        long lTextLen;

        char *text = readall(fp_text, &lTextLen);

        fclose(fp_text);

 

        FILE *fp_out = fopen(argv[2], "wb");

        if (!fp_out) {

               fprintf(stderr, "[!] An error occurred while creating file %s!\\n", argv[2]);

               return 1;

        }

        fwrite(exe, sizeof(char), lEXELen, fp_out);          // write exe binary

        fwrite(text, sizeof(char), lTextLen, fp_out); // write message

        foot.iMessageLen = lTextLen;

        foot.iSignature = EXE_FOOTER_SIGNATURE;

        fwrite(&foot, sizeof foot, 1, fp_out);

        fclose(fp_out);

 

        printf("[+] EXE Created!\\n");

        return 0;

}

 

char *readall(FILE *fp, long *readsize) {

        fseek(fp, 0, SEEK_END);

        long lFileSize = ftell(fp);

        if (readsize) *readsize = lFileSize;

        fseek(fp, 0, SEEK_SET);

 

        char *arr = new char[lFileSize];

        fread(arr, sizeof(char), lFileSize, fp);

        return arr;

}


그냥 하이라이팅 없이 올릴게 ㅡㅡ;