逆向学习笔记(2)-这是代码还是数据
以下的ide为CodeBlocks,编译器采用的GCC,系统为win10 64bit,在不同编译器和环境下汇编代码可能不同
现象
#include <stdio.h>
#include <stdlib.h>
int getmin(int a, int b)
{
if(a>b)
return b;
else
return a;
}
typedef int (*pfunction)(int, int);
int main()
{
int a=456789,b=123789,c=0;
pfunction pGetmin = (pfunction)getmin;
c = pGetmin(a, b);
printf("%d",c);
return 0;
}
上面这段代码是比大小输出小的,typedef int (*pfunction)(int, int);
定义了一个函数指针,但是下面这段代码和上面的功能是完全一样的
#include <stdio.h>
#include <stdlib.h>
typedef int (*pfunction)(int, int);
int main()
{
int a=456789,b=123789,c=0;
unsigned char loc[] =
{
0x55, 0x89, 0xE5, 0x8B, 0x45, 0x08, 0x3B, 0x45, 0x0C, 0x7E, 0x05, 0x8B, 0x45, 0x0C, 0xEB, 0x03, 0x8B, 0x45, 0x08, 0x5D, 0xC3
};
pfunction getmin = (pfunction)&loc;
c = getmin(a, b);
printf("%d",c);
return 0;
}
原因分析
当c = pGetmin(a, b);
调用pGetmin的时候,在汇编中是先call跳到一个地址然后从那个地址再jmp到函数入口地址然后开始执行函数
getmin函数整体汇编为
push ebp
mov ebp,esp
mov eax,DWORD PTR [ebp+0x8]
cmp eax,DWORD PTR [ebp+0xc]
jle <getmin+16>
mov eax,DWORD PTR [ebp+0xc]
jmp <getmin+19>
mov eax,DWORD PTR [ebp+0x8]
pop ebp
ret
通过一些调试程序(发现CodeBlocks带的汇编调试没有vc6好用,看不到硬编码)可以得出这段汇编代码在硬编码中的值为
0x55, 0x89, 0xE5, 0x8B, 0x45, 0x08, 0x3B, 0x45, 0x0C, 0x7E, 0x05, 0x8B, 0x45, 0x0C, 0xEB, 0x03, 0x8B, 0x45, 0x08, 0x5D, 0xC3
这段数据我们在第二个代码中把它存入了一个char类型的数组,它虽然在数据区,但是它还是可以看作可运行的一段函数代码,我们依旧定义一个函数指针指向这个char类型数组的入口地址,达到了和第一种相同的效果
在编程中,我们是把代码和数据分得很开的,但是在逆向和汇编中,这个区别就不明显了,在计算机中都是以数据形式存在的,你可以说它是一串数据,也可以说它是代码
转载请注明出处
本文作者:Akkuman
本文链接:https://www.cnblogs.com/Akkuman/p/6963022.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?