![]() |
1
7
如果是我,我会使用符号表,例如“NMA.OUT GREP MAIN”。得到你想要的任何函数的真实地址。 如果你真的没有符号表,那就自己做吧。
搜索这个名字,地址会立即指向它。转到地址。;-) |
![]() |
2
3
如果编译器具有内联asm,则可以使用它创建模式。编写一些nop指令,这些指令可以通过内存转储中的操作码轻松识别:
|
![]() |
3
1
数字常量放在代码段中,编码在函数的指令中。所以你可以试着用一些神奇的数字,比如0千牛肉等等。 这里是用VisualC++编写的简单C函数的拆卸视图:
您可以看到0xDeadBeef使其成为函数的源代码。请注意,您在可执行文件中实际看到的内容取决于CPU的结尾(tx.richard)。 这是一个x86示例。但是RISC CPU(MIPS等)有指令将即时数据移动到寄存器中——这些即时数据也可以有特殊的可识别值(尽管MIPS、IIRC只有16位)。 psihodelia-越来越难理解你的意图。它只是一个你想找到的函数吗?那你就不能一个接一个地放5个nop去寻找它们吗?您是否控制编译器/汇编程序/链接器/加载程序?你可以使用什么工具? |
![]() |
4
1
正如您所指出的,这:
…将在堆栈中设置指向包含字符串的数据段的指针。然而,这:
……可能会将所有这些字节放在堆栈中,这样您就能够识别代码中的字符串(我刚刚在我的平台上尝试过)。 希望这有帮助 |
![]() |
5
1
对于您真正的问题,使用一种完全不同的方法,即查找特定的代码块:使用diff。 用包含问题函数的代码编译一次,用注释掉一次。生成两者的RAM转储。然后,对这两个转储进行比较,以查看更改了什么——这将是新的代码块。(您可能需要对转储进行某种类型的处理,以删除内存地址,以便获得干净的差异,但在这两种情况下,指令的顺序都应该相同。) |
![]() |
6
1
为什么不让每个函数转储自己的地址呢?像这样:
通过将fnaddr_设为静态,每个函数执行一次转储。显然,您需要调整fnaddr()以支持系统上的任何输出或日志记录。不幸的是,如果系统执行延迟初始化,您将只获得实际调用的函数的地址(这可能足够好)。 |
![]() |
7
0
可以通过调用同一个伪函数来启动每个函数,例如: void identify函数(无符号int标识符) { } 每个函数都将使用不同的参数(1、2、3,…)调用IdentifyFunction函数。这不会给您一个神奇的映射文件,但是当您检查代码转储时,您应该能够快速找到Identify函数的位置,因为会有很多跳转到该地址的操作。下一步扫描这些跳转,并在跳转之前检查以查看传递了什么参数。然后您可以创建自己的映射文件。对于某些脚本,这应该是相当自动的。 |
![]() |
Ilya Loskutov · 无法将单词加载到寄存器中 2 年前 |
![]() |
Ari157 · x86_64 Linux程序集中的逻辑与实现 2 年前 |
![]() |
Arya · 汇编语言中的“标签”——操作码 2 年前 |
![]() |
S1mple · 通过gcc生成64位共享库时的“未定义的主引用” 2 年前 |
![]() |
R0M2 · 为什么“GCC”忽略汇编代码的-fno pic 2 年前 |
![]() |
Akagi Akira · 如何在gnu汇编程序中组装MIPS cpu 2 年前 |