ReverseEngineering – Telegram
ReverseEngineering
1.24K subscribers
40 photos
10 videos
55 files
666 links
Download Telegram
ساخت یک باینری نیتیو (Win32) شبیه‌ سازی‌ شده که مکانیزم‌ های واقعی حفاظت آنتی‌ دیباگ ساده چک یکپارچگی تولید سریال بر اساس اسم  داخل داشته باشه تا بدون ریسک قانونی بتونید تمرین RE و عملیات کرک‌ سازی رو انجام بدید

ویژگی‌ها:

GUI
ساده با فیلدهای Name و Serial و دکمه Activate & Play

Anti-Debug: فراخوانی
IsDebuggerPresent() قبل از فعال‌سازی

Integrity (شبیه‌سازی):
بررسی ساده مسیر exe قابل ارتقا به checksum واقعی

الگوریتم سریال: تابع gen_expected_serial که روی نام کاربر s = s*31 + ch انجام میده و بعد سه گروه 16‌بیتی با XOR/شیفت میسازه خروجی در قالب AAAA-BBBB-CCCC

پیام موفق/ناموفق با MessageBoxA.


هشدار اخلاقی/قانونی: این کد فقط برای تمرین روی باینری‌ ایه که خودتون ساختید کرک و انتشار کرک نرم‌ افزارهای تجاری غیرقانونیه


کد کامل فایل hotspot_sim.c

کد رو دقیقا در یک فایل به اسم hotspot_sim.c ذخیره کنید

// hotspot_sim.c
یک برنامه شبیه‌ سازی‌ شده برای تمرین RE

#include <windows.h>
#include <stdio.h>
#include <string.h>

// شناساگر کنترل‌ها
#define IDC_NAME  1001
#define IDC_SERIAL 1002
#define IDC_BUTTON 1003

// یه تابع ساده برای ساختن سریال مورد انتظار بر اساس اسم کاربر
// فرمت خروجی: AAAA-BBBB-CCCC (اعداد هگز چهار رقمی)
void gen_expected_serial(const char *name, char *out, size_t outlen)
{
    unsigned long s = 0;
    // جمع مقادیر کاراکترها رو می‌گیریم
    for (size_t i = 0; i < strlen(name); ++i) {
        s = s * 31 + (unsigned char)name[i]; // یه ضرب و جمع ساده
    }
    // میایم سه گروه 16 بیتی می‌سازیم
    unsigned g1 = (unsigned)((s ^ 0xA5A5A5A5) & 0xFFFF);
    unsigned g2 = (unsigned)(((s >> 3) ^ 0x5A5A5A5A) & 0xFFFF);
    unsigned g3 = (unsigned)(((s << 7) ^ 0x3C3C3C3C) & 0xFFFF);
    // قالب‌بندی نهایی
    _snprintf_s(out, outlen, _TRUNCATE, "%04X-%04X-%04X", g1, g2, g3);
}

// تابعی که سریال ورودی رو با سریال تولیدشده مقایسه می‌کنه
int verify_serial(const char *name, const char *serial)
{
    char expected[64];
    gen_expected_serial(name, expected, sizeof(expected));
    // اینجا مقایسهٔ ساده میکنیم (حساس به حروف)
    if (_stricmp(expected, serial) == 0) return 1;
    return 0;
}

// تابعی که integrity ساده رو شبیه‌سازی می‌کنه
// اینجا فقط چک می‌کنیم که exe path طول مشخصی داشته باشه (نمونه‌ست)
int integrity_ok()
{
    char path[MAX_PATH];
    if (GetModuleFileNameA(NULL, path, MAX_PATH) == 0) return 0;
    size_t L = strlen(path);
    // شبیه‌سازی: اگه طول مسیر خیلی کوتاه باشه یا خیلی بلند باشه خطا بدیم
    if (L < 5) return 0;
    return 1;
}

// پنجره اصلی و پردازش پیام‌ها
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
    {
        // یک لیبل و یک فیلد برای نام
        CreateWindowA("static", "Name:", WS_VISIBLE | WS_CHILD, 10, 10, 50, 20, hWnd, NULL, NULL, NULL);
        CreateWindowA("edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
                      70, 10, 240, 22, hWnd, (HMENU)IDC_NAME, NULL, NULL);

        // لیبل و فیلد سریال
        CreateWindowA("static", "Serial:", WS_VISIBLE | WS_CHILD, 10, 40, 50, 20, hWnd, NULL, NULL, NULL);
        CreateWindowA("edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
                      70, 40, 240, 22, hWnd, (HMENU)IDC_SERIAL, NULL, NULL);

        // دکمه Activate
        CreateWindowA("button", "Activate & Play", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                      110, 80, 120, 30, hWnd, (HMENU)IDC_BUTTON, NULL, NULL);
        break;
    }
    case WM_COMMAND:
    {
        if (LOWORD(wParam) == IDC_BUTTON)
        {
            // اگه دیباگر باشه لغو می‌کنیم
            if (IsDebuggerPresent()) {
                MessageBoxA(hWnd, "Activation failed: debugger detected.", "Error", MB_OK | MB_ICONERROR);
                break;
            }

            // integrity ساده
            if (!integrity_ok()) {
                MessageBoxA(hWnd, "Activation failed: integrity check failed.", "Error", MB_OK | MB_ICONERROR);
1
                break;
            }

// گرفتن متن از کنترل‌ ها
            char name[128] = {0};
            char serial[128] = {0};
            HWND hName = GetDlgItem(hWnd, IDC_NAME);
            HWND hSerial = GetDlgItem(hWnd, IDC_SERIAL);
            GetWindowTextA(hName, name, sizeof(name));
            GetWindowTextA(hSerial, serial, sizeof(serial));

            // پاک کردن فضای خالی ابتدای/انتهای رشته
            if (strlen(name) == 0) {
                MessageBoxA(hWnd, "Please enter your name first.", "Info", MB_OK | MB_ICONINFORMATION);
                break;
            }
            if (strlen(serial) == 0) {
                MessageBoxA(hWnd, "Please enter serial.", "Info", MB_OK | MB_ICONINFORMATION);
                break;
            }

            // بررسی سریال
            if (verify_serial(name, serial)) {
                MessageBoxA(hWnd, "Activation successful! Playing...", "OK", MB_OK | MB_ICONINFORMATION);
            } else {
                MessageBoxA(hWnd, "Invalid serial!", "Error", MB_OK | MB_ICONERROR);
            }
        }
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcA(hWnd, msg, wParam, lParam);
    }
    return 0;
}

// نقطهٔ ورود برنامه ویندوزی
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // ساخت کلاس پنجره
    WNDCLASSA wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = "HotspotSimClass";
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    if (!RegisterClassA(&wc)) return -1;

    // ساخت پنجره
    HWND hWnd = CreateWindowA("HotspotSimClass", "Hotspot Player (Simulated - Native)",
                              WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                              CW_USEDEFAULT, CW_USEDEFAULT, 340, 160, NULL, NULL, hInstance, NULL);
    if (!hWnd) return -1;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // لوپ پیام ساده
    MSG msg;
    while (GetMessageA(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessageA(&msg);
    }

    return (int)msg.wParam;
}



Build a simulated native (Win32) binary that has real anti-debug protection mechanisms, simple integrity check, serial generation based on the name inside, so you can practice RE and cracking operations without legal risk

Features:

Simple GUI
with Name and Serial fields and Activate & Play button

Anti-Debug: Call
IsDebuggerPresent() before activation

Integrity (simulation):
Simple check of exe path, upgradeable to real checksum

Serial algorithm: gen_expected_serial function that does s = s*31 + ch on the username and then creates three 16-bit groups with XOR/shift. Output in the format AAAA-BBBB-CCCC

Success/Failure message with MessageBoxA.

Ethical/Legal Warning: This code is for practice only on a binary that you have created yourself. Cracking and distributing commercial software is illegal

Full code of the hotspot_sim.c file

Save the code exactly in a file named hotspot_sim.c

// hotspot_sim.c
A simulated program for practicing RE
Simple and vernacular explanations and comments

#include <windows.h>
#include <stdio.h>
#include <string.h>

// Control identifiers
#define IDC_NAME 1001
#define IDC_SERIAL 1002
#define IDC_BUTTON 1003

// A simple function to generate the expected serial based on the user name
// Output format: AAAA-BBBB-CCCC (four-digit hex numbers)
void gen_expected_serial(const char *name, char *out, size_t outlen)
{
unsigned long s = 0;
// We take the sum of the character values
for (size_t i = 0; i < strlen(name); ++i) {
s = s * 31 + (unsigned char)name[i]; // A simple multiplication and addition
}
// Let's create three 16-bit groups
unsigned g1 = (unsigned)((s ^ 0xA5A5A5A5) & 0xFFFF);
unsigned g2 = (unsigned)(((s >> 3) ^ 0x5A5A5A5A) & 0xFFFF);
unsigned g3 = (unsigned)(((s << 7) ^ 0x3C3C3C3C) & 0xFFFF);
// Final formatting
_snprintf_s(out, outlen, _TRUNCATE, "%04X-%04X-%04X", g1, g2, g3);
}
1
// A function that compares the input serial with the generated serial
int verify_serial(const char *name, const char *serial)
{
char expected[64];
gen_expected_serial(name, expected, sizeof(expected));
// Here we do a simple comparison (case sensitive)
if (_stricmp(expected, serial) == 0) return 1;
return 0;
}

// A function that simulates simple integrity
// Here we just check that the exe path has a certain length (example)
int integrity_ok()
{
char path[MAX_PATH];
if (GetModuleFileNameA(NULL, path, MAX_PATH) == 0) return 0;
size_t L = strlen(path);
// Simulation: throw an error if the path length is too short or too long
if (L < 5) return 0;
return 1;
}

// Main window and message processing
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
// A label and a field for the name
CreateWindowA("static", "Name:", WS_VISIBLE | WS_CHILD, 10, 10, 50, 20, hWnd, NULL, NULL, NULL);
CreateWindowA("edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
70, 10, 240, 22, hWnd, (HMENU)IDC_NAME, NULL, NULL);

// Label and serial field
CreateWindowA("static", "Serial:", WS_VISIBLE | WS_CHILD, 10, 40, 50, 20, hWnd, NULL, NULL, NULL);
CreateWindowA("edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
70, 40, 240, 22, hWnd, (HMENU)IDC_SERIAL, NULL, NULL);

// Activate button
CreateWindowA("button", "Activate & Play", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
110, 80, 120, 30, hWnd, (HMENU)IDC_BUTTON, NULL, NULL);
break;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == IDC_BUTTON)
{
// Cancel if debugger
if (IsDebuggerPresent()) {
MessageBoxA(hWnd, "Activation failed: debugger detected.", "Error", MB_OK | MB_ICONERROR);
break;
}

// Simple integrity
if (!integrity_ok()) {
MessageBoxA(hWnd, "Activation failed: integrity check failed.", "Error", MB_OK | MB_ICONERROR);
break;
}

// Get text from controls
char name[128] = {0};
char serial[128] = {0};
HWND hName = GetDlgItem(hWnd, IDC_NAME);
HWND hSerial = GetDlgItem(hWnd, IDC_SERIAL);
GetWindowTextA(hName, name, sizeof(name));
GetWindowTextA(hSerial, serial, sizeof(serial));

// Remove leading/trailing whitespace
if (strlen(name) == 0) {
MessageBoxA(hWnd, "Please enter your name first.", "Info", MB_OK | MB_ICONINFORMATION);
break;
}
if (strlen(serial) == 0) {
MessageBoxA(hWnd, "Please enter serial.", "Info", MB_OK | MB_ICONINFORMATION);
break;
}

// Verify serial
if (verify_serial(name, serial)) {
MessageBoxA(hWnd, "Activation successful! Playing...", "OK", MB_OK | MB_ICONINFORMATION);
} else {
MessageBoxA(hWnd, "Invalid serial!", "Error", MB_OK | MB_ICONERROR);
}
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcA(hWnd, msg, wParam, lParam);
}
return 0;
}

// Windows application entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Create window class
WNDCLASSA wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = "HotspotSimClass";
     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
     wc.hCursor = LoadCursor(NULL, IDC_ARROW);

     if (!RegisterClassA(&wc)) return -1;

     // Create the window
     HWND hWnd = CreateWindowA("HotspotSimClass", "Hotspot Player (Simulated - Native)",
                               WS_OVERLAPPED |  WS_CAPTION |  WS_SYSMENU |  WS_MINIMIZEBOX,
                               CW_USEDEFAULT, CW_USEDEFAULT, 340, 160, NULL, NULL, hInstance, NULL);
     if (!hWnd) return -1;

     ShowWindow(hWnd, nCmdShow);
     UpdateWindow(hWnd);

     // Simple message loop
     msg msg;
     while (GetMessageA(&msg, NULL, 0, 0)) {
         translateMessage(&msg);
         DispatchMessageA(&msg);
     }

     return (int)msg.wParam;
}



@reverseengine
1
برنامه کمکی: تولید سریال فایل: gen_serial.c

برای راحتی کار و تمرین یک برنامه C ساده که همون الگوریتم رو اجرا میکنه و سریال برای یک اسم میسازه

// gen_serial.c
// برنامه ساده برای تولید سریال بر اساس اسم

#include <stdio.h>
#include <stdint.h>
#include <string.h>

// تولید سریال مثل gen_expected_serial در باینری
void gen_expected_serial(const char *name, char *out, size_t outlen)
{
uint64_t s = 0;
// s = s*31 + ch
for (size_t i = 0; i < strlen(name); ++i) {
unsigned char ch = (unsigned char)name[i];
s = s * 31 + ch;
}
unsigned g1 = (unsigned)((s ^ 0xA5A5A5A5ULL) & 0xFFFF);
unsigned g2 = (unsigned)(((s >> 3) ^ 0x5A5A5A5AULL) & 0xFFFF);
unsigned g3 = (unsigned)(((s << 7) ^ 0x3C3C3C3CULL) & 0xFFFF);

// فرمت AAAA-BBBB-CCCC (حروف بزرگ هگز)
snprintf(out, outlen, "%04X-%04X-%04X", g1, g2, g3);
}

int main(int argc, char **argv)
{
char name[256] = {0};
char serial[64] = {0};

if (argc >= 2) {
strncpy(name, argv[1], sizeof(name)-1);
} else {
printf("Enter name: ");
if (!fgets(name, sizeof(name), stdin)) return 1;
name[strcspn(name, "\r\n")] = 0;
}

if (strlen(name) == 0) {
fprintf(stderr, "Name is empty\n");
return 1;
}

gen_expected_serial(name, serial, sizeof(serial));
printf("Name: %s\nSerial: %s\n", name, serial);
return 0;
}



نحوه ساخت Build

با MinGW (در ویندوز):

برای hotspot_sim.c:

gcc hotspot_sim.c -o hotspot_sim.exe -mwindows


mwindows برای حذف پنجره کنسول و ساخت GUI

برای gen_serial.c:

gcc gen_serial.c -o gen_serial.exe



با MSVC (Developer Command Prompt):

hotspot_sim.c:

cl /EHsc hotspot_sim.c user32.lib gdi32.lib

gen_serial.c:

cl /EHsc gen_serial.c


چجوری تست و استفاده کنید

داخل VM ویندوزی حتما VM و snapshot برای فایل hotspot_sim.exe رو اجرا کنید


اسم دلخواه بزنید مثلا Ali حالا یا سریال رو با gen_serial.exe Ali بسازید و در فیلد Serial پیست کنید یا داخل دیباگر تابع تولید رو اجرا و مقدار expected را بخونید


اگر سریال درست باشه MessageBox موفقیت نمایش میده

راهنمای کوتاه آنالیز در x64dbg / IDA

جستجوی رشته‌ها
: "Name:", "Serial:", "%04X-%04X-%04X", "Activate & Play" → رفرنس‌ها معمولا توابع مهم رو نشون میدن

IsDebuggerPresent: breakpoint
روی IsDebuggerPresent یا آدرسی که اون رو صدا میزنه اگر 1 برگرده برنامه مسیر خطا رو میزنه

GetWindowTextA: breakpoint
بذارید تا مقدار name و serial رو داخل حافظه ببینید

ثابت‌ها: جستجوی ثابت‌های XOR (0xA5A5A5A5, 0x5A5A5A5A, 0x3C3C3C3C) یا قالب %04X-%04X-%04X شما رو به تابع تولید سریال میرسونه

مقایسه: breakpoint روی stricmp تا قبل از مقایسه دو بافر رو ببینید

MessageBoxA:
گذاشتن breakpoint اینجا سریع میگه کدوم شاخه اجرا شده موفق یا خطا




Auxiliary program: Serial generation File: gen_serial.c)

For convenience and practice, a simple C program that implements the same algorithm and creates a serial for a name

// gen_serial.c
// Simple program to generate serial based on name

#include <stdio.h>
#include <stdint.h>
#include <string.h>

// Generate serial like gen_expected_serial in binary
void gen_expected_serial(const char *name, char *out, size_t outlen)
{
uint64_t s = 0;
// s = s*31 + ch
for (size_t i = 0; i < strlen(name); ++i) {
unsigned char ch = (unsigned char)name[i];
s = s * 31 + ch;
}
unsigned g1 = (unsigned)((s ^ 0xA5A5A5A5ULL) & 0xFFFF);
unsigned g2 = (unsigned)(((s >> 3) ^ 0x5A5A5A5AULL) & 0xFFFF);
unsigned g3 = (unsigned)(((s << 7) ^ 0x3C3C3C3CULL) & 0xFFFF);

// format AAAA-BBBB-CCCC (hex uppercase letters)
snprintf(out, outlen, "%04X-%04X-%04X", g1, g2, g3);
}

int main(int argc, char **argv)
{
char name[256] = {0};
char serial[64] = {0};

if (argc >= 2) {
strncpy(name, argv[1], sizeof(name)-1);
} else {
printf("Enter name: ");
if (!fgets(name, sizeof(name), stdin)) return 1;
name[strcspn(name, "\r\n")] = 0;
}

if (strlen(name) == 0) {
fprintf(stderr, "Name is empty\n");
return 1;
}

gen_expected_serial(name, serial, sizeof(serial));
printf("Name: %s\nSerial: %s\n", name, serial);
return 0;
}
1
How to Build

With MinGW (on Windows):

For hotspot_sim.c:

gcc hotspot_sim.c -o hotspot_sim.exe -mwindows


mwindows to remove the console window and build the GUI

For gen_serial.c:

gcc gen_serial.c -o gen_serial.exe


With MSVC (Developer Command Prompt):

hotspot_sim.c:

cl /EHsc hotspot_sim.c user32.lib gdi32.lib

gen_serial.c:

cl /EHsc gen_serial.c

How to test and use

Inside a Windows VM, be sure to run the VM and snapshot for the hotspot_sim.exe file

Give it a name of your choice, for example Ali. Now either create the serial with gen_serial.exe Ali and paste it in the Serial field, or run the generation function inside the debugger and read the expected value

If the serial is correct, the MessageBox will display success

A short guide to analyzing in x64dbg / IDA

Search Strings
: "Name:", "Serial:", "%04X-%04X-%04X", "Activate & Play" → References usually indicate important functions

IsDebuggerPresent: breakpoint
On IsDebuggerPresent or the address that calls it, if it returns 1, the program will hit the error path

GetWindowTextA: breakpoint
Put it to see the value of name and serial in memory

Constants: Search for XOR constants (0xA5A5A5A5, 0x5A5A5A5A, 0x3C3C3C3C) or the pattern %04X-%04X-%04X will take you to the serial generation function

Comparison: breakpoint on stricmp to see the two buffers before comparing

MessageBoxA:
Putting a breakpoint here will quickly tell you which branch was executed successfully or failed

@reverseengine
1
تحلیل استفاده از ابزارهای RMM برا بایپس EDR در حملات گروه های باج افزاری Medusa و DragonForce

Analysis of the use of RMM tools to bypass EDR in Medusa and DragonForce ransomware attacks


https://zensec.co.uk/blog/how-rmm-abuse-fuelled-medusa-dragonforce-attacks

@FUZZ0x
1