1. Basic Structure of a C++ Program

A handle on programming is likely to increase your effectiveness in Malware Analysis. This section is a reference sheet for key concepts and syntax particularly for C++.

Every C++ program starts with the main() function, which serves as the entry point. Before that, the #include directive is used to import standard or system libraries.

A minimal example:

#include <iostream>

int main() {
    std::cout << "Hello, offensive world!" << std::endl;
    return 0;
}

2. Input and Output (I/O)

C++ handles console input using std::cin and output using std::cout, both part of the standard namespace (std). These are essential for basic interaction and debugging during development.

int age;
std::cout << "Enter your age: ";
std::cin >> age;

3. Variables and Data Types

C++ is strongly typed. All variables must have a declared type:

int number = 42;
float pi = 3.14f;
char initial = 'A';
bool isActive = true;

Variables are stored in memory either on the stack (local/static) or the heap (dynamic).


4. Control Flow

Used to make decisions and repeat operations.

4.1 Conditionals

if (x > 0) {
    // ...
} else if (x == 0) {
    // ...
} else {
    // ...
}

4.2 Loops

for (int i = 0; i < 5; i++) { ... }
while (condition) { ... }
do { ... } while (condition);

4.3 Switch Case

switch (value) {
    case 1: break;
    case 2: break;
    default: break;
}

5. Functions

Functions are used to modularize code.

int add(int a, int b) {
    return a + b;
}

void sub(int a, int b){
	cout << a - b;
}

6. Pointers and References

Pointers store memory addresses. They are critical in shellcode injection, memory manipulation, and API interaction.

int x = 10;
int* ptr = &x;

References act as aliases to existing variables:

void modify(int& ref) {
    ref = 99;
}

7. Type Casting

// modern cpp style typecasting
int intval = 48
char charval = static_cast<char>(intval);
// convert
unsigned char byte = static_cast<unsigned char>(std::stoul("FF", nullptr, 16));

8. Dynamic Memory Allocation

Memory can be allocated and freed manually:

int* p = new int(100);
delete p;

This allows heap-based memory control, often used in memory-resident malware.


9. Arrays and C-style Strings

Arrays are fixed-size containers:

int arr[3] = {1, 2, 3};

Byte array requires the use of unsigned char

unsigned char bytearray[1024] = {0xFF,0xFF}

C-style strings are null-terminated character arrays:

char msg[] = "hello";

Use secure functions like strcpy_s over strcpy to prevent buffer overflows.


10. Structs, Enums, and Type Aliases

10.1 Structs

Structs group related data:

struct Point {
    int x;
    int y;
};
// instantiate
struct Point p;
p.x = 10;
p.y = 20;

// you can also use the following mthod
struct {  
  string brand;  
  string model;  
  int year;  
} myCar1, myCar2;

myCar1.brand = "bla";
myCar1.year = 2025;
...

10.2 Enum

Enums improve readability:

enum Status { OK, FAIL };

10.3 Typedef Datatype Declaration

Datatype declaration with Typedef :

typedef unsigned int uint;
using byte = unsigned char;

Typedef with Structs:

typedef struct {
	string x;
	string y;
	int z;
} myStruct;

myStruct obj1;

obj1.x = "hello";
obj1.y = "world";
obj1.z = 2025;

11. Object-Oriented Programming (OOP)

C++ is fully object-oriented:

class Malware {
private:
    std::string payload;
public:
    Malware(std::string p) : payload(p) {}
    void execute() { /* ... */ }
};

Includes encapsulation, inheritance, polymorphism, constructors and destructors.


12. Namespaces and std::

Namespaces organize code and avoid conflicts. Use std:: to access standard components.

std::cout << "Hello";

using namespace std;

It is advised to avoid using namespace std; in large projects.


13. Smart Pointers

Smart pointers automate memory management:

#include <memory>

std::unique_ptr<int> uptr(new int(10));
std::shared_ptr<int> sptr = std::make_shared<int>(20);

They help prevent memory leaks and dangling pointers.


14. Templates

Templates allow generic programming. It is used to help reduce duplication in your code. For instance, rather than having multiple functions that do the same thing for different input types you can have one function that dynamically understands the input types during the compile using Template function.

template<typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

They are widely used in the Standard Template Library (STL).


15. Lambda Expressions

Lambdas are anonymous functions, useful for callbacks or threading:

auto square = [](int x) { return x * x; };

// with ternary operator
// <condition>?<if true>:<if false>
auto test = [](int x, int y){return x>y?x:y;};
std::cout << test(1,2);

16. Move Semantics (std::move)

Move semantics enable resource transfer without copying:

std::string a = "data";
std::string b = std::move(a);

Used to optimize performance for large objects or buffers.


17. Exception Handling

C++ uses try-catch blocks:

try {
    throw std::runtime_error("Error");
} catch (const std::exception& e) {
    std::cout << e.what();
}

Used for robust error control and safe failure handling.


18. RAII (Resource Acquisition Is Initialization)

RAII ensures that resources are tied to object lifetimes. When objects go out of scope, destructors automatically release memory, file handles, locks, etc.

std::ofstream file("log.txt"); // Automatically closed at end of scope

19. Standard Template Library (STL)

The STL provides high-performance data structures and algorithms:

  • Containers: vectormapsetqueue
  • Algorithms: sort()find()count()
  • Iterators: pointer-like objects to navigate containers
#include <vector>
...
std::vector<int> nums = {1, 2, 3};
std::sort(nums.begin(), nums.end());

byte array style Vector

std::vector<unsigned char> bytescod = {0xFF, 0xFF};

20. Optimizations

https://learn.microsoft.com/en-us/cpp/preprocessor/optimize?view=msvc-170
Remove optimization for specific code sections/functions:

// above the procedure use the following lineL

#pragma optimize( "", off )

Turn optimization back on:

#pragma optimize( "", on )

21. Windows DataTypes

21.1 Windows Handle and Identifier Types

Datatype Original Definition Usage Example
HANDLE void* (opaque pointer) Generic handle to an object, e.g. HANDLE hFile = CreateFile(...);
HWND struct HWND__* (pointer to a window struct) Represents a window handle, e.g. HWND hwnd = GetForegroundWindow();
HINSTANCE struct HINSTANCE__* (pointer to a window struct) Module handle, often passed to WinMain as HINSTANCE hInstance
HMODULE struct HMODULE__* (pointer to a window struct) Handle to a loaded DLL, e.g. HMODULE hMod = LoadLibrary("user32.dll");
FARPROC int (__stdcall * )() Generic pointer to a function, e.g. FARPROC pFunc = GetProcAddress(hMod, "MessageBoxA");
WPARAM UINT_PTR (unsigned integer type) Message parameter, e.g. used in LRESULT CALLBACK WndProc(..., WPARAM wParam, ...)
LPARAM LONG_PTR (signed integer type) Message parameter, e.g. LPARAM lParam in WndProc
LRESULT LONG_PTR Return value of WndProc, e.g. return DefWindowProc(hwnd, msg, wParam, lParam);
BOOL int TRUE (1) or FALSE (0) e.g. BOOL result = IsWindow(hwnd);

21.2 Windows String Types

Datatype Original Definition Usage Example
LPCSTR const char* ANSI string, e.g. LPCSTR myStr = "me ow";
LPSTR char* Mutable ANSI string buffer, e.g. LPSTR buf = new char[100];
LPCWSTR const wchar_t* Wide-character (Unicode) string, e.g. LPCWSTR wstr = L"me ow";
LPWSTR wchar_t* Mutable wide string, e.g. LPWSTR buf = new wchar_t[100];
TCHAR wchar_t (Unicode) or char (ANSI) Generic text type depending on UNICODE macro, e.g. TCHAR buf[100];
LPTSTR TCHAR* Generic mutable string, Unicode if UNICODE is defined
LPCTSTR const TCHAR* Generic const string, Unicode if UNICODE is defined

21.3 Windows Pointer Types

Datatype Original Definition Usage Example
LPBYTE BYTE* pointer to raw bytes, e.g. LPBYTE pByte = new BYTE[16]; memcpy(pByte, data, size);
LPCVOID const void* pointer to read-only memory e.g. LPCVOID data = L"hello world\n";
LPVOID void* generic pointer e.g. LPVOID ptr = VirtualAlloc(NULL, 64, MEM_COMMIT, PAGE_READWRITE);

22. Basic Windows API Function

Example using MessageBox

#include <windows.h>

int main() {
	LPCWSTR lpText = L"me ow";
	LPCWSTR lpCaption = L"4dm";
    MessageBoxW(NULL, lpText, lpCaption, MB_OK);
    return 0;
}

Typical data types and functions used:

  • HANDLEDWORDLPVOID
  • VirtualAllocCreateRemoteThreadWriteProcessMemoryLoadLibrary

Understanding structs, memory models, and calling conventions is key to building reliable and stealthy tools.