Re_加密与解密

迟迟没有学习的加密与解密,现在开始吧

基础篇

一、Win API简介

API(Application Programming Interface)应用程序编程接口。在早期,windows的主要部分只需要三个动态链接库中实现,这代表了windows三个主要子系统——Kernel,User和GDI.
Kernel:操作系统的核心功能服务,包括进程与线程控制,内存管理,文件访问等。
User:负责处理用户接口,包括键盘和鼠标输入,窗口和菜单管理等。
GDI:图形设备接口,允许程序在屏幕上和打印机上显示文本和图像。

二、常用的Win32 API函数

1、GetWindowText函数

此函数在USER32.DLL用户模块中,它的作用是取得一个窗体的标题文字,或者一个文本控件的内容。
函数原型:

1
2
3
4
5
int GetWindowText(
HWND hwnd, //窗口或文本控件句柄
LPTSTR lpString, //缓冲区地址
int nMaxCount //复制的最大字符数
)

返回值:如果成功就返回文本长度,失败就返回零。
ANSI版是GetWindowTextA,Unicode版是GetWindowTextW.

2、GetDlgItem函数

此函数在USER32.DLL用户模块中,它的作用是获取制定对话框的句柄。
函数原型:

1
2
3
4
HWND GetDlgItem(
HWND hDlg, //对话框句柄
int nIDDlgItem //控件标识
)

返回值:如果成功就返回对话框句柄,失败就返回零。

3、GetDlgItemText函数

此函数在USER32.DLL用户模块中,它的作用是获取对话框的文本。
函数原型:

1
2
3
4
5
6
UINT GetDlgItemText(
HWND hDlg, //对话框句柄
int nIDDlgItem, //控件标识(ID号)
LPTSTR lpString, //缓冲区地址
int nMaxCount //复制的最大字符数
)

返回值:如果成功就返回文本长度,失败就返回零。
ANSI版是GetDlgItemTextA,Unicode版是GetDlgItemTextW.

4、GetDlgItemInt函数

此函数在USER32.DLL用户模块中,它的作用是获取对话框的整数。
函数原型:

1
2
3
4
5
6
UINT GetDlgItemInt(
HWND hDlg, //对话框句柄
int nIDDlgItem, //控件标识(ID号)
BOOL *lpTranslated, //接收成功/失败指示的指针
BOOL bSigned //指定为有符号还是无符号
)

返回值:如果成功就返回文本长度,失败就返回零。
ANSI版是GetDlgItemIntA,Unicode版是GetDlgItemIntW.

5、MessageBox函数

此函数在USER32.DLL用户模块中,创建和显示信息框
函数原型:

1
2
3
4
5
6
UINT MessageBox(
HWND hWnd, //父窗口句柄
LPTSTR lpText, //消息框文本地址
LPTSTR lpCaption, //消息框标题地址
UINT uType //复制的最大字符数
)

返回值:如果成功就返回文本长度,失败就返回零。
ANSI版是MessageBoxA,Unicode版是MessageBoxW.

三、什么是句柄

句柄(Handle)在Windows中使用非常频繁,它是Windows标识,由应用程序建立或使用的对象所使用的一个唯一的整数值(通常32位)。程序通过调用Windows函数获取句柄,然后在其他Window函数中使用这个句柄,以引用它代表的的对象。句柄的实际值对程序来说无关紧要。

四、Windows消息机制

Windows是一个消息(Message)驱动式系统,Windows消息提供应用程序与应用程序,应用程序与Windows系统之间进行通信的手段。应用程序想要实现的 功能由消息来触发,并且靠对消息的响应和处理来完成。
Windows系统中有两种消息列队:一种是系统消息列队,另一种是应用程序消息列队。计算机的所有输入设备由Windows监控。当一个事件发生时,Windwos先将输入的消息放入系统消息队列中,再将输入的消息拷贝到相应的程序队列中,应用程序中的消息循环从它的消息队列中检索每个消息并且发给相应的窗口函数中。总是按到达的先后排队(一些系统消息除外),这就使得一些外部实时事件可能得不到及时的处理。

1、SendMessage函数

调用一个窗口的窗口函数,将一条消息发给那个窗口。除非消息处理完毕,否则该函数不会返回。
函数原型:

1
2
3
4
5
6
LRESULT SendMessage(
HWND hWnd, //目的窗口的句柄
UINT Msg, //消息标识符
WPARAM wParam, //消息的WPARAM域
LPARAM lParam //消息的LPARAM域
)

返回值:由具体的消息决定,如消息投递成功,返回TURE(非零)

2、WM_COMMAND消息

当用户从菜单或按钮中选择一条命令或者一个控件发给它的父窗口,或者当一个快捷键被释放时发送。
函数原型:

1
2
3
4
5
WM_COMMAND
wNotifyCode = HIWORD(wParam);//通告代码
wID = LOWORD(wParam) //菜单条目,控件标识符
hwndCtl = (HWND) lParam, //控件句柄
)

返回值:系统处理这条消息,返回零

五、虚拟内存

虚拟内存(Virtual Memory)不是真正的内存,他通过映射(Map)的方法,使可使用的虚拟地址(Virtual Address)达到4GB。
简单地说,虚拟内存的实现方法和过程如下:

(1)当一个应用程序被启动时,操作系统就创建一个新进程,并给每个进程分配2GB的虚拟地址(不是内存,是地址)
(2)虚拟内存管理器将应用程序的代码映射到那个程序代码的物理地址中的某个位置,并把当前所需要的代码读取到物理地址中(虚拟地址和应用程序代码在的物理内存中的位置是没有关系的)
(3)如果使用动态链接库DLL,DLL也被映射到进程的虚拟地址的空间,在需要的时候才被读入物理内存
(4)其它项目(例如数据,堆栈等)的空间是从物理内存中分配的,并被映射到虚拟空间中
(5)应用程序通过使用它的虚拟地址空间中的地址开始执行,然后虚拟内存管理器每次把内存的内存访问映射到物理位置
如果上面步骤不能理解,那明白以下几点就可以了:
1、应用程序不会直接访问物理地址
2、虚拟内存管理器通过虚拟地址的访问请求,控制所有的物理地址访问
3、每个应用程序都有互相独立的4GB寻址空间,不同应用程序的地址空间是隔离的
4、DLL程序没有自己”私有”空间,它们总是被映射打其它应用程序的地址空间。

使用虚拟内存的好处是:简化内存的管理,并可弥补物理内存的不足,可以防止多任务环境下各个应用程序之间的冲突。

六、简单介绍PE

Windows的可执行文件(EXE,DLL)是PE(Portable Executable)格式。PE文件使用的一个平面地址空间 ,所有的数据都被合并在一起,组成一个很大的结构。文件的内容被分割成不同的区块(Section,又称区段,节等),块中包含代码和数据。每一个块都有他自己在内存中的一套属性(可读,可写等)。
每一个区块都有不同的名字,这个名字表示区块代码的功能。常见的区块有.text,.rdata,.data,.rsrc等
.text:是在编译或汇编结束时产生的一种块,它的内容全是指令代码
.rdata:是运行期只读数据
.data:是初始化的数据块
.idata:包含其它外来DLL的函数技巧数据,即输入表。
.rsrc:包含模块的全部资源,如图标,菜单,位图等。
PE文件非常好的一个地方就是在磁盘上的数据与内存中的结构图是一致的。

PE相关的名词解释如下:
(1)入口点(Entry Point)
PE文件执行时的入口点。也就是程序在执行时的第一行代码的地址应该是就这个值。
(2)文件偏移地址(File Offset)
当PE文件存储在磁盘上时,各数据的地址称做文件偏移地址 ,文件偏移地址从PE文件的第一个字节开始计数,起始值是0
(3)虚拟地址(Virtual Address,VA)
由于Windows程序运行在386保护模式下,所以程序访问存储器所使用的逻辑地址称为虚拟地址VA,又称为内存偏移地址。
(4)基地址(ImageBase)
文件执行时将被映射到指定的地址中,这个初始化内存地址称为基地址,这个值是由PE文件本身设定的。
(5)相对虚拟地址(Relative Virual Address,RVA)
表示此段代码在内存中相对于基地址的偏移,即:
相对虚拟地址(RVA)=虚拟地址(VA)-基址(ImageBase)

Donate
-------------本文结束感谢您的阅读-------------