简体   繁体   English

如何找到内存中的数据地址?

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

i need to find a way how to find the address's for value of another program. 我需要找到一种方法来找到另一个程序的值的地址。 i find the address before hand but i don't know how to find them again after i close and reopen the program with out searching for them again (i need the program to find them on it's own). 我先找到了地址,但关闭并重新打开程序后又不再次搜索它们,我不知道如何找到它们(我需要程序自己找到它们)。 anyone know how i can do this (sorry if im unclear i don't know how to explain it really) if your confused just ask and i'll try to make it clear 任何人都知道我该怎么做(对不起,如果不清楚,我真的不知道如何解释),如果您感到困惑,只是问一下,我会尽力弄清楚

im using C++ 我正在使用C ++

Assuming your platform is Windows, I find it convenient to inject your own DLL into the target process. 假设您的平台是Windows,我发现将自己的DLL注入目标进程很方便。 From there, you could possibly do a heap walk and look for the value. 从那里,您可以进行堆遍历并寻找值。 After you've got it, send it back to your process via IPC (for instance, with Boost's message_queue). 获得它之后,通过IPC将其发送回您的进程(例如,使用Boost的message_queue)。

EDIT 编辑

Blood , as you requested, here's a little code and a food for thought. ,按照您的要求,这里有一个小的代码和思想食品。 The DLL itself is pretty simple, for example something like this: 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:
        }
}

Now that you have the DLL, you still need to inject it to the desired process. 现在有了DLL,您仍然需要将其注入所需的进程。 This can be easily done with EasyHook API. 使用EasyHook API可以轻松完成此操作。 Download the library and see an example of unmanaged hook. 下载该库,并查看非托管挂钩的示例。

A program can find addresses of its own variables pretty easily ( &variable ). 程序可以很容易地找到其自身变量的地址( &variable )。 If it's cooperating in things, it can then send that to the other program by some normal IPC mechanism. 如果它在事物上协作,则可以通过某种常规IPC机制将其发送到其他程序。 The other program won't (normally) be able to do much with it directly though -- at least on a typical system (*BSD, Linux, Windows, etc.) each process will have memory mapped separately, so an address in one isn't directly usable in another. 但是,另一个程序通常无法直接执行很多操作-至少在典型的系统(* BSD,Linux,Windows等)上,每个进程将分别映射内存,因此一个地址位于一个内存中在另一个环境中不能直接使用。

Nearly all will provide some sort of debugging capability that lets you access one process' memory from another process, but how that works varies widely. 几乎所有人都将提供某种调试功能,使您可以从另一个进程访问一个进程的内存,但是工作方式千差万别。

After you close and reopen a program, the addresses are all randomized. 关闭并重新打开程序后,地址将全部随机化。 There's no way to save an address for the next time you run. 无法保存下次运行的地址。

Instead, you need to design a file structure for whatever data you have. 相反,您需要为任何数据设计文件结构。 Write it to a file, expressing structural relationships somehow other than addresses, and restore pointer-links when reading it back. 将其写入文件,以某种方式表达地址以外的结构关系,并在读回时恢复指针链接。 This is called serialization. 这称为序列化。

In theory, if you understand how the target program working and its internal data structure, you can find the address of the target variable, because each single byte of memory that is dynamically allocated during run time can always be found from some information statically known to code, except variables originated inside a function. 从理论上讲,如果您了解目标程序的工作方式及其内部数据结构,则可以找到目标变量的地址,因为在运行时动态分配的内存的每个单个字节始终可以从静态已知的一些信息中找到。代码,但源自函数内部的变量除外。 However, practically, it's nearly impossible to understand a program by inspecting its binary representation. 但是,实际上,通过检查程序的二进制表示来理解程序几乎是不可能的。 So you are out of luck:-) 所以你不走运:-)

A little more thoughts: 还有一点想法:

let me guess what you are trying to do: you want to stop an integer counting down in another process. 让我猜猜您要做什么:您想在另一个进程中停止倒数。 If that the case, you can manually find the address by a game tool, then set a break point by a debugger to pause when the address is written, then make the break point to happen by different possible operations in the target program. 在这种情况下,您可以通过游戏工具手动找到地址,然后由调试器将断点设置为在写入地址时暂停,然后通过目标程序中的各种可能操作使断点发生。 This way you could identify which code are decreasing the value and possibly modify the EXE/DLL to disable these code. 这样,您可以确定哪些代码正在减小该值,并可能修改EXE / DLL以禁用这些代码。 Chances are the target program will crash more often or does not entertain you any more, for the same code you disabled is used to decrease the energy of you and your opponents:-) 目标程序很有可能会崩溃或不再招待您,因为您禁用的相同代码会减少您和对手的精力:-)

如果您只想一次了解该指针以将其包含在代码中,则可以使用诸如cheatengine之类的程序来获取该指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM