灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:3072回复:0

逆向基础知识

楼主#
更多 发布于:2011-12-16 18:00


整理By LengF   来自于《加密解密第三版》
1.字符存储顺序
这是多字节数据存储需要考虑的一个问题,实际情况是跟cpu有关,微机处理有正序(Big-Endian)和逆序(Little-Endian)之分,我们常见的是逆序存储,只有少数特殊的RISC架构的CPU使用正序,如IBM的Power-PC,两者区别如下:
Big-Endian:高字节存储低地址,低位字节存入高地址
Little-Endian:刚好相反,低位字节存入低地址,高位字节存入高地址
举个例子,比如十六进制数12345678h写入到1000h开始的内存中,两种不同存储结构如下:
 数 据       地 址                          数  据      地  址
+-----------+                                                            +-----------+
+  12H   +   -->  1000H                                          +  78H   +   -->  1000H
+-----------+                                                            +-----------+
+  34H   +   -->  1001H                                          +  56H   +   -->  1001H
+-----------+                                                            +-----------+
+  56H   +   -->  1002H                                          +  34H   +   -->  1002H
+-----------+                                                            +-----------+
+  78H   +   -->  1003H                                          +  12H   +   -->  1003H
+-----------+                                                            +-----------+
+  其他+   -->  1004H                                          +  其他+   -->  1004H
    Big-Endian                                                               Little-Endian

2.ASCII和Unicode字符集
ASCII是美国信息交换标准码简称,是一个7位编码标准,即2的7次方等于128字符集。而ANSI是扩展的ASCII编码,即8位二进制表示,可以表示256字符。
同时Unicode也是ASCII字符编码的一个扩展,在window中用2个字节进行编码,也称为宽字节编码,原来7位的ASCII编码也被扩充到16位,高位补零
3.Window系统基础常识
经常我们听到说Win32编程,是在编程过程中使用32位版本的Windows系统API函数,早期还有16位的API,在Win32中兼容所有16位的API。但是需要注意的在有些平台工作方式是不同的。
比如,在window NT/2000/xp中,Win15的API函数通过调用一个转换函数转换为Win32函数调用,然后被操作系统处理,而在Window9x中则刚好相反。
window的核心动态链接库DLL
Kernel:操作系统核心功能,包括进程和线程控制、内存管理、文件访问等
User:负责处理用户接口,包括键盘鼠标、窗口和菜单管理
GDI:图形接口,打印功能,显示等
编程常识:
API函数是区分字符集的,一般我们调用的函数其实在原始定义中是没有的,而是通过系统判断去调用不同的字符集的函数,比如我们在c语言经常使用MessageBox函数,这个函数在User32.dll中是找不到入口点的,但是存在两个函数MessageBoxA和MessageBoxW,主要区别在于,前者采用的是ANSI编码,而后者采用unicode(也称为宽字节)。了解这些对于破解有很好的帮助,因为我们经常会用到,比如破解注册码的程序,当用户输入注册码后,程序会获取用户输入的信息,那么他在系统中的实现就是通过调用类似于GetWindowText或者GetDlgItem等函数方式,因此我们可以对这些函数进行断点后继续分析,可以有效提高破解速度。
Unicode于ANSI之间字符转换操作是WideCharToMutiByte函数和MutiByteToWideChar函数。

由于现在我们比较常用的是Win32,所以你必须知道,在NT架构下,Win32的API可以接受Unicode和ASCII两种编码的字符集,但是在内核中只能使用Unicode,因此如果使用ANSI的程序都将需要一步字符集的转换,也因此程序会暂用更多的内存和CPU资源,得出一个结论,在Win32下使用unicode编程是一个明智的选择。

Window的消息机制
Windows是一个消息驱动式的系统,我们在学习MFC的时候对于这个理解非常的重要。有两种消息队列:系统消息队列和应用程序消息队列。那么过程又是如何?举个例子:当一个事件发生时,window先将输入的消息放入到系统消息队列中,再将输入的消息拷贝到相应的应用程序队列中,应用程序中的消息循环从给他消息队列中检索每个消息并且发送相应的窗口函数,消息队列处理方式是采用先来先处理的队列机制。在Window消息处理中有个比较重要的SendMessage函数,该函数会登陆消息处理完毕才返回。

Window的保护机制
80x86系列的CPU能够在实模式、保护模式和虚拟86模式下运行。并且在Win32中寄存器从16位扩展到32位,同时增加了一些新的寄存器。当前的Window系统都是工作在保护模式下。为什么呢?因为如果使用实模式只能利用32位寄存器中的前16位后面的16位就浪费了,这种也叫MS-DOS的运行环境。了解window保护机制对于我们逆向学习也是比较重要,因为在不同的模式下,存在不同的CPU寻址方式。在保护模式下,内存是线性的,段寄存器的意义比较特殊,它里面存放不是段基地址,而是存放段选择子,是不直接参与选址的,他只是一个全局描述符表(GDT)或者本地描述符表(LDT)的一个指针,不同段寄存器的读写权限也是不一样的。在Win32中,每个进程都赋予了4gB的独立虚拟空间,范围位00000000h~FFFFFFFFh,此时程序代码和数据都放在同一个地址空间,就不必区分代码段和数据段了。
虚拟地址:(VM)
虚拟地址不是真正的内存,他通过映射MAP的方法,使可用的虚拟地址达到4GB,其中应用程序只能暂用2GB,剩下2GB系统暂用,在Window NT中可能应用程序可以暂用达到3GB。在物理内存中,操作系统和DLL代码都会被映射,而与应用程序无关的不会被映射,但是必须明白,用户的EXE程序只在自己的CPU时间片中才会被映射,而用户自定义的DLL则是选择性被映射。

简单总结以上几点:
(1)应用程序是不会直接访问物理地址的
(2)虚拟内存管理器通过虚拟地址的访问请求,控制所有的物理地址访问
(3)每个应用程序都由相互独立的4GB寻址空间,不同应用程序的地址空间是隔离的
(4)DLL没有自己的私有空间,他们总是被映射到其他应用程序的地址空间中
4.PE结构基础概念
(1)入口点:可执行程序执行时的入口点,通俗一点就是,程序在执行时第一行代码的地址
(2)文件偏移地址:当PE存储在磁盘上,各数据的地址,从第一个字节开始计数,起始值位0
(3)虚拟地址(VA):上面说过Window程序运行在保护模式下,采用是虚拟地址,即程序访问存储器所使用的逻辑地址,也称为内存偏移地址
(4)基地址:文件被执行时映射到指定内存地址中的初始内存地址
以上这些信息可以借助PEid来查看或者LoadPE

喜欢0 评分0
游客

返回顶部