我正在学习逆向工程的基础.在扭转裂缝的同时,在几乎所有功能的开头都看到了这种模式:
pushl %ebp
movl %esp, %ebp
pushl %ebx # because ebx is a callee-saved register
subl $0x14,%esp # of course $0x14 changes depending on the function
calll 0x08048766
addl $0x1a5f, %ebx # also this value sometime changes depending on the function
Run Code Online (Sandbox Code Playgroud)
哪里0x08048766有一个函数可以做到这一点:
movl 0(%esp), %ebx
retl
Run Code Online (Sandbox Code Playgroud)
所以基本上,正常情况下,每个函数首先初始化寄存器ebp和esp.然后寄存器ebx被推入堆栈,这也是完全可以理解的,因为ebx是被调用者保存的寄存器,稍后在函数中使用它来引用一些静态数据(来自.rodata),例如:
leal -0x17b7(%ebx), %eax
movl %eax, 0(%esp)
calll printf
Run Code Online (Sandbox Code Playgroud)
现在最有趣的(对我而言)部分:如果我已经正确理解,ebx首先用指向的值初始化esp(这使用函数at 0x08048766),为什么?里面有什么?这不是一个未初始化的点到堆栈中吗?
然后添加另一个值ebx.这个值代表什么?
我想更好地理解ebx在这种情况下如何使用寄存器,以及如何计算它指向的地址. …
正如手册所说,函数SDL_PollEvent"如果有待处理事件则返回1,如果没有可用则返回0".,这就是为什么我们使用的测试SDL_PollEvent(&e)!=0(如果e是SDL_Event).
但是,使用这个测试!SDL_PollEvent(&e)怎么样?它应该工作,但显然它会导致一些问题.
这是一个代码示例:
#include <SDL2/SDL.h>
#include <stdio.h>
int main(int argc, char* args[]){
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("Hello",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 100, 100, SDL_WINDOW_SHOWN);
SDL_Event e;
int quit=0;
while(!quit){
//Here the test
while (!SDL_PollEvent(&e)){
if (e.type==SDL_QUIT)
quit=1;
else if ( e.type == SDL_KEYDOWN )
printf( "Hello\n" );
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个代码应该做的是打开一个新窗口,并在每次按下一个键时在控制台中打印"Hello".这段代码可以很好地测试,SDL_PollEvent(&e)!=0但是SDL_KEYDOWN当我使用测试时它不会读取事件!SDL_PollEvent(&e)(但它会在while中输入并处理SDL_QUIT事件而没有任何问题).
为什么会这样?
该函数fopen("file-name",a);将返回一个指向文件末尾的指针。如果文件存在,则打开它,否则创建一个新文件。
是否可以使用附加模式并仅在文件已存在时打开文件?(否则返回 NULL 指针)。
提前致谢