Generic Music Player
I saw @Shadow` 's hack and saw that it had the ability to be able to play music. The only downside was that it only worked with WAV files and had to be in a specific folder so I decided to tackle this problem myself and write a small class for it. With this class, you will be able to play MP3 files and other formats supported by the computer as long as you have the codecs available for it. I've also tested it with FLAC and WAV, they work fine. This class is mainly powered by the MCI API from Microsoft. You can enter in relative/partial paths, like "Music" and it will find all files in the "Music" folder next to the injected DLL. You can also put in absolute paths like "C:\Music Stuff" and it will search that directory.
Also if you noticed that I used, TCHAR, LPTSTR and _T alot, well that's because I wanted to add support for both ANSI and Unicode depeding on the Character Set that's been used on the current project. Also note that the class is static, meaning you can only have 1 instance of it in every application or DLL.
I should also mention that SetVolume uses a value between 0 and 1000, eg. 0 = 0% and 1000 = 100%. The same thing applies to the Volume variable which tells the current volume level. GetCurrentPosition and SetCurrentPosition use millisecond values for their positions.
player.h
player.cpp
Here's a little "Demo DLL" source that you can try out to test some of the class' features.
I've attached the built Demo DLL which you can inject into any process and mess around with.
Virus Scans:
https://www.virustotal.com/file/b467...is/1348830741/
BasicMusicPlayerDemo.rar - Jotti's malware scan
Also if you noticed that I used, TCHAR, LPTSTR and _T alot, well that's because I wanted to add support for both ANSI and Unicode depeding on the Character Set that's been used on the current project. Also note that the class is static, meaning you can only have 1 instance of it in every application or DLL.
I should also mention that SetVolume uses a value between 0 and 1000, eg. 0 = 0% and 1000 = 100%. The same thing applies to the Volume variable which tells the current volume level. GetCurrentPosition and SetCurrentPosition use millisecond values for their positions.
player.h
Code:
#include <Windows.h>
#include <Shlwapi.h>
#include <vector>
#include <tchar.h>
#pragma comment(lib, "Winmm.lib")
#pragma comment(lib, "Shlwapi.lib")
struct MusicPlayerEntry
{
LPTSTR SongName;
LPTSTR Path;
};
class MusicPlayer
{
public:
static std::vector<MusicPlayerEntry*> Entries;
static void PopulateMusic(LPTSTR directory, LPTSTR extension);
static void Cleanup();
static bool IsPlaying();
static bool IsPaused();
static void PlayMusic(MusicPlayerEntry* entry);
static void PauseMusic();
static void ResumeMusic();
static void StopMusic();
static void SetVolume(int value);
static int GetCurrentPosition();
static void SetCurrentPosition(int position);
static void FormatMilliseconds(int milliseconds, LPTSTR output, size_t bufferSize);
static int LengthMilliseconds, Volume;
private:
static bool AliasDefined;
static void AddEntry(LPTSTR filePath, LPTSTR songName);
static HMODULE GetCurrentModuleHandle();
static BOOL DirectoryExists(LPTSTR directory);
};
Code:
#include "player.h"
std::vector<MusicPlayerEntry*> MusicPlayer::Entries;
int MusicPlayer::LengthMilliseconds = 0;
int MusicPlayer::Volume = 1000;
bool MusicPlayer::AliasDefined = false;
void MusicPlayer::PopulateMusic(LPTSTR directory, LPTSTR extension)
{
if(PathIsRelative(directory))
{
TCHAR buffer[MAX_PATH];
GetModuleFileName(GetCurrentModuleHandle(), buffer, MAX_PATH);
PathRemoveFileSpec(buffer);
PathCombine(buffer, buffer, directory);
directory = buffer;
}
if(!DirectoryExists(directory))
return;
TCHAR wildcardPath[MAX_PATH];
PathCombine(wildcardPath, directory, _T("*"));
WIN32_FIND_DATA findData;
HANDLE findHandle = FindFirstFile(wildcardPath, &findData);
do
{
LPTSTR currentExtension = PathFindExtension(findData.cFileName);
if(!lstrcmp(currentExtension, extension))
{
LPTSTR path = new TCHAR[MAX_PATH];
PathCombine(path, directory, findData.cFileName);
LPTSTR songName = new TCHAR[MAX_PATH];
lstrcpy(songName, findData.cFileName);
PathStripPath(songName);
PathRemoveExtension(songName);
AddEntry(path, songName);
}
} while (FindNextFile(findHandle, &findData) != 0);
}
void MusicPlayer::Cleanup()
{
StopMusic();
for(unsigned int i = 0; i < Entries.size(); i++)
{
delete Entries[i]->SongName;
delete Entries[i]->Path;
}
Entries.clear();
}
HMODULE MusicPlayer::GetCurrentModuleHandle()
{
static int var = 0;
MEMORY_BASIC_INFORMATION mbi;
if(!VirtualQuery(&var, &mbi, sizeof(mbi)))
return NULL;
return static_cast<HMODULE>(mbi.AllocationBase);
}
void MusicPlayer::FormatMilliseconds(int milliseconds, LPTSTR output, size_t bufferSize)
{
_stprintf_s(output, bufferSize, _T("%d:%02d"), milliseconds / 1000 / 60, milliseconds / 1000 % 60);
}
bool MusicPlayer::IsPlaying()
{
TCHAR buffer[20];
mciSendString(_T("status currentSong mode"), buffer, 20, NULL);
return !lstrcmp(buffer, _T("playing"));
}
bool MusicPlayer::IsPaused()
{
TCHAR buffer[20];
mciSendString(_T("status currentSong mode"), buffer, 20, NULL);
return !lstrcmp(buffer, _T("paused"));
}
void MusicPlayer::PlayMusic(MusicPlayerEntry* entry)
{
StopMusic();
TCHAR buffer[MAX_PATH + 40];
_stprintf_s(buffer, _T("open \"%s\" type mpegvideo alias currentSong"), entry->Path);
mciSendString(buffer, NULL, 0, NULL);
mciSendString(_T("play currentSong"), NULL, 0, NULL);
TCHAR length[128];
mciSendString(_T("status currentSong length"), length, 128, NULL);
LengthMilliseconds = _ttoi(length);
AliasDefined = true;
}
void MusicPlayer::PauseMusic()
{
if(IsPlaying())
mciSendString(_T("pause currentSong"), NULL, 0, NULL);
}
void MusicPlayer::ResumeMusic()
{
if(IsPaused())
mciSendString(_T("resume currentSong"), NULL, 0, NULL);
}
void MusicPlayer::StopMusic()
{
if(AliasDefined)
mciSendString(_T("close currentSong"), NULL, 0, NULL);
}
int MusicPlayer::GetCurrentPosition()
{
if(IsPlaying())
{
TCHAR length[128];
mciSendString(_T("status currentSong position"), length, 128, NULL);
return _ttoi(length);
}
return 0;
}
void MusicPlayer::SetCurrentPosition(int position)
{
if(IsPlaying())
{
TCHAR buffer[60];
_stprintf_s(buffer, _T("play currentSong from %d"), position);
mciSendString(buffer, NULL, 0, NULL);
}
}
void MusicPlayer::SetVolume(int value)
{
if(IsPlaying() && value >= 0 && value <= 1000)
{
TCHAR buffer[40];
_stprintf_s(buffer, _T("setaudio currentSong volume to %i"), value);
mciSendString(buffer, NULL, 0, NULL);
Volume = value;
}
}
BOOL MusicPlayer::DirectoryExists(LPTSTR dirName)
{
DWORD attribs = GetFileAttributes(dirName);
if (attribs == INVALID_FILE_ATTRIBUTES)
return false;
return (attribs & FILE_ATTRIBUTE_DIRECTORY);
}
void MusicPlayer::AddEntry(LPTSTR filePath, LPTSTR songName)
{
MusicPlayerEntry* entry = new MusicPlayerEntry();
entry->SongName = songName;
entry->Path = filePath;
Entries.push_back(entry);
}
Code:
#include <Windows.h>
#include "player.h"
DWORD WINAPI Main(LPVOID)
{
unsigned int currentEntryIndex = 0;
// Find all .mp3 files inside the Music folder next to the DLL.
MusicPlayer::PopulateMusic(_T("Music"), _T(".mp3"));
// Check if there were any .mp3 files found.
if(!MusicPlayer::Entries.size()) return 0;
while(true)
{
// If no song is playing, play one.
if(!MusicPlayer::IsPlaying())
{
// Check that we've played all songs.
if(currentEntryIndex < MusicPlayer::Entries.size())
{
// Play the next song available.
MusicPlayerEntry* entry = MusicPlayer::Entries[currentEntryIndex++];
MusicPlayer::PlayMusic(entry);
// Display song information.
TCHAR buffer[255];
TCHAR formattedTime[20];
// Convert the milliseconds to minutes and seconds.
MusicPlayer::FormatMilliseconds(MusicPlayer::LengthMilliseconds, formattedTime, 20);
_stprintf_s(buffer, _T("Current song is: %s\nLength: %s"), entry->SongName, formattedTime);
MessageBox(NULL, buffer, _T("Information"), MB_OK);
}
else
{
// Exit.
MessageBox(NULL, _T("All songs have been played!"), _T("Done"), MB_OK);
break;
}
}
Sleep(1000);
}
return 0;
}
BOOL APIENTRY DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDll);
CreateThread(NULL, NULL, Main, NULL, NULL, NULL);
break;
case DLL_PROCESS_DETACH:
// Cleanup stuff here, only do it when the player is no longer needed.
MusicPlayer::Cleanup();
}
return TRUE;
}
Virus Scans:
https://www.virustotal.com/file/b467...is/1348830741/
BasicMusicPlayerDemo.rar - Jotti's malware scan




It's not even a control. I'm well aware of the BASS library, I've used it in a .NET application to play XM files. Anyway, adding alot of extra DLLs just to play music is going to be a hassle for people if it's used in a hack.