1

我需要找到一种方法来找到另一个程序的值的地址。我事先找到了地址,但是在我关闭并重新打开程序而不再次搜索它们之后我不知道如何再次找到它们(我需要程序自己找到它们)。任何人都知道我怎么能做到这一点(对不起,如果我不清楚我不知道如何解释它真的)如果你感到困惑只是问,​​我会尽量说清楚

我正在使用 C++

4

5 回答 5

4

假设您的平台是 Windows,我发现将您自己的 DLL 注入目标进程很方便。从那里,您可以进行堆遍历并查找值。在你得到它之后,通过 IPC 将它发送回你的进程(例如,使用 Boost 的 message_queue)。

编辑

Blood,正如你所要求的,这里有一些代码和值得深思的地方。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 轻松完成。下载库并查看非托管挂钩的示例。

于 2010-04-10T05:55:25.273 回答
3

程序可以很容易地找到自己变量的地址(&variable)。如果它正在合作,它可以通过一些正常的 IPC 机制将它发送到另一个程序。另一个程序(通常)不能直接用它做很多事情——至少在一个典型的系统(*BSD、Linux、Windows 等)上,每个进程都会有单独映射的内存,所以一个地址在一个不能直接用于另一个。

几乎所有都将提供某种调试功能,使您可以从另一个进程访问一个进程的内存,但其工作方式差异很大。

于 2010-04-10T05:04:13.537 回答
1

关闭并重新打开程序后,地址都是随机的。下次运行时无法保存地址。

相反,您需要为您拥有的任何数据设计一个文件结构。将其写入文件,以某种方式表达地址以外的结构关系,并在读回时恢复指针链接。这称为序列化。

于 2010-04-10T05:04:45.107 回答
1

理论上,如果你了解目标程序的工作原理及其内部数据结构,就可以找到目标变量的地址,因为在运行时动态分配的每个单字节内存总是可以从一些静态已知的信息中找到。代码,但源自函数内部的变量除外。然而,实际上,通过检查程序的二进制表示来理解程序几乎是不可能的。所以你不走运:-)

多一点想法:

让我猜猜你想做什么:你想在另一个进程中停止一个整数倒计时。如果是这种情况,您可以通过游戏工具手动查找地址,然后通过调试器设置断点以在写入地址时暂停,然后通过目标程序中的不同可能操作使断点发生。通过这种方式,您可以识别哪些代码正在减少值,并可能修改 EXE/DLL 以禁用这些代码。目标程序很可能会更频繁地崩溃或不再让您满意,因为您禁用的相同代码用于减少您和您的对手的能量:-)

于 2010-04-10T05:24:58.573 回答
0

如果您只想知道指针一次以将其包含在您的代码中,您可以使用像 cheatengine 这样的程序来获取指针。

于 2013-12-04T21:46:49.167 回答