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> 太强了 大大 其他数据怎么改 謝謝大大用心推! 請問這是需要使用DLL注入的方式嗎?
DLL注入會失敗
目前可以編譯完成,但不知道要怎麼使用 建議 使用intel c++ strays 發表於 2022-3-21 13:42 static/image/common/back.gif
建議 使用intel c++
怎麼說呢?? 是有比較好debug 還是說有其方便之處
平常都是用visual studio 寫 C++ & C#
VSC++ 加入 masm 不是也可以編寫嗎?
測試下intel c++ 還是看不懂 求高手來個教學 太专业了.有点弄不来怎么玩:( sky40112 發表於 2022-3-21 17:20 static/image/common/back.gif
怎麼說呢?? 是有比較好debug 還是說有其方便之處
平常都是用visual studio 寫 C++ & C#
VSC++ 加入 masm ...
inline asm 方便 #define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field))令人眼前一亮 ;P感謝分享 實用
頁:
[1]
2