C# 簡單記憶體補丁

来源:http://www.cnblogs.com/Supperlitt/archive/2017/04/15/6714111.html
-Advertisement-
Play Games

寫在開頭:看了一些視頻教程,感覺OD為什麼別人學個破解那麼容易,我就那麼難了呢,可能是沒有那麼多時間吧。 解釋:個人見解:所謂記憶體補丁,即:通過修改運行程式的內容,來達到某種目的的操作。修改使用OpenProcess打開,WriteProcessMemory寫入,CloseHandle關閉。部分需要 ...


寫在開頭:看了一些視頻教程,感覺OD為什麼別人學個破解那麼容易,我就那麼難了呢,可能是沒有那麼多時間吧。

解釋:個人見解:所謂記憶體補丁,即:通過修改運行程式的內容,來達到某種目的的操作。修改使用OpenProcess打開,WriteProcessMemory寫入,CloseHandle關閉。部分需要讀取數據判斷使用:ReadProcessMemory

0x1 看教程

  關於有的學習教程,確實要看看視頻才能瞭解別人的操作,或者很簡單一個東西,如果沒有別人的指導那麼自己操作確實不太容易。

0x2 學習到部分概念

  肯定不可能一味的模仿,做一樣的東西,所以需要學以致用就很關鍵了。於是乎,用vs2013 c++寫了幾行代碼,用於自己測試,用C#寫記憶體補丁

0x3 網上檢索

  沒有人生而知之,所以網上查詢也是很關鍵的一步,查詢哪些內容呢?就是查詢C#如何寫記憶體補丁,代碼大同小異不過不一定能用。

0x4 代碼實踐

  網上找到的代碼也是要在實踐中得出能否使用的。所以這一步也是必不可免的。

於是乎有了下麵的代碼。需要使用OD找到代碼的位置即和在記憶體中和代碼的相差位置。

MCF程式  C++ OK方法中

void CMFCTestDlg::OnBnClickedOk()
{
    CString str;
    GetDlgItemText(IDC_EDIT1, str);

    if (str == "test123456789"){
        ::MessageBox(NULL, L"OK", L"提示", 0);
    }
    else{
        ::MessageBox(NULL, L"Fail", L"提示", 0);
    }
}
View Code

C#程式中調用,首先貼一個幫助類,來源網上。當然對其中添加和修改了部分方法。

public abstract class ApiHelper
    {
        [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
        public static extern bool ReadProcessMemory
            (
                IntPtr hProcess,
                IntPtr lpBaseAddress,
                IntPtr lpBuffer,
                int nSize,
                IntPtr lpNumberOfBytesRead
            );

        [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
        public static extern IntPtr OpenProcess
            (
                int dwDesiredAccess,
                bool bInheritHandle,
                int dwProcessId
            );

        [DllImport("kernel32.dll")]
        private static extern void CloseHandle
            (
                IntPtr hObject
            );

        //寫記憶體
        [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
        public static extern bool WriteProcessMemory
        (
            IntPtr hProcess,
            IntPtr lpBaseAddress,
            int[] lpBuffer,
            int nSize,
            IntPtr lpNumberOfBytesWritten
        );

        //獲取窗體的進程標識ID
        public static int GetPid(string windowTitle)
        {
            int rs = 0;
            Process[] arrayProcess = Process.GetProcesses();
            foreach (Process p in arrayProcess)
            {
                if (p.MainWindowTitle.IndexOf(windowTitle) != -1)
                {
                    rs = p.Id;
                    break;
                }
            }

            return rs;
        }

        //根據進程名獲取PID
        public static int GetPidByProcessName(string processName, ref IntPtr baseAddress)
        {
            Process[] arrayProcess = Process.GetProcessesByName(processName);
            foreach (Process p in arrayProcess)
            {
                baseAddress = p.MainModule.BaseAddress;
                return p.Id;
            }

            return 0;
        }

        //根據進程名獲取PID
        public static int GetPidByProcessName(string processName)
        {
            Process[] arrayProcess = Process.GetProcessesByName(processName);
            foreach (Process p in arrayProcess)
            {
                return p.Id;
            }

            return 0;
        }

        //根據窗體標題查找視窗句柄(支持模糊匹配)
        public static IntPtr FindWindow(string title)
        {
            Process[] ps = Process.GetProcesses();
            foreach (Process p in ps)
            {
                if (p.MainWindowTitle.IndexOf(title) != -1)
                {
                    return p.MainWindowHandle;
                }
            }
            return IntPtr.Zero;
        }

        //讀取記憶體中的值
        public static int ReadMemoryValue(int baseAddress, string processName)
        {
            try
            {
                byte[] buffer = new byte[2];
                IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //獲取緩衝區地址
                IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
                ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, buffer.Length, IntPtr.Zero); //將制定記憶體中的值讀入緩衝區
                CloseHandle(hProcess);
                return Marshal.ReadInt32(byteAddress);
            }
            catch
            {
                return 0;
            }
        }

        //將值寫入指定記憶體地址中
        public static bool WriteMemoryValue(int baseAddress, string processName, int[] value)
        {
            IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高許可權
            bool result = WriteProcessMemory(hProcess, (IntPtr)baseAddress, value, value.Length, IntPtr.Zero);
            CloseHandle(hProcess);

            return result;
        }
    }
View Code

最後是在具體按鈕中的調用了。

private string processName = "MFCTest"; //

        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr startAddress = IntPtr.Zero;
            int pid = ApiHelper.GetPidByProcessName(processName, ref startAddress);
            if (pid == 0)
            {
                MessageBox.Show("哥們啟用之前該運行吧!");
                return;
            }

            int baseAddress = startAddress.ToInt32() + 0x1000;
            int value = ReadMemoryValue(baseAddress);             // 讀取基址(該地址不會改變)
            int address = baseAddress + 0x14F3;                   // 獲取2級地址
            value = ReadMemoryValue(address);
            bool result = WriteMemory(address, new int[] { 144 });
            address = address + 0x1;
            result = WriteMemory(address, new int[] { 144 });

            MessageBox.Show(result ? "成功" : "失敗");
        }


        //讀取制定記憶體中的值
        public int ReadMemoryValue(int baseAdd)
        {
            return ApiHelper.ReadMemoryValue(baseAdd, processName);
        }

        //將值寫入指定記憶體中
        public bool WriteMemory(int baseAdd, int[] value)
        {
            return ApiHelper.WriteMemoryValue(baseAdd, processName, value);
        }
View Code

0x5 總結

  只有不斷學習才能知道新的知識,同時在學習中進步。很多不懂的概念其實很簡單。當然前提是你明白以後。

   其中註意一點。

測試代碼下載:WriteProcessMemory的buffer填入一個數組也是可以的。需要計算長度。然後nSize就是,前面的數組作為幾個位元組進行使用。

// 重構了些許代碼


        //將值寫入指定記憶體地址中
        public static bool WriteMemoryValue(int baseAddress, string processName, int[] value, int len)
        {
            IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高許可權
            bool result = WriteProcessMemory(hProcess, (IntPtr)baseAddress, value, len, IntPtr.Zero);
            CloseHandle(hProcess);

            return result;
        }

// 144=0x90  表示 nop
bool result = ApiHelper.WriteMemoryValue(address, processName, new int[] { 144 + 144 * 256 }, 2);

 

 WinTestRe.zip


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第三章 MVC 模式,項目和約定 在深入瞭解ASP.NET Core MVC的細節之前,我想確保您熟悉MVC設計模式背後的思路以及將其轉換為ASP.NET Core MVC項目的方式。 您可能已經瞭解本章中討論的一些想法和約定,特別是如果您已經完成了高級ASP.NET或C#開發。 如果沒有,我鼓勵你 ...
  • 從開始接觸.Net Core到現在已經有將近一年的時間了,今天來做一下相關的學習總結,順便也回憶一下自己這段時間以來的成長。 有一點不得不承認的是,在接觸.Net Core之前,我對於linux系統一點也不瞭解,也未曾有過主動去學習的念頭,在接觸了.Net Core之後才開始慢慢學習linux相關知 ...
  • 轉自:http://blog.163.com/m13864039250_1/blog/static/2138652482015283397609/ 用Fluent API 配置/映射屬性和類型 簡介 通常通過重寫派生DbContext 上的OnModelCreating 方法來訪問Code Firs ...
  • 在一些數據的即時查詢場景中,我們可能需要對輸入信息進行模糊查詢併進行選擇,例如在一些文本輸入場景,如輸入某個站點編碼或者設備編碼,然後獲取符合的列表供用戶選擇的場景,本篇隨筆介紹在DevExpress程式中使用PopupContainerEdit和PopupContainer實現數據展示。 ...
  • Rookey.Frame v1.0經過一年時間的修改及沉澱,穩定版終於問世了,此版本經過上線系統驗證,各個功能點都經過終端用戶驗證並持續優化,主要優化以下幾個方面: 1.性能較原來提升3倍之多 2.修複BUG數達1000+上 3.模塊緩存即時生效無需手動刷新緩存 4.增加可配置的任務調度功能 5.表 ...
  • 一.IIS部署基本問題 將項目部署部署到IIS時,啟動網站常會遇到頁面報錯not found 403 可能原因: 1.應用程式池.Net Framework版本不對,解決方法打開控制面板-->管理工具-->Internet信息服務(IIS)管理器,打開應用程式池選擇項目的應用程式,配置為相應版本; ...
  • net core cli 是快速創建模板項目 1. 安裝CLI 參考: https://www.hanselman.com/blog/dotnetNewAngularAndDotnetNewReact.aspx 視頻參考: https://www.youtube.com/channel/UC_R2R ...
  • row.Table.Columns.Contains( "fieldname ") ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...