汪道之

有人的地方就有江湖

0%

病毒_Win_虚拟地址

OllyDebug简介

Windows下用户级调试神器——OllyDebug,简称OD

OD是强大的动态追踪工具,具有可视化操作界面,但是非常占内存

基本功能

  1. 启动一个程序调试
  2. Attach到一个已经运行的程序调试
  3. 单步,step into and step over
  4. 断点
  5. 继续运行
  6. 查看内存
  7. 修改内存
  8. 查看寄存器
  9. 修改寄存器
  10. 代码窗体跳到指定地址
  11. 修改指令
  12. 查看一个进程加载的dll
  13. 查看dll中有哪些函数
  14. 查找内存中的某个值

动态链接库DLL

DLL(Dynamic Link Libraries)使得更新和重用程序更加方便

  1. 是程序的一部分,作为模块被进程加载到自己的空间地址
  2. 在编译时不会插入可执行文件中,在运行时整个库的代码才会调入内存,这就是所谓的“动态链接”

一些重要的动态链接库:

Windows中有几个非常重要的底层DLL:Kernel32.dll、User32.dll、GDI32.dll、ntdll.dll

  1. Kernel32.dll顾名思义就是内核相关的功能,主要包含用于管理内存、进程和线程的函数
  2. User32.dll中包含的则是用于执行用户界面的函数,比如把用户的鼠标点击操作传递给窗口,以便窗口根据用户的点击来执行预定的事件
  3. GDI32.dll的名称用了缩写,全称是Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函数,比如要显示一个程序窗口,就调用了其中的函数来画这个窗口
  4. ntdll.dll是Windows系统从ring3到ring0的入口。位于Kernel32.dll和user32.dll中的所有win32 API最终都是调用ntdll.dll中的函数实现的

Windows内存管理和程序加载

保护模式内存管理

  1. DOS的内存管理是实模式,我们可以随意改动甚至系统的内存(比如修改中断向量表)
  2. Windows是工作在x86的保护模式。每个进程都有自己独立的线性地址空间(0-4GB,32位CPU的寻址能力是2^32=4GB),互不干扰,这4GB空间会按某个固定大小(如4KB)分成N个页
  3. 同时,内存又分为用户空间和内核空间,用户空间代码无法直接访问内核空间
  4. 其能防止应用程序非法访问其他应用程序的地址空间(任务间保护),防止应用程序非法访问操作系统地址空间(系统保护)

一个小实验

在cmd中编译以下代码,编译命令gcc a.c -o b.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int gi;
void usage(){
printf("please input s to set gi or d to dispaly gi\n");
}

void main(int argCount, char ** args){
if (argCount != 2) {
usage();
return;
}
if (args[1][0] == 's') {
gi = 12;
printf("gi = %d\n", gi);
printf("&gi = %d\n",&gi);
getchar(); //进程持续挂起
}
else if (args[1][0] == 'd') {
printf("gi = %d\n", gi);
printf("&gi = %d\n",&gi);
}
else usage();
}

然后运行,会发现两个进程的值不同,但地址空间却相同!

image-20210512200247086

这说明,我们看到的是“虚假”的内存地址

原因分析

在Windows系统下,处于保护模式,我们看见的内存地址是逻辑地址,并非真正的物理地址

在DOS系统下,处于实模式,我们看见的内存地址就是真实的物理地址

同一逻辑地址的值对应不同物理上内存地址正是保护模式的能力

image-20210512200650502

image-20210512200751672

转换过程

32位虚拟地址分成3部分

  1. CR3寄存器给出页目录地址
  2. 前面10位用于在页目录中查找页表地址
  3. 中间10位用于在页表中查找页表项
  4. 后面12位给出相对页表项地址的偏移

image-20210512201221862