Reverse零碎知识与经验记录(持续更新)

  这篇文章记录我在学习reverse时学到的琐碎的知识与经验,如有错误请斧正。

零碎的知识点

  1. Win32应用程序中,API函数的参数是通过栈传递的。
  2. 可执行文件保存字符串时一般会给字符串多留出一些空间。
  3. 应用程序被加载到内存时有一个最小的内存分配大小,一般为1000。即使程序运行时只占有100内存,它被加载到内存时仍然会分到1000左右的内存,这些内存一部分会被程序占用,其余部分为空域部分,全部被填充为NULL。
  4. 网络协议中通常采用大端序方式,Intel x86 CPU采用小端序方式。
  5. 编写Windows汇编程序时,Win32 API函数在内部会使用ECX与EDX,调用这些API时,ECX与EDX的值就会改变。所以,ECX与EDX中保存有重要数据时,调用API前要先把这些数据备份到其他寄存器或栈。
  6. Windows中使用的是段内存模型,使用时需要指出相关内存属于哪一个区段。
  7. cdecl是主要在C语言中使用的方式,调用者负责处理栈;stdcall方式常用于Win32 API,被调用者负责清理栈。尽管Win32 API是使用C语言编写的库,但它使用stdcall方式而不是C语言默认的cdecl方式是为了获得更好的兼容性,使C语言之外的其它语言也能调用API。
    cdecl方式的好处在于,它可以像C语言的printf()函数一样,向被调用函数传递长度可变的参数。这种长度可变的参数在其他调用约定中很难实现;stdcall方式的好处在于被调用者函数内部存在着栈清理代码,与cdecl方式相比代码尺寸要小。
    C语言也可以使用stdcall方式编译源码,只要使用_stdcall关键字即可。
#include

int _stdcall function(int a, int b)
{
	return a + b;
}

int main()
{
	return add(1, 2);
}
  1. 32位WindowsOS中,各进程分配有4GB的虚拟内存,因此进程中VA值的范围是00000000~FFFFFFFF。
  2. PE文件加载到内存时,文件不会原封不动地加载,而要根据节区头中定义的节区起始地址、节区大小等加载。因此,磁盘文件中的PE与内存中的PE具有不同的形态。
  3. IAT提供的机制与隐式链接有关。
  4. 去除二进制可执行文件符号是指从二进制文件中删除符号。编译过程会在二进制目标文件中留下符号。在创建最终的可执行文件或二进制文件时,其中一些符号用于在链接过程中解析文件之间的引用关系。其他情况下,符号用于提供与所使用的调试器有关的其他信息。链接过程完成后,许多符号就没用了。在构建时,传递给链接器的选项可帮助链接器删除不必要的符号。此外,一个名为strip的实用工具也可以用于删除现有二进制文件中的符号。虽然去除符号后的二进制文件比未去除符号的二进制文件要小,但去除符号后的二进制文件的功能依然保持不变。
  5. 幻数是一些文件格式规范所要求的特殊标签值,它表示文件符合这种规范。比如Java的.class文件的幻数为十六进制数0xcafebabe,MS-DOS的可执行文件头中的标签时MZ。
  6. 可变长字符串对象会根据需要在内部随时动态分配/释放内存,因此,每次运行时字符串的地址会有所不同。此外,调试时也无法一眼看全实际字符串,这也是调试的困难之一。
  7. 共享库可能会使用导出序数,以方便用户通过序数而非名称访问函数。使用序数可以加快地址查询速度,并允许程序员隐藏函数的名称。Windows DLL即使用导出序数。

经验

  1. 在逆向工程中,绝对不要完全相信任何工具所提供的结果,除非该结果得到其他几款工具和手动分析的确认,这是一个良好的习惯。
  2. 调试前先预测代码的实现,这是个好习惯。若预测有误也没关系,从头开始调试即可。但若是有幸预测正确,则可以节省大量调试时间。

你可能感兴趣的:(编程随笔,安全,逆向工程)