簡體   English   中英

如何找到內存中的數據地址?

[英]how to find the address of data in memory?

我需要找到一種方法來找到另一個程序的值的地址。 我先找到了地址,但關閉並重新打開程序后又不再次搜索它們,我不知道如何找到它們(我需要程序自己找到它們)。 任何人都知道我該怎么做(對不起,如果不清楚,我真的不知道如何解釋),如果您感到困惑,只是問一下,我會盡力弄清楚

我正在使用C ++

假設您的平台是Windows,我發現將自己的DLL注入目標進程很方便。 從那里,您可以進行堆遍歷並尋找值。 獲得它之后,通過IPC將其發送回您的進程(例如,使用Boost的message_queue)。

編輯

, as you requested, here's a little code and a food for thought. ,按照您的要求,這里有一個小的代碼和思想食品。 DLL本身非常簡單,例如:


#include <Windows.h>

/** You can use this one to examine the given memory blocks.
  * However, since you're inside another process, you cannot use
  * std::cout. But you'll get the idea (just an example). The code
  * is from my another project.
  */
void MyDump(const void *m, unsigned int n)
{
        const unsigned char *p = reinterpret_cast<const unsigned char *>(m);
        char buffer[16];
        unsigned int mod = 1;

        memset(&buffer, 0, sizeof(buffer));

        std::cout << "------------------------------------------------------------------------------------\nOffset     | Hex                                                | ASCII            |\n------------------------------------------------------------------------------------\n0x" << std::setfill('0') << std::setw(8) << std::hex << (long)m << " |";

        for (unsigned int i = 0; i < n; ++i, ++mod) {
                buffer[i % 16] = p[i];

                --mod;

                if (mod % 4 == 0)
                        std::cout << " ";

                ++mod;

                std::cout << std::setw(2) << std::hex << static_cast<unsigned int>(p[i]) << " ";

                if ((mod == 16 && i != 0) || i == n - 1) {
                        if (i == n - 1) {
                                for (unsigned int j = 0; j < (16 - mod) * 3; ++j)
                                        std::cout << " ";

                                if (mod <= 4)
                                        std::cout << " ";

                                if (mod <= 8)
                                        std::cout << " ";

                                if (mod <= 12)
                                        std::cout << " ";
                        }

                        mod = 0;

                        std::cout << "| ";

                        for (unsigned short j = 0; j < 16; ++j) {
                                switch (buffer[j]) {
                                        case 0x7:
                                        case 0x8:
                                        case 0x9:
                                        case 0xa:
                                        case 0xb:
                                        case 0xd:
                                        case 0xe:
                                        case 0xf:
                                                std::cout << " ";

                                                break;

                                        default: std::cout << buffer[j];
                                }
                        }

                        std::cout << " |";

                        if (i == n - 1) {
                                std::cout << "\n------------------------------------------------------------------------------------\n";

                                return;
                        }

                        memset(&buffer, 0, sizeof(buffer));

                        std::cout << "\n0x" << std::setfill('0') << std::setw(8) << std::hex << (long)m + i << " |";
                }
        }
}

BOOL APIENTRY DllMain(HANDLE h_module, DWORD ul_reason_for_call, LPVOID)
{
        switch (ul_reason_for_call) {
                case DLL_PROCESS_ATTACH:
                        /** Do the heap walk here, please see
                          * http://msdn.microsoft.com/en-us/library/ee175819%28v=VS.85%29.aspx
                          * for enumerating the heap.
                          */

                        break;

                case DLL_THREAD_ATTACH: break;

                case DLL_THREAD_DETACH: break;

                case DLL_PROCESS_DETACH:
        }
}

現在有了DLL,您仍然需要將其注入所需的進程。 使用EasyHook API可以輕松完成此操作。 下載該庫,並查看非托管掛鈎的示例。

程序可以很容易地找到其自身變量的地址( &variable )。 如果它在事物上協作,則可以通過某種常規IPC機制將其發送到其他程序。 但是,另一個程序通常無法直接執行很多操作-至少在典型的系統(* BSD,Linux,Windows等)上,每個進程將分別映射內存,因此一個地址位於一個內存中在另一個環境中不能直接使用。

幾乎所有人都將提供某種調試功能,使您可以從另一個進程訪問一個進程的內存,但是工作方式千差萬別。

關閉並重新打開程序后,地址將全部隨機化。 無法保存下次運行的地址。

相反,您需要為任何數據設計文件結構。 將其寫入文件,以某種方式表達地址以外的結構關系,並在讀回時恢復指針鏈接。 這稱為序列化。

從理論上講,如果您了解目標程序的工作方式及其內部數據結構,則可以找到目標變量的地址,因為在運行時動態分配的內存的每個單個字節始終可以從靜態已知的一些信息中找到。代碼,但源自函數內部的變量除外。 但是,實際上,通過檢查程序的二進制表示來理解程序幾乎是不可能的。 所以你不走運:-)

還有一點想法:

讓我猜猜您要做什么:您想在另一個進程中停止倒數。 在這種情況下,您可以通過游戲工具手動找到地址,然后由調試器將斷點設置為在寫入地址時暫停,然后通過目標程序中的各種可能操作使斷點發生。 這樣,您可以確定哪些代碼正在減小該值,並可能修改EXE / DLL以禁用這些代碼。 目標程序很有可能會崩潰或不再招待您,因為您禁用的相同代碼會減少您和對手的精力:-)

如果您只想一次了解該指針以將其包含在代碼中,則可以使用諸如cheatengine之類的程序來獲取該指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM