C++、Cheat Engine / OllyDBG 从多级指针查找基“静态”地址

2024-03-13

我又回来了,沮丧并拼命寻求帮助:D。

我正在尝试为一个简单的程序创建一个作弊程序,它基本上是一个 .dll 文件,当使用其基地址注入主程序时,它将更改主程序中的整数值。问题是,我无法使用作弊引擎找到它,主要是因为有多个带有负数的级别指针?偏移量。例如:

//Starting pointer address
0x0033FCF0 -> 200

//Finding second level pointer using "Find out what's accessing this address" in Cheat Engine
**(mov eax,[ebp+08])** // **EAX=0x00000007** , **EPB=0x0033FCE8 => mov 00000007,[0033FCE8+08]**

2nd Level Pointer:
**(0033FCE8+18) -> 200**

因此,我继续使用“找出是什么......”来查找下一个指针,但是在使用带有二级指针地址的 T-SEARCH 时,我得到了 7 - 8 个新的静态地址。

问题是,我无法判断哪一个是正确的,因为作弊引擎拒绝让我使用负数添加指针?抵消。

Example:

Base Pointer:
**mov eax,[epb-18] !!!** // Notice the **MINUS**

最重要的是,作弊引擎拒绝接受带有负偏移量的指针!


我认为你误解了作弊引擎的目标。

CE 允许您修改以持久方式存储在内存中的值。例如,在堆上,或者在程序的静态数据中。

例如,C++ 对象以确定性方式分配,因此它们永远不会移动。这就是为什么它们可以通过在对象的整个生命周期中保持不变的指针来引用。该对象有时由另一个对象拥有。如果你找到一个指向所有者对象的指针,你就找到了所谓的基指针.

例如 :

class Object
{
    bool dummy;
    int someField;
    Object* child;
};

现在假设你有一棵包含 3 个元素的嵌套树Object。意味着你有根Object(n°1),其child是另一个Object(n°2),其child是另一个Object(n°3)。想象一下你做了这样的事情:

int main(int argc, char** argv)
{
    Object root; // n°1
    root.child = new Object(); // n°2
    root.child->child = new Object(); // n°3

    return 0;
}

你有兴趣搞乱 n°3someField价值。你知道地址someField,相对于Object, is of +sizeof(bool) = 1. So (void*)&(object n°3) + 1是一个指向someField你要。

现在,如何找到指向对象 n°3 的指针? 知道相对地址child is +sizeof(bool)+sizeof(int) = 5。我们知道指向对象 n°3 的指针是(void*)&(object n°2) + 5.

对象 n°2 的地址也是如此,我将其作为练习。

但是对象 n°1 呢?它没有分配在堆上。它在堆栈上。废话。所以我们必须找到另一种方法来找到对象n°1存储的地址。

局部变量存储在堆栈中。在汇编中,它们通过相对于寄存器的偏移量来识别EBP (or ESP如果函数不改变堆栈)。EBP是堆栈的顶部,而ESP是堆栈的底部。

在这个例子中:

function foo()
{
    int a;
    double b;
}

当调用 foo 时,堆栈将增加刚好足以容纳 a 和 b,即 sizeof(int) + sizeof(double),即 12 个字节。 a 将存储在EBP - sizeof(int) = EBP - 4(与...一样ESP + 8) 和 b 将被存储在EBP - sizeof(int) - sizeof(double) = EBP - 12(与...一样ESP). 注意力!编译器可以更改此顺序,因此变量的声明顺序在内存中不一定相同。优化也可以彻底改变这一点。但让我们保持简单好吗?

回到我们的主要例子。我们有哪些局部变量?仅根。因此根将位于EBP - 9直接地。但这仅当 main 是调用堆栈顶部的函数时才有效。没有调试器,你就无法做到这一点。

让我们假设我们的EBP当 main 被调用时(取自新编译的 C 程序),值为 0028FF28。

根位于 (0x0028FF28 - 9) = 0x0028FF1F; 指向的指针root.child位于 (0x0028FF1F + 5) = (0x0028FF24); 所以,root.child位于*0x0028FF24。

指向的指针root.child->child位于 (*0x0028FF24 + 5) = (假设 10000) 然后root.child->child为 *10000。

最后,root.child->child.someField为 *10000 + 3。

总结一下:你只需要找到root的静态地址即可找到其余的。 root 不在堆或任何类型的持久内存上,但它在 main 的堆栈上,该堆栈几乎在整个程序中持续存在,因此它几乎就像是永久的。 CE通过扫描整个进程内存空间帮助您找到静态地址

考虑到所有这些,您应该能够计算hp的相对地址在堆栈上并找到一个指向它的静态指针(main 非常非常非常有可能在每次启动程序时都有一个静态帧地址)。如果您需要帮助,请使用调试器!我推荐免疫调试器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++、Cheat Engine / OllyDBG 从多级指针查找基“静态”地址 的相关文章

  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐