红色警戒1006的注入

#include <iostream>
#include <Windows.h>
#include <cstdint>
#include <stdio.h>
#include <wchar.h>

#define JMP_REAL(addr) __asm { __asm jmp _DWORD PTR [addr##_ ] }
#define NewCountryValue  100 
#define JUMPOUT(address) __asm { jmp address }
#define EXPORT extern "C" __declspec(dllexport)
typedef unsigned int _BYTE;
typedef unsigned int _DWORD;
typedef unsigned int _QWORD;
typedef unsigned int _WORD;
// 目标注入地址(原始函数入口点)
constexpr uintptr_t TARGET_ADDR = 0x004E4AA2;
constexpr uintptr_t TARGET_ADDR2 = 0x0053649F;
constexpr uintptr_t TARGET_ADDR3 = 0x005367A7;
constexpr uintptr_t TARGET_ADDR4 = 0x00536A62;
constexpr uintptr_t TARGET_ADDR5 = 0x00536B6A;

// 跳转代码模板: E9 [4字节相对偏移]
uint8_t jmpCode[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
uint8_t jmpCode2[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };

// 原始代码备份地址
const int HOOK_LEN = 5;

void* trampolineAddr = nullptr;
void* trampolineAddr2 = nullptr;
void* trampolineAddr3 = nullptr;
void* trampolineAddr4 = nullptr;
void* trampolineAddr5 = nullptr;

const uintptr_t loc_4E4B72 = 0x004E4B72;
const uintptr_t loc_4E4B64 = 0x004E4B64;
const uintptr_t loc_5364C0 = 0x005364C0;
const uintptr_t loc_536A83 = 0x00536A38;
const uintptr_t loc_5367C6 = 0x005367C6;
const uintptr_t loc_4314D3 = 0x004314D3;
const uintptr_t loc_536B73 = 0x00536B73;
const uintptr_t loc_65F406 = 0x0065F406;
const uintptr_t loc_50C9E9 = 0x0050C9E9;
const uintptr_t loc_50CA05 = 0x0050CA05;
const uintptr_t loc_51725C = 0x0051725C;

uintptr_t DWORD_839848 = 0x00839848;
char byte_A3D2C2 = 0x00A3D2C2;

// 函数类型定义
typedef int(__thiscall* Sub4F94D0Func)(void*);
typedef int(__thiscall* Sub491D10Func)(DWORD* This, int a2);
typedef void(*FunctionType)();

// 函数指针初始化
Sub4F94D0Func sub_4F94D0 = (Sub4F94D0Func)0x4F94D0;
Sub491D10Func sub_491D10 = (Sub491D10Func)0x491D10;

typedef int(__stdcall* OriginalSub6437F0)(int);
OriginalSub6437F0 originalSub6437F0 = (OriginalSub6437F0)0x006439ED;

const uintptr_t loc_6439FC = 0x006439FC;
typedef int(__thiscall* Sub4F94D0Func)(void*);
typedef int(__thiscall* Sub491D10Func)(DWORD* This, int a2);
typedef int(__thiscall* Sub50CB00Func)(char* This, const char* a2);
typedef unsigned int(__thiscall* Sub50E9A0Func)(char* This, int a2, int a3, int a4, char* a5, size_t a6);
typedef int(__thiscall* Sub50CE00Func)(char* This, const char* a2, int a3);
typedef int(__thiscall* Sub45E0E0Func)(char* This);
typedef int(__thiscall* Sub70B540Func)(char* This);
typedef wchar_t(__fastcall* Sub6F9EC0Func)(void *a1, DWORD *a2, int a3, int a4);
typedef int(* _sprintf)(char *a1, const char *a2, ...);
typedef int(__stdcall* Sub536D30Func)(int *a1, unsigned __int16 a2, int a3);
typedef int(__stdcall* Sub46ACB0Func)(int a1, int a2, int a3);
typedef int(__cdecl* Sub6437F0Func)(int);
typedef int(__thiscall* Sub493FC0Func)(unsigned int *This, unsigned __int8 *a2, int a3);

// 函数指针初始化
Sub45E0E0Func sub_45E0E0 = (Sub45E0E0Func)0x45E0E0;
Sub70B540Func sub_70B540 = (Sub70B540Func)0x70B540;
Sub50CB00Func sub_50CB00 = (Sub50CB00Func)0x50CB00;
Sub50CE00Func sub_50CE00 = (Sub50CE00Func)0x50CE00;
Sub50E9A0Func sub_50E9A0 = (Sub50E9A0Func)0x50E9A0;
Sub6F9EC0Func sub_6F9EC0 = (Sub6F9EC0Func)0x6F9EC0;
Sub536D30Func sub_536D30 = (Sub536D30Func)0x536D30;
Sub46ACB0Func sub_46ACB0 = (Sub46ACB0Func)0x46ACB0;
Sub6437F0Func sub_6437F0 = (Sub6437F0Func)0x6437F0;
Sub493FC0Func sub_493FC0 = (Sub493FC0Func)0x493FC0;

_sprintf sub_7820F4 = (_sprintf)0x7820F4;

uintptr_t byte_82EE88 = 0x0082EE88; // idb
uintptr_t off_7A906C = 0x007A906C;
uintptr_t off_7A907C = 0x007A907C;
uintptr_t nWidth = 0x008523E0;
uintptr_t nHeight = 0x008523E4;
uintptr_t off_79AF8C = 0x0079AF8C;
uintptr_t off_79AEF8 = 0x0079AEF8;
uintptr_t word_AB6842 = 0x00AB6842;

// 检查内存读写权限
bool IsValidPointer(uintptr_t address) {
    MEMORY_BASIC_INFORMATION mbi;
    if (VirtualQuery((LPCVOID)address, &mbi, sizeof(mbi))) {
        return (mbi.State == MEM_COMMIT &&
            (mbi.Protect & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE | PAGE_READONLY)) != 0);
    }
    return false;
}

// 生成跳转指令
void GenerateJump(uintptr_t from, uintptr_t to) {
    if (!IsValidPointer(from) || !IsValidPointer(to)) {
        std::cerr << "Invalid memory address for jump!" << std::endl;
        return;
    }

    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)from, 5, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed during jump generation! Error: " << GetLastError() << std::endl;
        return;
    }

    *(BYTE*)from = 0xE9;
    *(DWORD*)(from + 1) = to - from - 5;
    VirtualProtect((LPVOID)from, 5, oldProtect, &oldProtect);
}

__declspec(naked) char HookFunction() {
    __asm {
        // 保存寄存器状态
        pushad
        pushfd
        lea     ebp, [esi + 5430h]
        mov     ebx, [ecx + 9D4h]
        mov     ecx, ebp
        mov     edx, [ebx]
        mov     eax, [edx + 0xB90]
        push    eax
        call    sub_491D10

        mov     ecx, [ebx + 4]
        mov     edi, eax
        mov     edx, [ecx + 0xB90]
        mov     ecx, ebp
        push    edx
        call    sub_491D10
        // 调试输出: 再次调用 sub_491D10 后

        add     edi, eax
        mov     eax, [esi + 230h]
        test    eax, eax
        jnz     loc_return_4E4B72

        test    edi, edi
        jg      loc_return_4E4B72
        // 调试输出: 测试 edi 后
        // 新增逻辑: 判断是否为新建基地车
        mov     ecx, DWORD_839848
        mov     ebx, [ecx + 9D0h]
        mov     ecx, [ebx + 10h]
        xor eax, eax
        test    ecx, ecx
        jle     short loc_799624
        mov     edi, 0
        mov     ebx, edi

        loc_799612 :
        mov     ebp, ebx
            test    ebp, edx
            jnz     short loc_799645
            inc     eax
            add     ebx, 0xD
            cmp     eax, ecx
            jl      short loc_799612
            loc_799624 :
        xor     eax, eax

            loc_799626 :
        mov     edx, 0x39
            lea     ecx, [esi + 5430h]
            push    edx
            call    sub_491D10
            test    eax, eax
            jnz     loc_return_4E4B72
            jmp     loc_return_4E4B64

            loc_799645 :
        mov     eax, 2
            jmp     short loc_799626

            // === 恢复寄存器和返回业务 ===

            loc_return_4E4B72 :
        popfd
            popad
            jmp loc_4E4B72

            loc_return_4E4B64 :
        popfd
            popad
            jmp loc_4E4B64
    }
}

__declspec(dllexport)char aDRa2LdprgmgrCp[20] = "D:\\Ra2\\LdPrgMgr.cpp"; // 假设存储有效地址

__declspec(dllexport)wchar_t aLoadbriefRussi[] = L"潌摡牂敩㩦畒獳慩"; // idbconst wchar_t* aNameTtnk = L"Name:Ttnk";
__declspec(dllexport)char aNameChina[11] = "Name:China"; // idb
__declspec(dllexport)char aLoadbriefChina[16] = "LoadBrief:China"; // idb
__declspec(dllexport)char aNameHowi[10] = "Name:HOWI"; // idb
__declspec(dllexport)wchar_t aNameTtnk[] = L"慎敭吺乔K"; // idb
__declspec(dllexport)wchar_t aNameRussians[] = L"慎敭刺獵楳湡s"; // idb

__declspec(naked) void sub_799910(unsigned int a1 )
{
    _asm {
        cmp     ebp, 8
        jnz     short loc_79992E
        push    0B7h
        push    offset aDRa2LdprgmgrCp
        xor     edx, edx
        mov     ecx, offset aNameRussians
        call    sub_6F9EC0
        mov     ebp, eax
        ret

        loc_79992E :

        cmp     ebp, 63h
        ja      short loc_799960
        push    0CBh
        push    offset aDRa2LdprgmgrCp; "D:\\Ra2\\LdPrgMgr.cpp"
        push    ebp
        push    offset aNameChina; "Name:China"
        mov     edx, offset byte_82EE88
        push    edx
        call    sub_7820F4
        add     esp, 0Ch
        sub     edx, eax
        inc     edx
        mov     ecx, edx
        xor     edx, edx
        call    sub_6F9EC0
        mov     ebp, eax
        ret

        loc_799960 : ; CODE XREF : sub_799910 + 21↑j
        xor     ebp, ebp
        ret
    }
}

__declspec(naked) int sub_7999D0(unsigned int a1)
{
    _asm {
        cmp     eax, 8
        jnz     short loc_7999EE
        push    0F5h; int
        push    offset aDRa2LdprgmgrCp; "D:\\Ra2\\LdPrgMgr.cpp"
        xor     edx, edx
        mov     ecx, offset aNameTtnk; "Name:TTNK"
        call    sub_6F9EC0
        ret

        loc_7999EE : ; CODE XREF : sub_7999D0 + 3↑j
        cmp     eax, 63h; 'c'
        jg      short loc_799A1E
        push    10Fh; int
        push    offset aDRa2LdprgmgrCp; "D:\\Ra2\\LdPrgMgr.cpp"
        push    eax
        push    offset aNameHowi; "NameHOWI"
        mov     edx, offset byte_82EE88
        push    edx; Buffer
        call    sub_7820F4
        add     esp, 0Ch
        sub     edx, eax
        inc     edx
        mov     ecx, edx; Format
        xor     edx, edx
        call    sub_6F9EC0
        ret

        loc_799A1E : ; CODE XREF : sub_7999D0 + 21↑j
        xor     eax, eax
        ret
    }

}

__declspec(naked) int sub_799970(unsigned int result)
{
    _asm {
        cmp     eax, 8
        jnz     short loc_79998E
         push    126h; int
        push    offset aDRa2LdprgmgrCp; "D:\\Ra2\\LdPrgMgr.cpp"
        xor     edx, edx
        mov     ecx, offset aLoadbriefRussi; "LoadBrief:Russia"
        call    sub_6F9EC0
        mov     edi, eax
        ret

        loc_79998E : ; CODE XREF : sub_799970 + 3↑j
        cmp     eax, 63h; 'c'
        jg      short loc_7999C0
        push    128h; int
        push    offset aDRa2LdprgmgrCp; "D:\\Ra2\\LdPrgMgr.cpp"
        push    eax
        push    offset aLoadbriefChina; "LoadBrief:China"
        mov     edx, offset byte_82EE88
        push    edx; Buffer
        call    sub_7820F4
        add     esp, 0Ch
        sub     edx, eax
        inc     edx
        mov     ecx, edx; Format
        xor     edx, edx
        call    sub_6F9EC0
        mov     edi, eax
        ret

        loc_7999C0 : ; CODE XREF : sub_799970 + 21↑j
        xor     edi, edi
        ret
    }
}

extern "C" __declspec(naked) char loc_53649F() {
    _asm {
        call    sub_799910
        jmp     loc_5364C0
    }
}

extern "C" __declspec(naked) char loc_5367A7() {
    _asm {
        call    sub_7999D0
        jmp     loc_5367C6
    }
}

extern "C" __declspec(naked) char loc_536A62() {
    _asm {
        call    sub_799970
        jmp     loc_536A83
    }
}

extern "C" __declspec(naked) char HookFunction5() {
    _asm {
         // 保存所有通用寄存器

        call    sub_536D30
        cmp     ebx, 0x7C42
        jz      loc_536B70        // 保存原来的 ebp   // 设置新的栈基指针
        pop     edi
        pop     esi
        pop     ebp
        pop     ebx
        jmp   loc_536B73
        loc_536B70 :
        push    ebp
        push    edi
        pop     edi
        pop     esi
        pop     ebp
        pop     ebx
        jmp   loc_536B73
    }
}

// 处理数据的独立函数

void InstallHookX(uintptr_t TARGET_ADDR, void*& trampolineAddr, void* HookFunction) {
    constexpr int HookLen = 5;
    DWORD oldProtect;

    if (!VirtualProtect((LPVOID)TARGET_ADDR, HookLen, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed\n";
        return;
    }

    if (!trampolineAddr) {
        trampolineAddr = VirtualAlloc(NULL, HookLen + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (!trampolineAddr) {
            std::cerr << "VirtualAlloc failed\n";
            return;
        }
    }

    BYTE original_bytes[HookLen];
    memcpy(original_bytes, (LPVOID)TARGET_ADDR, HookLen);
    memcpy(trampolineAddr, original_bytes, HookLen);

    // 跳转回原函数剩下的部分
    BYTE jmpBack[5] = { 0xE9 };
    intptr_t backOffset = (intptr_t)(TARGET_ADDR + HookLen) - ((intptr_t)trampolineAddr + HookLen + 5);
    *(DWORD*)(jmpBack + 1) = (DWORD)backOffset;
    memcpy((BYTE*)trampolineAddr + HookLen, jmpBack, 5);

    // 写钩子跳转,前5字节jmp,其余填nop
    BYTE jmpHook[HookLen];
    jmpHook[0] = 0xE9;
    intptr_t hookOffset = (intptr_t)HookFunction - ((intptr_t)TARGET_ADDR + 5);
    *(DWORD*)(jmpHook + 1) = (DWORD)hookOffset;
    for (int i = 5; i < HookLen; i++) {
        jmpHook[i] = 0x90;
    }
    memcpy((LPVOID)TARGET_ADDR, jmpHook, HookLen);

    FlushInstructionCache(GetCurrentProcess(), (LPCVOID)TARGET_ADDR, HookLen);
    VirtualProtect((LPVOID)TARGET_ADDR, HookLen, oldProtect, &oldProtect);
}

void Unhook1() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook1\n";
        return;
    }
    BYTE original_bytes[5];
    memcpy(original_bytes, (LPVOID)trampolineAddr, 5);
    memcpy((LPVOID)TARGET_ADDR, original_bytes, 5);
    VirtualProtect((LPVOID)TARGET_ADDR, 15, oldProtect, &oldProtect);
}

void Unhook2() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR2, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook2\n";
        return;
    }
    BYTE original_bytes2[5];
    memcpy(original_bytes2, (LPVOID)trampolineAddr2, 5);
    memcpy((LPVOID)TARGET_ADDR2, original_bytes2, 5);
    VirtualProtect((LPVOID)TARGET_ADDR2, 15, oldProtect, &oldProtect);
}

void Unhook3() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR3, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook2\n";
        return;
    }
    BYTE original_bytes3[5];
    memcpy(original_bytes3, (LPVOID)trampolineAddr3, 5);
    memcpy((LPVOID)TARGET_ADDR3, original_bytes3, 5);
    VirtualProtect((LPVOID)TARGET_ADDR3, 15, oldProtect, &oldProtect);
}
void Unhook4() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR4, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook2\n";
        return;
    }
    BYTE original_bytes4[5];
    memcpy(original_bytes4, (LPVOID)trampolineAddr4, 5);
    memcpy((LPVOID)TARGET_ADDR4, original_bytes4, 5);
    VirtualProtect((LPVOID)TARGET_ADDR4, 15, oldProtect, &oldProtect);
}

void Unhook5() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR5, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook2\n";
        return;
    }
    BYTE original_bytes5[5];
    memcpy(original_bytes5, (LPVOID)trampolineAddr5, 5);
    memcpy((LPVOID)TARGET_ADDR5, original_bytes5, 5);
    VirtualProtect((LPVOID)TARGET_ADDR5, 15, oldProtect, &oldProtect);
}

void Unhook6() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR6, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook2\n";
        return;
    }
    BYTE original_bytes6[5];
    memcpy(original_bytes6, (LPVOID)trampolineAddr6, 5);
    memcpy((LPVOID)TARGET_ADDR6, original_bytes6, 5);
    VirtualProtect((LPVOID)TARGET_ADDR6, 15, oldProtect, &oldProtect);
}
void Unhook7() {
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)TARGET_ADDR7, 15, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "VirtualProtect failed in Unhook2\n";
        return;
    }
    BYTE original_bytes7[5];
    memcpy(original_bytes7, (LPVOID)trampolineAddr7, 5);
    memcpy((LPVOID)TARGET_ADDR7, original_bytes7, 5);
    VirtualProtect((LPVOID)TARGET_ADDR7, 15, oldProtect, &oldProtect);
}
// 在DLL入口中调用
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    printf("%s\n", aNameChina);
    printf("%s\n", aLoadbriefChina);
    printf("%s\n", aNameHowi);
    // 打印 wchar_t 字符串
    wprintf(L"%s\n", aNameTtnk);
    wprintf(L"%s\n", aLoadbriefRussi);
    wprintf(L"%s\n", aNameRussians);
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        InstallHookX(TARGET_ADDR, trampolineAddr, HookFunction);
        InstallHookX(TARGET_ADDR2, trampolineAddr2, loc_53649F);
        InstallHookX(TARGET_ADDR3, trampolineAddr3, loc_5367A7);
        InstallHookX(TARGET_ADDR4, trampolineAddr4, loc_536A62);
        InstallHookX(TARGET_ADDR5, trampolineAddr5, HookFunction5);
        //InstallHookX(TARGET_ADDR6, trampolineAddr6, HookFunction6);
        //InstallHookX(TARGET_ADDR7, trampolineAddr7, HookFunction7);
        break;
    case DLL_PROCESS_DETACH:
        Unhook1();
        Unhook2();
        Unhook3();
        Unhook4();
        Unhook5();
        //Unhook6();
        //Unhook7();
        break;
    }
    return TRUE;
}

 

请登录后发表评论