C로 작성한 실행파일(exe)에 음악넣기
갑자기 실행파일에 음악포함?
배경은
어셈블리와 리버싱 기초 스터디를 진행하면서
간단한 크랙미 형태의
문제를 내주었는데
그 때 사람들이 음악을 들으면서 하면
좋을 것 같아서 음악을 실행파일에 포함해 보았지요.
안그래도 답답할텐데
노이로제걸릴만한 음악이 자꾸 나오면
^___^
강한 멘탈을 심어주기 위한 저의 세심한 배려?라고
볼 수 있겠네요.
자 이제 시작해봅시다!!
visual studio 2017을 사용했구요.
.c형태의 C언어로 작성하였습니다.
먼저, 프로젝트를 만들고
리소스파일을 우클릭 합니다.
[그림1]과 같이
[리소스파일]을 우클릭 후 [추가] - [리소스] 를 누릅니다.
[그림2]를 보면 icon을 가져오기해서 추가할 수도 있습니다.
맨 아래에 "WAVE"라고 나오는 부분이 있는데
원래는 없어야 정상입니다.
[그림3]에 추가하는 방법이 나옵니다.
[그림3]과 같이 "[프로젝트명].rc"의 코드를 확인합니다.
52라인에 보면 IDR_WAVE1 WAVE "music.wav"라고 적힌 부분이 있습니다.
IDR_WAVE1은 #define으로 추후 이 음악을 플레이 시 호출할 이름입니다.
WAVE는 WAVE형태의 리소스라는 의미입니다.
"music.wav"는 호출할 음악파일의 경로를 적어주면 됩니다.
위와 같이 설정한 경우에는 저 경로에 음악파일이 없다면?
음악이 나오지 않습니다.
음악은 wav파일만 가능한 것으로 알고 있습니다.
이 부분도 필요하다면 msdn을 참고하세요.
...
그래서 파일 내부에 포함시키기 위해
[그림5]와 같이 IDR_WAVE1을 클릭하면
[그림6]과 같이 오른쪽 아래에 편집기가 나옵니다.
여기서 External File 속성을 False로 설정해 줍니다.
그러면 음악이 외부에 존재하지 않고,
리소스영역에 음악이 그대로 저장됩니다.
단, 실행파일의 용량은 음악파일의 용량만큼
추가로 증가한다는 단점!!
이 후 [그림5]의 IDR_WAVE1을 더블클릭하면
[그림7]과 같이 음악이 첨부되어 있는 것을 확인할 수 있습니다.
다이얼로그박스도 리소스에서 추가로 생성하시면 됩니다.
참고 : https://ccurity.tistory.com/202
그 전에 링커가 링킹시에 음악재생에 필요한 라이브러리를 추가해줘야 합니다.
[그림8]과 같이 누르고
[그림9]와 같이 winmm.lib를 추가해줍니다.
이제 음악을 틀어볼까요?
소스는 C언어로 작성하였습니다.
#pragma comment(linker,"/subsystem:\"windows\" \ /entry:\"mainCRTStartup\"")
#pragma comment(lib, "winmm.lib")
#include<stdio.h>
#include<Windows.h>
#include<string.h>
#include<tchar.h>
#include "resource.h"
BOOL CALLBACK dlg_proc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) {
TCHAR buffer[0x50] = { 0 };
TCHAR myName[0x50] = { 0 };
TCHAR reverse[0x50] = { 0 };
int length;
switch (msg) {
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
length = GetDlgItemText(hdlg, IDC_EDIT1, buffer, 0x50);
DWORD dwNamesize = (DWORD)0x50;
GetUserName(myName, &dwNamesize);
int nameLength = _tcslen(myName);
int j = nameLength;
for (int i = 0; i < nameLength; i++) {
reverse[i] = myName[--j];
}
if (!_tcscmp(reverse, buffer)) {
MessageBoxA(NULL, ":) You are genius!! <<", " [+] Woooooow!", MB_OK);
EndDialog(hdlg, 0);
break;
}
else {
MessageBoxA(NULL, ":( Do not you know your name?", " [-] Error", MB_OK);
}
break;
case IDC_BUTTON1:
MessageBoxA(NULL, "You can not never turn off music! ^____^", " [*] Is not this music good ?", MB_OK);
break;
case IDCANCEL:
EndDialog(hdlg, 0);
break;
}
break;
}
return 0;
}
int main() {
HINSTANCE hInst;
hInst = GetModuleHandle(NULL);
MessageBoxA(NULL, "What your name?", "Quiz", MB_OK);
PlaySound(MAKEINTRESOURCE(IDR_WAVE1), hInst, SND_RESOURCE | SND_ASYNC | SND_LOOP);
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, dlg_proc);
return 0;
}
기본적인 API의 설명은 패스할게요~
1라인은 콘솔화면 출력하지 않겠다는 말이에요~
어차피 다이얼로그박스를 띄우는 프로그램이니..
2라인은 다른사람에게 파일로 주었을 때도 문제가 없도록 하기위해
라이브러리를 정적으로 실행파일안에 포함시킨다는 의미에요.
참고 : https://ccurity.tistory.com/233
정적라이브러리에 대한 설명은
위 링크의 (6) - [2] 에 설명이 나와있어요
PlaySound가 음악을 재생시키는 API입니다.
첫 번째 파라미터는 MAKEINTRESOURCE를 사용했는데
#define로 정의한 정수를 문자열로 바꿔줍니다.
두 번째 파라미터는 HINSTANCE형태로 현재실행주소를 넣었네요.
세 번째 파라미터는 SND_RESOURCE | SND_ASYNC | SND_LOOP 가 있는데
SND_RESOURCE는 리소스영역에 음악이 있다는 것,
SND_ASYNC는 비동기 실행을 한다는 것,
SND_LOOP는 음악 끝나면 반복하겠다는 것을 말합니다.
비동기로 실행한다..?
다들 아시겠지만 한 번 집고 넘어가면
동기실행은 끝날 때까지 기다렸다가 실행하는 형태고
그러기 때문에 음악이 끝나야 다음으로 진행되는 구조입니다.
비동기실행은 음악은 음악대로 알아서 실행하고
다음으로 진행하는 구조입니다.
왜 비동기로 실행하는지 아시겠죠?
굉장히 요약해서 설명해서 간단해보이지만
이러한 부분은 프로세스와 스레드의 이해가 뒷받침되어야
자연스럽게 넘길 수가 있어요~
위에 DialogBox 실행 시에 CALLBACK함수가 나오는데
참고 : https://ccurity.tistory.com/266
CALLBACK함수와 thread에 대한 내용은
위 링크의 6.을 보면 도움이 될지도 모르겠습니다.
여기까지 진행했으면
다이얼로그박스와 함께 음악이 나옵니다.
원래 목적이 리버싱문제를 내기 위한 것이라..
다이얼로그박스에 원하는 말이 들어오면 되겠죠?
파일을 분석하는 동안 음악은 계속 나온다니
노이로제 걸릴걸 생각하니 뿌듯하네요~
답은 PC사용자계정명을 reverse해서 적으면 됩니다.
사람들이 머리를 써서 음소거를 하기 시작했어요..
열심히 만들었는데 상처받게...
그래서 프로그램이 실행중인 동안
볼륨은 항상 MAX로 하는 기능을 추가해야겠어요.
그러나 물리적으로 스피커전원을 끄는 것은
어떻게 할 수가 없네요..
검색하다보면 음악을 넣는 방법은 많이 나오는데
전부 외부파일을 불러서 링크형태로 되어있어서
배포할 때나 음악파일이 없는 경우
아에 재생이 되지 않아서
직접 구현하였습니다!!
'Programming Language > Windows API' 카테고리의 다른 글
대화상자 생성 (0) | 2018.12.09 |
---|---|
리소스파일 (0) | 2018.12.09 |
메뉴 및 공용대화상자 (0) | 2018.10.09 |
지렁이게임 (0) | 2018.09.30 |
두더지잡기 게임 (0) | 2018.09.30 |
댓글