多字节存储顺序
大端
小端
Windows操作系统
WindowsAPI
动态链接库 DLL
kernel32.dll:控制着系统的内存管理、数据的输入输出操作和中断处理,当windows启动时,kernel32.dll就驻留在内存中特定的写保护区域。
user32.dll:windows用户界面相关程序接口,包括windows处理,基本用户界面等属性,创建窗口和发送消息等
gdi32.dll:是windows GDI图形用户界面相关程序,包含的函数用来绘制图像和显示文字
GetWindowText函数
//The GetWindowText function copies the text of the specified window's title bar (if it has one) into a buffer. If the specified window is a control, the text of the control is copied. However, GetWindowText cannot retrieve the text of a control in another application.
int GetWindowText(
HWND hWnd, // handle to window or control
LPTSTR lpString, // text buffer
int nMaxCount // maximum number of characters to copy
);
HWND GetDlgItem函数
//The GetDlgItem function retrieves a handle to a control in the specified dialog box.
HWND GetDlgItem(
HWND hDlg, // handle to dialog box
int nIDDlgItem // control identifier
);
UINT GetDlgItemText函数
//The GetDlgItemText function retrieves the title or text associated with a control in a dialog box.
UINT GetDlgItemText(
HWND hDlg, // handle to dialog box
int nIDDlgItem, // control identifier
LPTSTR lpString, // pointer to buffer for text
int nMaxCount // maximum size of string
);
int MessageBOx
//The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, plus any combination of predefined icons and push buttons.
int MessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
句柄
一个句柄是唯一的一个整数值,用于标识应用程序中的不同对象和同类对象的不同的实例
例如:一个窗口、按钮、图表、滚动条、输出设备、控件或文件等,应用程序能够通过句柄访问相应的对象的信息。
windows具体的运行机制
windows NT/2000/XP 与Unicode
NT架构将Unicode字符集作为标准
MessageBox(L"aaa");
#define WINAPI __stdcall //windows 用的 退出时 子程序平衡栈
#define WINAPIV __cdecl // C语言用的 退出时 调用者平衡栈
匈牙利命名法
许多 Windows 程序员都使用“匈牙利标记法”作为变量命名约定。这是为了纪念具有传奇色彩的微软程序员 Charles Simonyi。
这种标记法非常简单,即变量名以一个或者多个小写字母开始,这些字母表示变量的数据型态。例如:szCmdLine 中的 sz 代表“以0结尾的字符串(StringZero)”;在 hInstance 和 hPrevInstance 中的 h 前缀表示“句柄(Handle)”;在 iCmdShow 中的 i 前缀表示“整型(Integer)”。
当命名结构变量时,可以用结构名(或者结构名的一种缩写)的小写形式作为变量名称的前缀,或者用作整个变量名。例如:msg 变量是 MSG 型态的结构;wndclass 是 WNDCLASSEX 型态的一个结构;ps 是一个 PAINTSTRUCT 结构,rect 是一个 RECT 结构。
匈牙利表示法能够帮助程序写作者及早发现并避免程序中的错误。由于变量名既描述了变量的作用,又描述了其数据型态,就比较容易避免产生数据型态不合的错误。
前缀 | 数据类型 |
---|---|
c | char 或 WCHAR 或 TCHAR |
by | BYTE (无符号字符) |
n | short(短整型) |
i | int(整型) |
x, y | int,表示 x 坐标和 y 坐标 |
cx, cy | int,表示 x 或 y 的长度,c 表示“count”(计数) |
B 或 f | BOOL(int);f 表示“flag” |
w | WORD(无符号短整型) |
l | LONG(长整型) |
dw | DWORD(无符号长整型) |
fn | 函数 |
s | 字符串 |
sz | 以零结束的字符串 |
h | 句柄 |
p | 指针 |
回调函数
CALLBACK 开头的函数
#define CALLBACK __stdcall
windows 调用,不用我们自己调用
windows消息机制
windows系统有两种消息队列
- 系统消息队列 只有一个
- 应用程序消息队列 每个进程一个
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//分配消息
}
MSG结构
typedef struct tagMSG {
HWND hwnd; //Handle to the window whose window procedure receives the message
UINT message; //消息的类型
WPARAM wParam; //消息的第一个参数
LPARAM lParam; //消息的第二个参数
DWORD time; //发送消息的时间
POINT pt; //发送消息时鼠标所在的位置
} MSG, *PMSG;
SendMessage函数
WM_COMMAND
WM_GETTEXT
WM_QUIT
WM_LBUTTONDOWN
WM_RBUTTONUP
WM_KEYUP
windows保护模式
实模式、保护模式和虚拟8086方式
实模式
80x86系列使用CS寄存器和IP寄存器来通知CPU指令放在内存中的位置
段地址+偏移地址 = 20位 物理地址
CS:代码段
DS:数据段
8086以前(8bit)->8086(16bit)->80386(32bit)->现在的64bitCPU
寄存器AL->AX->EAX->RAX
保护模式
和实模式改变的主要是寻址的方式,起到保护作用
一、不同任务之间的保护:通过把每个不同的任务放在不同的虚拟地址空间中,来实现不同任务之间的隔离,以达到程序间的隔离
二、同一任务的保护:在每一个任务之内定义了4中保护级别。分别为0、1、2、3环。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O4KrgxYP-1610116983079)(E:\IT学习\加密与解密\assets\基础知识篇.assets\image-20210108151350882.png)]
其中,0级代表最高的权限级别,3级代表最低的权限级。
0,1,2属于系统级,3环属于用户级
一般的系统只使用0环和3环这两个级别。
操作系统的核心层是运行在Ring 0级,而win32子系统(如Kernel32.dll、User32.dll、GDI32.dlll)都是运行在Ring 3级,以提供与子程序的接口
虚拟内存
虚拟内存并不是真正的内存,它是通过映射
(Map)的方法,使可用的虚拟地址(VA)达到4GB(因为EIP32位索引的最大范围是4GB)。
PC是非intel厂家对IP的称呼,也就是说PC起始跟CS:IP是一回事儿。
PE
PE的意思就是Portable Executable(可移植的执行体)。它是Windows环境自身所带的执行体文件格式。
它的一些特性继承自Unix的Coff(common object file format)文件格式。
“portable executable”(可移植的执行体)意味着此文件格式是跨win32平台的:也就是说即使Windows运行在非Intel的CPU上,任何win32平台的PE装载器都能识别和使用该文件格式。
基本上所有win32执行体(除了VxD和16位的D11)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode drivers)。因而研究PE文件格式给了我们洞悉Windows结构的良机。
PE文件结构
PE文件使用的是一个平面地址空间,所有代码和数据都合并在一起,组成一个很大的结构。
文件的内容被分割为不同的区块(Section,又称为区段,节等),块中包含代码或数据。每个区块都有自己在内存中的属性,即读/写。 每个区块都有不同的名字。
常见区块的名字含义
.text | 是在编译或汇编结束时产生的一种块,它的内容全是指令代码 |
---|---|
.rdata | 是运行期只读数据 |
.data | 是初始化的数据块 |
.idata | 包含其他外来DLL的函数及数据信息,即输入表 |
.rsrc | 包含模块的全部资源:如图表、菜单、位图等 |
PE文件的优势
PE文件非常好的一个地方就是在磁盘上的数据结构与在内存中的结构是一致的。
当系统装载一个可执行文件到内存中,主要就是将一个PE文件的某一部分映射到地址空间中。这样,PE文件的数据结构在磁盘和内存中就是一样的了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UbnfZ6jc-1610116983092)(E:\IT学习\加密与解密\assets\基础知识篇.assets\image-20210108155221485.png)]
PE相关名词
OEP 原始入口点 Original Entry Pint
File Offset 文件偏移地址
VA Virtual Address 虚拟地址
与实模式下的“段地址:偏移地址” 类似,虚拟地址也写成“段:偏移量”的形式
不同之处在于,此处的段是指段选择子
如: “0123:0040100”
0123:表示段选择子,其数据存储在CS段选择器里面,同一程序在不同系统环境下,此值可能不同
00401000:此处表示内存中的虚拟地址,一般来说,同一个程序的同一条指令在不同系统环境下,此值相同(PE映射原理)。
基地址(ImageBase)
文件执行时将被映射到指定内存地址中,这个初始内存地址称为基地址。这个值是由PE文件本身设定的。
按照默认设置·用VisualC++建立的EXE文件基地址是00400000h DLL文件基地址是10000000h 但是,这个值可以自己在编译器设定的。
:0040100”
0123:表示段选择子,其数据存储在CS段选择器里面,同一程序在不同系统环境下,此值可能不同
00401000:此处表示内存中的虚拟地址,一般来说,同一个程序的同一条指令在不同系统环境下,此值相同(PE映射原理)。
基地址(ImageBase)
文件执行时将被映射到指定内存地址中,这个初始内存地址称为基地址。这个值是由PE文件本身设定的。
按照默认设置·用VisualC++建立的EXE文件基地址是00400000h DLL文件基地址是10000000h 但是,这个值可以自己在编译器设定的。
Load PE :强大的PE编辑工具