kkmomo 發表於 2022-2-27 04:12:23

x64 Dll + Asm + NT Api hook VC++ sample code

本帖最後由 kkmomo 於 2022-2-27 04:16 編輯

Tested for TwMS 241.1 MapleStory.exe
全部5個檔案,下面直接貼 source ,不另附檔案下載

範例中數據皆取自本站的 新 楓之谷(MapleStory) 遊戲代碼分享區

檔案列表:
Assembly.asm
dllmain.cpp
X64AsmSample.sln
X64AsmSample.vcxproj
X64AsmSample.vcxproj.filters

此範例實作:
1. CRC bypass (沒用到 asm)
    注入 dll 後直接寫入

2. Boss 無敵 Asm + 開關
    預設為關
    call SetBossInvincibleEnable(BOOLEAN Enable) 設定開/關

3. 全職業攻擊技能無延遲 Asm + 開關
    預設為關,速度5
    call SetAttackNoDelay(BOOLEAN Enable)  設定開/關
    call SetAttackNoDelayValue(DWORD Value) 設定速度

4. Nt Api Hook Asm + hook function
    以 Hook NtQuerySystemInformation 為例
    當 SystemInformationClass == SystemProcessInformation 時
    印出 pid 跟 process image name

Assembly.asm; ASSEMBLE CODE

; Exportation
PUBLIC BossInvincible
PUBLIC AttackNoDelay
PUBLIC NtQuerySystemInformation_Orig


; Importation
EXTERN g_controlData_Enable_BossInvincible:QWORD
EXTERN g_controlData_Enable_NoDelay:QWORD
EXTERN g_controlData_NoDelayValue:QWORD

; Declaration
.DATA
g_noDelayCount DB 00H


; Implementation
.CODE

BossInvincible PROC
  mov rcx,
  cmp byte ptr , 01H
  je BossInvincible_Enable
  mov rcx, 140531EC0H
  push rcx
  mov ecx,
  ret
BossInvincible_Enable:
  mov eax,01H
  ret
BossInvincible ENDP

AttackNoDelay PROC
  mov rcx,
  cmp byte ptr , 01H
  jne AttackNoDelay_Orig
  mov rcx,
  mov al, byte ptr
  cmp byte ptr , al
  jae AttackNoDelay_Orig
  inc byte ptr
  jmp SkipSetAction
AttackNoDelay_Orig:
  mov byte ptr , 0
  mov ,r13d
SkipSetAction:
  mov rax,
  mov ,ebx
  mov rcx,1434F9CD7H
  jmp rcx
AttackNoDelay ENDP

NtQuerySystemInformation_Orig PROC
  mov r10,rcx
  mov eax,00000036H
  syscall
  ret
NtQuerySystemInformation_Orig ENDP

ENDdllmain.cpp#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
#include <shlwapi.h>
#include <winternl.h>
#include <tchar.h>
#include <stdio.h>

#pragma comment(lib, "Shlwapi.lib")

#define _DEBUG_TAG_ L"sample"
#define _FMT_PREFIX_ _DEBUG_TAG_ L": %s L%d "
#define _FMT_NEWLINE_ L"\r\n"
#define my_log(fmt, ...) mylog(_FMT_PREFIX_ _T(fmt) _FMT_NEWLINE_, __FUNCTIONW__, __LINE__, __VA_ARGS__)
#define TARGET_PROCESS_NAME L"MapleStory.exe"

#ifndef RtlOffsetToPointer
#define RtlOffsetToPointer(B,O)  ((PCHAR)( ((PCHAR)(B)) + ((ULONG_PTR)(O))  ))
#endif

typedef struct _SYSTEM_PROCESS_INFO
{
    ULONG                   NextEntryOffset;
    ULONG                   NumberOfThreads;
    LARGE_INTEGER           Reserved;
    LARGE_INTEGER           CreateTime;
    LARGE_INTEGER           UserTime;
    LARGE_INTEGER           KernelTime;
    UNICODE_STRING          ImageName;
    ULONG                   BasePriority;
    HANDLE                  ProcessId;
    HANDLE                  InheritedFromProcessId;
} SYSTEM_PROCESS_INFO, * PSYSTEM_PROCESS_INFO;

struct CONTROL_DATA
{
    BOOLEAN Enable_BossInvincible;
    BOOLEAN Enable_NoDelay;
    DWORD NoDelayValue;
};

CONTROL_DATA g_controlData{ 0 };

typedef union tagpfnNtQuerySystemInformation {
    NTSTATUS(NTAPI* func_ptr)(
        IN      SYSTEM_INFORMATION_CLASS SystemInformationClass,
        IN OUT  PVOID SystemInformation,
        IN      ULONG SystemInformationLength,
        OUT     PULONG ReturnLength OPTIONAL
        );
} pfnNtQuerySystemInformation;

pfnNtQuerySystemInformation pNtQuerySystemInformation = { 0 };

void mylog(LPCWSTR Format, ...)
{
    WCHAR buf = L"";
    va_list args;
    va_start(args, Format);
    vswprintf_s(buf, _countof(buf), Format, args);
    OutputDebugStringW(buf);
    va_end(args);
}

NTSTATUS NtQuerySystemInformation_Hook(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength)
{
    NTSTATUS Status;
    PSYSTEM_PROCESS_INFO SystemProcess;
    PSYSTEM_PROCESS_INFO NextSystemProcess;
    Status = pNtQuerySystemInformation.func_ptr(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
    if (NT_SUCCESS(Status) && SystemInformationClass == SystemProcessInformation)
    {
        SystemProcess = (PSYSTEM_PROCESS_INFO)SystemInformation;
        NextSystemProcess = (PSYSTEM_PROCESS_INFO)((PBYTE)SystemProcess + SystemProcess->NextEntryOffset);
        my_log("Query ProcessId=%llu ImageName=%wZ", NextSystemProcess->ProcessId, &NextSystemProcess->ImageName);
    }
    return Status;
}

extern "C"
{
    DWORD64 g_controlData_Enable_BossInvincible = 0;
    DWORD64 g_controlData_Enable_NoDelay = 0;
    DWORD64 g_controlData_NoDelayValue = 0;

    void BossInvincible();
    void AttackNoDelay();
    NTSTATUS NtQuerySystemInformation_Orig(
        SYSTEM_INFORMATION_CLASS SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength);
}

void WriteMem(const DWORD64 lpAddress, PBYTE Buffer, unsigned Length)
{
    BOOL res;
    DWORD OldProtection;
    res = VirtualProtect((LPVOID)lpAddress, Length, PAGE_EXECUTE_READWRITE, &OldProtection);
    if (res == TRUE)
    {
        memcpy((LPBYTE)lpAddress, Buffer, Length);
        res = VirtualProtect((LPVOID)lpAddress, Length, OldProtection, &OldProtection);
        if (res != TRUE)
        {
            my_log("Restore mem protect fail %lu", GetLastError());
        }
    }
    else
    {
        my_log("Set mem protect fail %lu", GetLastError());
    }
}

void AsmJumpFar(const DWORD64 lpAddress, LPCVOID Function, SIZE_T Nops)
{
    DWORD OldProtection;
    VirtualProtect((LPVOID)lpAddress, 14ULL + Nops, PAGE_EXECUTE_READWRITE, &OldProtection);
    *(LPWORD)lpAddress = 0x25FFU;
    *(PDWORD)(lpAddress + 2) = 0;
    *(PDWORD64)(lpAddress + 6) = (DWORD64)Function;
    if (!!Nops)
    {
        memset(((LPBYTE)lpAddress + 14), 0x90, Nops);
    }
    VirtualProtect((LPVOID)lpAddress, 14ULL + Nops, OldProtection, &OldProtection);
}

void SetBossInvincibleEnable(BOOLEAN Enable)
{
    g_controlData.Enable_BossInvincible = Enable;
}

void SetAttackNoDelay(BOOLEAN Enable)
{
    g_controlData.Enable_NoDelay = Enable;
}

void SetAttackNoDelayValue(DWORD Value)
{
    g_controlData.NoDelayValue = Value;
}

void MyRoutine()
{
    g_controlData_Enable_BossInvincible = (DWORD64)RtlOffsetToPointer(&g_controlData, FIELD_OFFSET(CONTROL_DATA, Enable_BossInvincible));
    g_controlData_Enable_NoDelay = (DWORD64)RtlOffsetToPointer(&g_controlData, FIELD_OFFSET(CONTROL_DATA, Enable_NoDelay));
    g_controlData_NoDelayValue = (DWORD64)RtlOffsetToPointer(&g_controlData, FIELD_OFFSET(CONTROL_DATA, NoDelayValue));
   
    HMODULE ntdll = GetModuleHandleA("ntdll.dll");
    if (ntdll)
    {
        DWORD64 NtQuerySystemInformation_Addr = (DWORD64)GetProcAddress(ntdll, "NtQuerySystemInformation");
        *(DWORD64*)(&pNtQuerySystemInformation) = (DWORD64)NtQuerySystemInformation_Orig;
        my_log("NtQuerySystemInformation_Addr=%p", NtQuerySystemInformation_Addr);
        AsmJumpFar(NtQuerySystemInformation_Addr, NtQuerySystemInformation_Hook, 2);
    }
    else
    {
        my_log("Get ntdll module handle fail %lu", GetLastError());
    }

    BYTE bypassPatch[] =
    {
        //xor eax,eax
        0x31, 0xC0,
        //ret
        0xC3,
        // nops
        0x90, 0x90
    };
    DWORD64 function_addr = 0x143B7E0E0U;
    WriteMem(function_addr, bypassPatch, sizeof(bypassPatch));
    AsmJumpFar(0x141B01AD0U, BossInvincible, 0);
    AsmJumpFar(0x1434F9CC9U, AttackNoDelay, 0);
    SetAttackNoDelayValue(5);
    SetBossInvincibleEnable(FALSE);
    SetAttackNoDelay(FALSE);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    DWORD len;
    WCHAR processName = { 0 };

    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        len = GetModuleFileNameW(GetModuleHandleA(NULL), processName, MAX_PATH);
        if (len > 0)
        {
            if (StrStrW(processName, TARGET_PROCESS_NAME))
            {
                my_log("CreateThread");
                CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MyRoutine, 0, 0, 0);
            }
        }
        else
        {
            my_log("Get moudle file name fail %lu.", GetLastError());
        }
        break;
    case DLL_PROCESS_DETACH:
        FreeLibrary(hModule);
        break;
    }
    return TRUE;
}X64AsmSample.slnMicrosoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31911.196
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X64AsmSample", "X64AsmSample.vcxproj", "{BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}"
EndProject
Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|x64 = Debug|x64
                Release|x64 = Release|x64
        EndGlobalSection
        GlobalSection(ProjectConfigurationPlatforms) = postSolution
                {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Debug|x64.ActiveCfg = Debug|x64
                {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Debug|x64.Build.0 = Debug|x64
                {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Release|x64.ActiveCfg = Release|x64
                {BE72125F-805E-4DF1-B8BE-80DFC1C1AA83}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CB2CD138-098F-465E-A9B3-17033E4BA7F0}
        EndGlobalSection
EndGlobalX64AsmSample.vcxproj<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <VCProjectVersion>16.0</VCProjectVersion>
    <Keyword>Win32Proj</Keyword>
    <ProjectGuid>{be72125f-805e-4df1-b8be-80dfc1c1aa83}</ProjectGuid>
    <RootNamespace>X64AsmSample</RootNamespace>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>_DEBUG;X64ASMSAMPLE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
      <PrecompiledHeader>NotUsing</PrecompiledHeader>
      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <EnableUAC>false</EnableUAC>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>NDEBUG;X64ASMSAMPLE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
      <PrecompiledHeader>NotUsing</PrecompiledHeader>
      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <EnableUAC>false</EnableUAC>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="dllmain.cpp" />
  </ItemGroup>
  <ItemGroup>
    <MASM Include="Assembly.asm">
      <FileType>Document</FileType>
    </MASM>
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
  </ImportGroup>
</Project>X64AsmSample.vcxproj.filters<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="dllmain.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <MASM Include="Assembly.asm">
      <Filter>Source Files</Filter>
    </MASM>
  </ItemGroup>
</Project>

廖信翔 發表於 2022-2-27 16:12:42

xlChen 發表於 2022-2-27 23:00:10

太强了

依然卡卡 發表於 2022-3-14 21:55:22

大大 其他数据怎么改

molina1026 發表於 2022-3-20 12:52:22

謝謝大大用心推!

sky40112 發表於 2022-3-20 13:36:27

請問這是需要使用DLL注入的方式嗎?
DLL注入會失敗
目前可以編譯完成,但不知道要怎麼使用

strays 發表於 2022-3-21 13:42:43

建議 使用intel c++

sky40112 發表於 2022-3-21 17:20:23

strays 發表於 2022-3-21 13:42 static/image/common/back.gif
建議 使用intel c++

怎麼說呢?? 是有比較好debug 還是說有其方便之處
平常都是用visual studio 寫 C++ & C#
VSC++ 加入 masm 不是也可以編寫嗎?

strays 發表於 2022-3-21 17:33:21

測試下intel c++

Happy0626 發表於 2022-3-24 22:16:24

還是看不懂 求高手來個教學

huhai122 發表於 2022-4-18 20:34:23

太专业了.有点弄不来怎么玩:(

Torin 發表於 2022-6-19 16:01:19

sky40112 發表於 2022-3-21 17:20 static/image/common/back.gif
怎麼說呢?? 是有比較好debug 還是說有其方便之處
平常都是用visual studio 寫 C++ & C#
VSC++ 加入 masm  ...

inline asm 方便

t812206236 發表於 2022-7-9 19:08:00

#define FIELD_OFFSET(type, field)    ((LONG)(LONG_PTR)&(((type *)0)->field))令人眼前一亮

PS2GUARD 發表於 2022-7-20 22:31:36

;P感謝分享

ysl86294 發表於 2023-1-5 23:54:03

實用
頁: [1] 2
查看完整版本: x64 Dll + Asm + NT Api hook VC++ sample code