Programming Language/Windows API

C로 작성한 실행파일(exe)에 음악넣기

D4tai1 2019. 7. 27.

갑자기 실행파일에 음악포함?

 

배경은 

어셈블리와 리버싱 기초 스터디를 진행하면서

간단한 크랙미 형태의

문제를 내주었는데

 

그 때 사람들이 음악을 들으면서 하면 

좋을 것 같아서 음악을 실행파일에 포함해 보았지요.

 

안그래도 답답할텐데 

노이로제걸릴만한 음악이 자꾸 나오면

^___^

 

강한 멘탈을 심어주기 위한 저의 세심한 배려?라고

볼 수 있겠네요.

 

자 이제 시작해봅시다!!

 

 


visual studio 2017을 사용했구요.

.c형태의 C언어로 작성하였습니다.

 

먼저, 프로젝트를 만들고

리소스파일을 우클릭 합니다.

[그림1] 리소스파일

[그림1]과 같이

[리소스파일]을 우클릭 후 [추가] - [리소스] 를 누릅니다.

 

[그림2] 리소스추가

[그림2]를 보면 icon을 가져오기해서 추가할 수도 있습니다.

맨 아래에 "WAVE"라고 나오는 부분이 있는데

원래는 없어야 정상입니다.

[그림3]에 추가하는 방법이 나옵니다.

 

[그림3] .rc파일 수정

[그림3]과 같이 "[프로젝트명].rc"의 코드를 확인합니다.

 

[그림4] 추가내용

52라인에 보면 IDR_WAVE1 WAVE "music.wav"라고 적힌 부분이 있습니다.

 

IDR_WAVE1은 #define으로 추후 이 음악을 플레이 시 호출할 이름입니다.

WAVE는 WAVE형태의 리소스라는 의미입니다.

"music.wav"는 호출할 음악파일의 경로를 적어주면 됩니다.

 

위와 같이 설정한 경우에는 저 경로에 음악파일이 없다면?

음악이 나오지 않습니다.

 

음악은 wav파일만 가능한 것으로 알고 있습니다.

이 부분도 필요하다면 msdn을 참고하세요. 

 

...

 

그래서 파일 내부에 포함시키기 위해 

 

[그림5] 리소스뷰

[그림5]와 같이 IDR_WAVE1을 클릭하면

 

[그림6] 음악파일을 내부에 포함

[그림6]과 같이 오른쪽 아래에 편집기가 나옵니다.

 

여기서 External File 속성을 False로 설정해 줍니다.

그러면 음악이 외부에 존재하지 않고,

 

리소스영역에 음악이 그대로 저장됩니다.

단, 실행파일의 용량은 음악파일의 용량만큼

추가로 증가한다는 단점!!

 

이 후 [그림5]의 IDR_WAVE1을 더블클릭하면

 

[그림7] 음악첨부

[그림7]과 같이 음악이 첨부되어 있는 것을 확인할 수 있습니다.

 

 

다이얼로그박스도 리소스에서 추가로 생성하시면 됩니다.

 

참고 : https://ccurity.tistory.com/202

 

대화상자 생성

1. 대화상자 만들기 1) 대화상자 ▶ 메뉴리소스 생성한 방식과 유사하게 생성할 수 있다. ▶ 다양한 동작에 배치할 수 있다. (동작 시 대화상자 발생) 2) 동작방식 [1] 리소스에서 새로운 대화상자를 생성한다. [2..

ccurity.tistory.com

 

그 전에 링커가 링킹시에 음악재생에 필요한 라이브러리를 추가해줘야 합니다.

 

[그림8] 프로젝트 속성

 

[그림8]과 같이 누르고

 

[그림9] 라이브러리 추가

[그림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

 

Linux System Call

1. 이론 ▶ 먼저 아래 그림을 보려고 한다. (그림 그리기 힘들다 ㅠㅠ) ▶ 위로 갈수록 하이레벨이고 아래로 갈수로 로우레벨이다. (1) 이 그림으로 하고 싶은 말은 OS별로 제공되는 [Linux에서는 system call |..

ccurity.tistory.com

정적라이브러리에 대한 설명은

위 링크의 (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

 

위장 악성코드를 실행하는 방법

※ OS : Windows환경의 악성코드 1. 위장 악성코드 ▶ 악성코드 제작자는 악성코드를 은닉하기 위해 여러가지 방법을 개발한다. ▶ 즉, 탐지를 우회하기 위해 위장 실행 기법을 개발한다. 2. Launchers(실행기) (1..

ccurity.tistory.com

CALLBACK함수와 thread에 대한 내용은

위 링크의 6.을 보면 도움이 될지도 모르겠습니다.

 


여기까지 진행했으면

다이얼로그박스와 함께 음악이 나옵니다.

 

[그림10] wav 파일 포함

 

 

[그림11] 프로그램 실행

원래 목적이 리버싱문제를 내기 위한 것이라..

다이얼로그박스에 원하는 말이 들어오면 되겠죠?

파일을 분석하는 동안 음악은 계속 나온다니

 

노이로제 걸릴걸 생각하니 뿌듯하네요~

 

답은 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

댓글