我正在学习OllyDbg中的汇编程序和调试技巧,以学习如何使用未记录的函数.现在我遇到以下问题:
我有以下代码部分(来自OllyDbg):
MOV EDI,EDI
PUSH EBP
MOV EBP,ESP
MOV EAX, DWORD PTR SS:[EBP+8]
XOR EDX,EDX
LEA ECX, DWORD PTR DS:[EAX+4]
MOV DWORD PTR DS:[EAX], EDX
MOV DWORD PTR DS:[ECX+4],ECX
MOV DWORD PTR DS:[ECX],ECX
MOV DWORD PTR DS:[EAX+C],ECX
MOV ECX, DWORD PTR SS:[EBP+C]
Run Code Online (Sandbox Code Playgroud)
这是函数的开始,目标是查找数据结构.所以我发现它首先将EBP推入堆栈,然后将ESP(当前堆栈指针)移动到EBP,我认为它现在定义了该函数的堆栈帧.现在教程说在流行的布局中,第一个参数位于[EBP + 8],第二个参数位于[EBP + C]
这是我不明白的.我怎么知道第一个参数放在EBP + 8?
希望有人可以帮助我!谢谢!
我想知道在堆栈框架中推送函数的返回值是否有意义.
我知道返回值主要存储在寄存器中(ecc用于gcc),但它仅用于性能吗?
谢谢!
我是装配新手,然后我遇到了这篇文章
它说这个代码
void MyFunction()
{
int a, b, c;
a = 10;
b = 5;
c = 2;
Run Code Online (Sandbox Code Playgroud)
相当于此
push ebp ; save the value of ebp
mov ebp, esp ; ebp now points to the top of the stack
sub esp, 12 ; space allocated on the stack for the local variables
mov [ebp - 4], 10 ; location of variable a
mov [ebp - 8], 5 ; location of b
mov [ebp - 12], 2 ; location …Run Code Online (Sandbox Code Playgroud) 在Andrei Alexandrescu的"D编程语言"中,
这是一个将委托作为模板参数的示例:
T[] find(alias pred, T)(T[] input)
if(is(typeof(pred(input[0])) == bool))
{
for(; input.length > 0; input = input[1 .. $]) {
if (pred(input[0])) break;
}
return input;
}
unittest {
int[] a = [1,2,3,4,-5,3,-4];
int z = -2;
auto b = find!(delegate(x) { return x < z; })(a);
asssert(b == a[4..$]);
}
Run Code Online (Sandbox Code Playgroud)
Alexandrescu解释说这是有效的,因为委托实际上是一个胖指针,由两部分组成:函数指针和指向其堆栈框架的指针(这就是为什么z可以在其体内访问).除了find将"pred"作为TEMPLATE参数,而不是作为参数.模板参数只能是编译时常量.
我确定单元测试中匿名委托的地址确实是一个编译时常量,但它的堆栈帧的地址当然不应该,所以如何将委托作为模板参数?
这里到底发生了什么?
在C中编写一个可移植函数(没有汇编),返回其堆栈帧的大小
int stackframe_size()
{
}
Run Code Online (Sandbox Code Playgroud)
尝试解决它如下所示 - 使用VS 2010编译时,此函数返回228个字节.有没有办法验证其正确性?
int stackframe_size(int run)
{
int i ;
if(!run)
{
return ((int)(&i) - stackframe_size(++run));
}
return (int)(&i);
}
Run Code Online (Sandbox Code Playgroud)
调用为:
int main()
{
printf("\nSize of stackframe_size() is: %d bytes",stackframe_size(0)) ;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我在 ASM 框架的帮助下创建 Java 字节码检测工具,需要确定并可能更改方法的局部变量的类型。很快我遇到了一个简单的情况,其中变量和堆栈映射节点看起来有些奇怪,并且没有提供有关正在使用的变量的足够信息:
public static void test() {
List l = new ArrayList();
for (Object i : l) {
int a = (int)i;
}
}
Run Code Online (Sandbox Code Playgroud)
给出以下字节码(来自 Idea):
public static test()V
L0
LINENUMBER 42 L0
NEW java/util/ArrayList
DUP
INVOKESPECIAL java/util/ArrayList.<init> ()V
ASTORE 0
L1
LINENUMBER 43 L1
ALOAD 0
INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator;
ASTORE 1
L2
FRAME APPEND [java/util/List java/util/Iterator]
ALOAD 1
INVOKEINTERFACE java/util/Iterator.hasNext ()Z
IFEQ L3
ALOAD 1
INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;
ASTORE 2
L4
LINENUMBER 44 L4
ALOAD 2 …Run Code Online (Sandbox Code Playgroud) 你好我想弄清楚是怎么工作的.stackalloc所以C/C++来自我的知识(有限)你不能动态地在堆栈上分配内存,就像在这里:
C/C++ 例:
void Allocate(int length){
int vector[length]; //wont work
}
Run Code Online (Sandbox Code Playgroud)
然后C#进入游戏,您可以这样做stackalloc:
void Allocate(int length){
int []vector=stackalloc int [length];
}
Run Code Online (Sandbox Code Playgroud)
是不是分配在stack知道compile-time或者precompile-time(macros等)数组的大小有什么分配?C#如何管理这个"magic"?如何创建堆栈框架?
我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp 。此外,我正在使用 SBCL、Emacs 和 Slime。
在第 10 章结束时,作者讨论了有用的 break 函数。为了提供背景上下文,他提出了这个有问题的函数:
(defun analyze-profit (price commission-rate)
(let* ((commission (* price commission-rate))
(result
(cond ((> commission 100) 'rich)
((< commission 100) 'poor))))
(format t "~&I predict you will be: ~S"
result)
result))
Run Code Online (Sandbox Code Playgroud)
该函数按预期工作,在 REPL 中使用以下参数调用:
> (analyze-profit 1600 0.15)
I predict you will be: RICH
RICH
> (analyze-profit 3100 0.02)
I predict you will be: POOR
POOR
Run Code Online (Sandbox Code Playgroud)
但是,当commission正好是 100时,它会显示错误的结果:
> (analyze-profit 2000 0.05)
I predict you …Run Code Online (Sandbox Code Playgroud) 我正在重构一个 C++ 应用程序,它引用了一堆多个回调函数,每个回调函数都有不同数量的参数,我想知道在调用每个函数之前是否有一种通用的方法来构建专用的参数堆栈框架。
换句话说:首先根据要调用的函数获取所有必需的参数,然后执行对被调用函数透明的调用。
在某种程度上,这与可变参数函数相反,因为这将是一个知道它可以接收不同数量参数的单个函数。在这里,我有一堆不可变的常规函数,我想从通用集线器调用它们。
我把C和C++标签都放在这里是因为我对这两种语言的命题都很感兴趣,我觉得适用于 C 的东西也适用于 C++,我仍然对“仅限 C++”的解决方案持开放态度,例如可变参数模板等。
所有这一切的背景是引用的程序实际上是在解析命令行,然后根据命令的名称调用函数,作为程序名称后的第一个参数传递,然后所有必需的作为纯字符串,但取决于调用的命令.
我知道我可以写这样的东西:
if(nb_of_args == 1)
my_callback_ptr(argv[n]);
else if (nb_of_args == 2)
my_callback_ptr(argv[n],argv[n+1]);
else if (nb_of_args == 3)
my_callback_ptr(argv[n],argv[n+1],argv[n+2]);
else if (nb_of_args == 4)
my_callback_ptr(argv[n],argv[n+1],argv[n+2],argv[n+3]);
else if…
Run Code Online (Sandbox Code Playgroud)
...无论函数本身如何,将编译调用限制为唯一数量的参数,但我仍然希望做得更好。
在此先感谢大家。
CSAPP 解释说,SSE 指令对 16 字节数据块进行操作,并且需要内存地址是 16 的倍数。
但是和栈帧有什么关系呢?这是否意味着SSE指令在堆栈帧上运行?如果有的话,常用的指令是什么?