levels 发布的文章

exe,dll,sys,com为主流可执行文件格式(pe格式)
32位pe32 64位pe32+
winnt.h有pe详细定义
pe含程序运行时所有info

layout:

ms-dos header
nt header
section header
section 实体

MS-DOS Header

DOS MZ Header
DOS STUB

IMAGE NT HEADERS

Signature
IMAGE FILE HEADERS
IMAGE
_OPTIONAL HEADERS
IMAGE DATA DIRECTORY(array lists)

Section Table

IMAGE SECTION HEADER
......
IMAGE SECTION HEADER

Sections

SECTION
SECTION
......
SECTION

实现LoadLibrary(系统默认给的pe格式),PE文件加载到内存中经过四步

  1. 要判定输入文件是否是PE格式;
  2. 要将PE文件分块按照内存映像结构放在内存中;
  3. 在IAT(Import Address Table)中,填入其依赖的导入函数地址
  4. 利用重定位表修复需要重定位的值。

PE文件加载,首先要检查的是该文件是否为PE格式,还需要检查该PE文件是否为DLL。
◎ PE的检测,需要检查的部分是MS-DOS头和NT头
◎ DLL的检测(只针对dll),检查NT头中的IMAGE_FILE_HEADER.

MS-DOS头
◎ MS-DOS头是微软为了考虑PE文件对DOS文件的兼容性而添加的。
• 大多数情况下由编译器自动生成,通常把
DOS MZ头与DOS stub合称为DOS文件头
◎ IMAGE_DOS_HEADER结构体如下图

IMAGE DOS HEADER结构体共64字节,其中两个字段比较重要,分别是e_magic
e_lfanew.

byte 1字节 word 2字节 double word 4字节

e_magic: 4D5A=>MZ 代表DOS signature
e_lfanew: NT offset address

Signature字段必须被设置为0x00004550

其中Machine,NumberOfSections,SizeOfOptionalHeader, Characteristics如果出现错误,将导致该PE文件无法正常执行。

0#1 Machine
◎该字段说明了可执行文件的目标CPU类型。
常见的一些Machine码
Machine Value
Inteli386 14Ch
MIPS R3000 162h
MIPS R4000 166h
Alpha AXP 184h
Power PC 1F0h

2 NumberOfSections

◎该字段说明了在这个PE文件中节区(Section)的数目。

3 TimeDateStamp

◎该字段说明了该PE文件是何时被创建的。

4 PointerToSymbolTable

◎该字段说明了COFF符号表(基本用不到)的文件偏移位置。COFF符号表在PE文件中较为少见,通常其值为0

SizeOfOptionalHeader
对于32位文件,该字段通常为0x00E0
对于64位文件,该字段通常为0x00F0

Magic
当IMAGE_ OPTIONAL_HEADER为
IMAGE_OPTIONAL_HEADER32(32位)时,Magic
0x10B。当其为IMAGE_OPTIONAL_HEADER64时,
Magic)70x20B.

AddressOfEntryPoint
该字段的值相对虚拟地址(加载到内存的地址),该值表明了程序最先执行的代码的启始地址,即程序入口点。

ImageBase
该字段表明了PE文件被加载进内存时,文件将被优先装入的虚拟内存的地址。对于EXE来说,ImageBase通常为0x00400000;对于DLL来说,ImageBase通常为0x10000000。装载后,EIP = ImageBase+
AddressOfEntryPoint.

SectionAlignment,FileAlignment
PE文件的Body部分划分为若干节区,FileAlignment制定了节区在文件系统中的最小单位,SectionAlignment则指定了节区在内存中的最小单位。
磁盘文件或内存的节区大小必定为FileAlignment或SectionAlignment的整数倍。

SizeOflmage
加载PE文件时,SizeOflmage指定了PE Image在虚拟内存中所占的空间大小。

SizeOfHeaders
该字段表明了整个PE文件头部的大小,该值必须是FileAlignment的整数倍。

Subsystem
该字段用于区分系统驱动文件与普通可执行文件。

NumberOfRvaAndSizes
该字段表明了下面出现的DataDirectory数组的个数。一般来说该值为16。

DataDirectory
DataDirectory是有IMAGE_DATA_DIRECTORY结构体构成的数组,数组的每项都有不同的意义。

RVA&VA(OS referance:ostep)
relative virtual address
virtual address(va)

va=image base + rva

PE文件在存储时为了减少体积,FileAlignment通常小于SectionAlignment。
当文件被映射到内存中后,同一数据在文件中的偏移量与在内存中的偏移量是不一样的,这样就存在这从文件偏移地址(RAW)到相对虚拟地址(RVA)之间的转换。
如果需要对存储在硬盘中的PE文件进行操作,需要将RVA换为RAW。

2024-04-25T02:48:39.png
对这个对话框进行功能分析,当我们输入用户名和密码后,系统有可能会调用GetDlgItemText()函数(常用于获取对话框控件的内容信息)获取Text里面的信息。

系统调用GetDlgItemText()函数至少2次,第1次获取用户名;第2次获取序列号。获取到用户名和序列号后,他可能会把输入的序列号和真正的序列号(也可能会比较用户名和序列号两个参数)进行比较(常用lstrcmp,代表long类型的string compare,即long类型字符串比较函数),相同则弹出成功对话框;不相同则弹出失败对话框。

2024-04-25T02:50:43.png

options-->debugging options,选events选项卡,选择WinMain(或EP),这样每次加载就会直接到WinMain函数,按Ctrl+F2重新加载程序。
2024-04-25T02:51:19.png

2024-04-25T02:52:55.png

2024-04-25T02:55:17.png

2024-04-25T02:57:39.png
Alt+C返回到CPU窗口,在命令行输入bp GetDlgItemTextA,按Alt+B确认断点有效
2024-04-25T02:58:11.png

2024-04-25T03:00:00.png

2024-04-25T03:00:28.png

2024-04-25T03:00:56.png

2024-04-25T03:02:53.png

2024-04-25T03:04:18.png

2024-04-25T03:12:10.png

2024-04-25T03:28:05.png

2024-04-25T03:30:29.png

2024-04-25T03:32:35.png

2024-04-25T03:41:39.png

2024-04-25T03:44:58.png
就是看一看真正的序列号是多少。还记得我们之前并没有跟进的一个函数lstrcmpA吗?我们重新加载程序,再次跟进到这个函数。
2024-04-25T03:55:00.png

2021-2022-2自编实验(训)指导书《软件安全与逆向分.doc

source code:

include "stdafx.h" //

int global = 50; //定义一个全局变量;
int PlusFunction(int x,int y) //定义一个返回值为int类型函数
//函数名PlusFunction,函数有两个int类型参数的函数;
{

int a = 10;                          //定义两个函数局部变量;
int b = 20;
return x+y+a+b+global;                   //函数返回值

}
int main(int argc, char* argv[])
{

int result = PlusFunction(30,40);             //函数调用
printf("%d\n",result);                  //按格式打印result
return 0;   //程序结束

}

1.png

2.png

3.png

4.png

5.png

6.png

7.png

8.png

9.png