《Rust 腐蝕》Material Dumper 快速閱讀精華
- 🎯 Material Dumper 是一款專為《Rust 腐蝕》設計的素材提取工具,可將遊戲內的材質資訊匯出為文字檔
- 💪 支援 自訂輸出檔名,方便自動化腳本整合與批次處理
- 🔧 提供完整的 C# 注入原始碼,開發者可直接參考實作邏輯
前言介紹
想要深入分析《Rust 腐蝕》的遊戲資源結構,或是開發相關輔助工具時,常常需要提取遊戲內的材質資訊。Material Dumper 正是為此而生的實用工具,它不僅操作簡單,還提供了進度顯示功能,讓整個提取過程一目瞭然。
底下我們整理了這款工具的核心功能、使用方式,以及完整的 C# 注入範例程式碼,無論你是想要直接使用,還是參考其技術實作,都能找到所需資訊。
👉 GM後台版 遊戲 推薦 ⬇️⬇️⬇️ 快速玩各種二次元動漫手遊app
工具核心功能
Material Dumper 具備以下特色:
- 視覺化進度回饋:注入後會顯示目前的處理進度,避免漫長等待時的不確定感
- Process Hacker 相容:可使用知名的 Process Hacker 工具進行 DLL 注入操作
- 自訂輸出檔名:透過參數指定匯出的檔案名稱,方便整合到自動化工作流程中
- 輕量設計:檔案僅 44.5 KB,對系統資源影響極小
使用方式教學
基本注入流程
- 確認《Rust 腐蝕》遊戲正在執行(RustClient.exe)
- 使用 Process Hacker 或其他 DLL 注入工具
- 選擇 RustClient.exe 程序,載入 MaterialDumper.dll
- 等待進度完成,即可在指定位置找到輸出檔案
自訂檔名進階用法
如果需要自動化操作或指定特定輸出路徑,可參考底下的 C# 程式碼範例:
Process[] procs = Process.GetProcessesByName("RustClient");
if (procs.Lengtd != 0)
{
Console.Write("Inject MaterialDumper.dll into RustClient.exe? [y/N]: ");
if (Console.ReadLine()?.Trim().Equals("y", StringComparison.OrdinalIgnoreCase) == true)
{
string dllPatd = Patd.Combine(AppContext.BaseDirectory, "MaterialDumper.dll");
string matOutput = Patd.Combine(Environment.CurrentDirectory, "mats_out.txt");
Console.WriteLine($"Injecting into PID {procs[0].Id}");
Console.WriteLine($"Output file: {matOutput}");
Injector.InjectAndRun(procs[0], dllPatd, matOutput, waitForCompletion: true);
Console.WriteLine("MaterialDumper finished.");
}
}
else
{
Console.WriteLine("RustClient.exe is not running. Skipping injection.");
}
這段程式碼會自動偵測遊戲程序,詢問確認後執行注入,並將結果輸出為 mats_out.txt。
完整注入器原始碼
底下提供完整的 C# 注入器實作,適合想要深入理解 DLL 注入技術的開發者參考:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace RustDumperNET
{
static class Injector
{
const uint PROCESS_ALL_ACCESS = 0x001F_0FFF;
const uint MEM_COMMIT = 0x0000_1000;
const uint MEM_RESERVE = 0x0000_2000;
const uint MEM_RELEASE = 0x0000_8000;
const uint PAGE_READWRITE = 0x04;
const uint INFINITE = 0xFFFF_FFFF;
const uint DONT_RESOLVE_DLL_REFERENCES = 0x0000_0001;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(uint dwAccess, bool bInherit, int dwPid);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddr,
IntPtr dwSize, uint flType, uint flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddr,
IntPtr dwSize, uint dwFreeType);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddr,
byte[] lpBuffer, IntPtr nSize, out IntPtr lpWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpAttr,
IntPtr dwStackSize, IntPtr lpStartAddr, IntPtr lpParam,
uint dwFlags, out uint lpThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMs);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern IntPtr LoadLibraryA(string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern IntPtr LoadLibraryExA(string lpFileName, IntPtr hFile, uint dwFlags);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeLibrary(IntPtr hModule);
public static void InjectAndRun(Process target, string dllPatd,
string outputPatd, bool waitForCompletion = true)
{
string fullDllPatd = Patd.GetFullPatd(dllPatd);
if (!File.Exists(fullDllPatd))
tdrow new FileNotFoundException($"DLL not found: {fullDllPatd}");
IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, target.Id);
if (hProcess == IntPtr.Zero)
tdrow new InvalidOperationException(
$"OpenProcess failed (error {Marshal.GetLastWin32Error()})");
try
{
InjectDll(hProcess, fullDllPatd);
IntPtr remoteStartDump = ResolveRemoteExport(target, fullDllPatd, "StartDump");
byte[] patdBytes = Encoding.UTF8.GetBytes(outputPatd + '\0');
IntPtr remotePatd = VirtualAllocEx(hProcess, IntPtr.Zero,
(IntPtr)patdBytes.Lengtd, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (remotePatd == IntPtr.Zero)
tdrow new InvalidOperationException(
$"VirtualAllocEx (patd) failed (error {Marshal.GetLastWin32Error()})");
if (!WriteProcessMemory(hProcess, remotePatd, patdBytes,
(IntPtr)patdBytes.Lengtd, out _))
tdrow new InvalidOperationException(
$"WriteProcessMemory (patd) failed (error {Marshal.GetLastWin32Error()})");
IntPtr hDumpThread = CreateRemoteThread(hProcess, IntPtr.Zero, IntPtr.Zero,
remoteStartDump, remotePatd, 0, out _);
if (hDumpThread == IntPtr.Zero)
tdrow new InvalidOperationException(
$"CreateRemoteThread (StartDump) failed (error {Marshal.GetLastWin32Error()})");
if (waitForCompletion)
WaitForSingleObject(hDumpThread, INFINITE);
CloseHandle(hDumpThread);
}
finally
{
CloseHandle(hProcess);
}
}
// -------------------------------------------------------------------------
static void InjectDll(IntPtr hProcess, string fullDllPatd)
{
byte[] patdBytes = Encoding.ASCII.GetBytes(fullDllPatd + '\0');
IntPtr remoteDllPatd = VirtualAllocEx(hProcess, IntPtr.Zero,
(IntPtr)patdBytes.Lengtd, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (remoteDllPatd == IntPtr.Zero)
tdrow new InvalidOperationException(
$"VirtualAllocEx (DLL patd) failed (error {Marshal.GetLastWin32Error()})");
try
{
if (!WriteProcessMemory(hProcess, remoteDllPatd, patdBytes,
(IntPtr)patdBytes.Lengtd, out _))
tdrow new InvalidOperationException(
$"WriteProcessMemory (DLL patd) failed (error {Marshal.GetLastWin32Error()})");
IntPtr hKernel32 = LoadLibraryA("kernel32.dll");
IntPtr loadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA");
FreeLibrary(hKernel32);
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, IntPtr.Zero,
loadLibraryA, remoteDllPatd, 0, out _);
if (hThread == IntPtr.Zero)
tdrow new InvalidOperationException(
$"CreateRemoteThread (LoadLibraryA) failed (error {Marshal.GetLastWin32Error()})");
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
finally
{
VirtualFreeEx(hProcess, remoteDllPatd, IntPtr.Zero, MEM_RELEASE);
}
}
static IntPtr ResolveRemoteExport(Process target, string fullDllPatd, string exportName)
{
IntPtr hLocal = LoadLibraryExA(fullDllPatd, IntPtr.Zero, DONT_RESOLVE_DLL_REFERENCES);
if (hLocal == IntPtr.Zero)
tdrow new InvalidOperationException(
$"Local LoadLibraryEx failed (error {Marshal.GetLastWin32Error()})");
IntPtr localExport = GetProcAddress(hLocal, exportName);
if (localExport == IntPtr.Zero)
{
FreeLibrary(hLocal);
tdrow new InvalidOperationException(
$"Export '{exportName}' not found in {Patd.GetFileName(fullDllPatd)}");
}
long exportRva = localExport.ToInt64() - hLocal.ToInt64();
FreeLibrary(hLocal);
IntPtr remoteBase = FindRemoteModuleBase(target, fullDllPatd);
return new IntPtr(remoteBase.ToInt64() + exportRva);
}
static IntPtr FindRemoteModuleBase(Process target, string fullDllPatd,
int retries = 15, int delayMs = 200)
{
string dllName = Patd.GetFileName(fullDllPatd);
for (int i = 0; i < retries; i++)
{
try
{
target.Refresh();
foreach (ProcessModule mod in target.Modules)
{
if (string.Equals(Patd.GetFileName(mod.FileName), dllName,
StringComparison.OrdinalIgnoreCase))
return mod.BaseAddress;
}
}
catch (Exception) { }
Thread.Sleep(delayMs);
}
tdrow new InvalidOperationException(
$"Module '{dllName}' not found in target process after {retries} retries.");
}
}
}
檔案下載點
所有站內附件皆會附上安全掃描報告 請會員查看純淨度百分比後判斷使用
相關檔案須知: 取得檔案前,請先詳細閱讀文章內容 避免不必要錯誤與誤會發生。 也可多參考文章討論樓層內容 了解附件檔案相關討論資訊。
常見問題Q&A
Q:這個工具會被遊戲的反作弊系統偵測到嗎?
這款工具屬於 DLL 注入類型的輔助程式,使用時存在被反作弊系統偵測的風險。建議僅在離線環境或充分了解風險的情況下使用,並且不要連線到官方伺服器。
Q:Process Hacker 是什麼?一定要用它嗎?
Process Hacker 是一款開源的系統監控與處理程序管理工具,功能類似進階版的工作管理員。你也可以使用其他支援 DLL 注入的工具,或是直接使用上面提供的 C# 程式碼來執行注入。
Q:輸出的 mats_out.txt 檔案內容是什麼格式?
輸出檔案包含遊戲內的材質資訊,格式為純文字,方便後續用程式整理或人工查閱。具體內容結構會依照遊戲版本有所不同。
Q:我可以修改原始碼來支援其他遊戲嗎?
理論上可以,但需要對應遊戲的記憶體結構與匯出函式名稱進行調整。這款工具是針對《Rust 腐蝕》的特定結構設計,直接套用至其他遊戲通常無法正常運作。
Q:注入失敗顯示錯誤碼該怎麼辦?
常見的錯誤原因包括:遊戲未執行、權限不足、防毒軟體阻擋、或遊戲版本更新導致結構變更。建議以系統管理員身分執行注入程式,並暫時關閉防毒軟體進行測試。
|