段选择器FS与TEB

  • WinNT内核下内存采用保护模式,段寄存器的意义与实模式汇编下的意义不同.另外,FS存的是段选择子,而不是实模式下的高16位基地址。

  • FS寄存器指向当前活动线程的TEB结构(线程结构)

  • 下面为FS寄存器下偏移的相关信息:

    偏移 说明

    000h 指向SEH链指针

    004h 线程堆栈顶部

    008h 线程堆栈底部

    00Ch SubSystemTib

    010h FiberData

    014h ArbitraryUserPointer

    018h FS段寄存器在内存中的镜像地址

    020h 进程PID

    024h 线程ID

    02Ch 指向线程局部存储指针

    030h PEB结构地址(进程结构)

    034h 上个错误号

PEB

详细参考https://blog.csdn.net/weixin_44156885/article/details/100729365

  • 使用汇编获取PEB地址的两种方法:

    方法1:
    MOV	EAX,DWORD PTR FS:[30]    ;FS:[30] = address of PEB

    方法2:

    MOV	EAX,DWORD PTR FS:[18]    ;FS[18] = address of TEB
    MOV EAX,DWORD PTR DS:[EAX+30] ;DS[EAX+30] = address of PEB
  • PEB几个重要成员
+002	BeingDebugged 	;Uchar(可用于反调试技术)
...
+008 ImageBaseAddress ;Ptr32 Void
...
+00c Ldr ;Ptr32 _PEB_LDR_DATA(可用于反调试技术)
...
+018 ProcessHeap ;Ptr32 Void(可用于反调试技术)
...
+068 NtGlobalFlag ;uint4B(可用于反调试技术)
PEB.Ldr
  • PEB.Ldr成员是指向_PEB_LDR_DATA结构体的指针,_PEB_LDR_DATA结构体如下。

    +000 Length                         :Uint4B
    +004 Initialized :UChar
    +008 SsHandle :Ptr32 Void
    +00c InLoadOrderModulelist :_LIST_ENTRY
    +014 InMemoryOrderModulelist :_LIST_ENTRY
    +01c InInitializationOrderModulelist:_LIST_ENTRY
    +024 EntryInProgress :Ptr32 Void
    +028 ShutdownInProgress :UChar
    +02c ShutdownThreadId :Ptr32 Void
  • 当模块(DLL)加载到进程后,通过PEB.Ldr成员可以直接获得该模块的加载基址,_PEB_LDR_DATA结构体中含有3个_LIST_ENTRY类型的成员,_LIST_ENTRY结构体如下。

    typedef struct LIST_ENTRY{
    struct _LIST_ENTRY *Flink;
    struct _LIST_ENTRY *Bink;
    }LIST_ENTRY,*PLIST_ENTRY;
  • 从上述结构体可以看出,_LIST_ENTRY结构体提供双向链表机制。链表中保存的是_LDR_DATA_TABLE_ENTRY结构体的信息

  • 每个加载到进程中的DLL模块都对应一个_LDR_DATA_TABLE_ENTRY结构体,这些结构体相互链接,最终形成了_LIST_ENTRY双向链表。_PEB_LDR_DATA结构体中存在3种_LIST_ENTRY双向链表,也就是说,存在多个_LDR_DATA_TABLE_ENTRY结构体,并且有三种链接方法可以将它们链接起来。

    结构体如下:


typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
_ACTIVATION_CONTEXT * EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
  • 模块初始化链表 InInitializationOrderModuleList 中按顺序存放着 PE 装入运行时初始化模块的信息

正文

  • 所有 win_32 程序都会加载 ntdll.dll 和 kernel32.dll 这两个最基础的动态链接库。如果想要在 win_32 平台下定位 kernel32.dll 中的 API 地址,可以采用如下方法:

(1)首先通过段选择字 FS 在内存中找到当前的线程环境块 TEB。

(2)线程环境块偏移位置为 0x30 的地方存放着指向进程环境块 PEB 的指针。

(3)进程环境块中偏移位置为 0x0C 的地方存放着指向 PEB_LDR_DATA 结构体的指针,

其中,存放着已经被进程装载的动态链接库的信息。

(4)PEB_LDR_DATA 结构体偏移位置为 0x1C 的地方存放着指向模块初始化链表的头指

针 InInitializationOrderModuleList。

(5)模块初始化链表 InInitializationOrderModuleList 中按顺序存放着 PE 装入运行时初始化

模块的信息,第一个链表结点是 ntdll.dll,第二个链表结点就是 kernel32.dll。

(6)找到属于 kernel32.dll 的结点后,在其基础上再偏移 0x08 就是 kernel32.dll 在内存中的

加载基地址。

(7)从 kernel32.dll 的加载基址算起,偏移 0x3C 的地方就是其 PE 头。

(8)PE 头偏移 0x78 的地方存放着指向函数导出表的指针。

(9)至此,我们可以按如下方式在函数导出表中算出所需函数的入口地址

- 如下图所示:

  • 导出表偏移 0x1C 处的指针指向存储导出函数偏移地址(RVA)的列表。
  • 导出表偏移 0x20 处的指针指向存储导出函数函数名的列表。
  • 函数的 RVA 地址和名字按照顺序存放在上述两个列表中,我们可以在名称列表中定位到所需的函数是第几个,然后在地址列表中找到对应的 RVA。
  • 获得 RVA 后,再加上前边已经得到的动态链接库的加载基址,就获得了所需 API 此刻在内存中的虚拟地址,这个地址就是我们最终在 shellcode 中调用时需要的地址。
  • 按照上面的方法,我们已经可以获得 kernel32.dll 中的任意函数
  • 类似地,我们已经具备了定位 ws2_32.dll 中的 winsock 函数来编写一个能够获得远程 shell 的真正的 shellcode 了。
  • 在摸透了 kernel32.dll 中的所有导出函数之后,结合使用其中的两个函数 LoadLibrary()和 GetProcAddress(),有时可以让定位所需其他 API 的工作变得更加容易。

本文参考:0day安全,以及众多博客

0day学习笔记(3)Windows定位API引起的惨案(原理)的更多相关文章

  1. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  2. 并发编程学习笔记(6)----公平锁和ReentrantReadWriteLock使用及原理

    (一)公平锁 1.什么是公平锁? 公平锁指的是在某个线程释放锁之后,等待的线程获取锁的策略是以请求获取锁的时间为标准的,即使先请求获取锁的线程先拿到锁. 2.在java中的实现? 在java的并发包中 ...

  3. DOCKER 学习笔记6 WINDOWS版尝鲜

    前言 经过前两节的学习,我们已经可以在Dokcer 环境下部署基本的主流环境有: Springboot 后端 MYSQL 持久化数据 以及Nginx 作为反向代理 虽说服务器上面的也没啥不好,但是毕竟 ...

  4. redis学习笔记(一)——windows下redis的安装与配置

    前言 很久没有写东西了(.......我的水平就是记个笔记),北漂实习的我,每天晚上回来都不想动,但是做为社会主义接班人的我,还是要时刻给自己充充电,趁着年轻,趁着日渐脱发的脑袋还没有成为" ...

  5. Python学习笔记 for windows

    学习来源 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001374738136 ...

  6. spring学习笔记---第三方SDK(Rest API)和Jaskson的巧用

    前言: 其实我以前一直不懂电商, 以及电商中所涉及的业务概念. 对于SKU等名词, 觉得有些玄乎. 对其背后的数据模型, 也有莫名的未知恐惧感: 庞大而理不清头绪. 不过最近有机会接触了微商(有赞), ...

  7. 操作系统学习笔记(三) windows内存管理

    //系统物理页面是由 (Page Frame Number Database )简称PFN数据库来进行管理,实际上是一个数组,每个物理页面都对应一个PFN项. 进程的地址空间是通过VAD(Virtua ...

  8. Appium学习笔记4_元素定位方法

    Appium之元素定位,如果对Android上如何使用工具获取页面元素有问题的,请转战到这:http://www.cnblogs.com/taoSir/p/4816382.html. 下面主要是针对自 ...

  9. Django框架学习笔记(windows环境下安装)

    博主最近开始学习主流框架django 网上大部分的安装环境都linux的 由于博主在windows环境下已经有了 Pycharm编辑器 ,所以决定还是继续在windows环境下学习 首先是下载 链接 ...

随机推荐

  1. idea打包或编译错误,错误为c盘idea路径某些文件被占用(非idea文件,项目生成的文件)

    方法列表(2的效果可能更好) 1.将被占用的文件删除之后,重新打包或编译. 2.多编译几次项目. 3.发现真正可能的原因.(貌似被南航企业版360拦截了,导致targe或maven等文件被占用问题) ...

  2. Scala学习系列(一)——Scala为什么是大数据第一高薪语言

    为什么是Scala 虽然在大数据领域Java的使用更普及,Python也有后来居上的势头,但Scala一直有着不可动摇的地位.我们熟悉的Spark,Kafka,Flink都是由Scala完成了其核心代 ...

  3. Light of future-冲刺Day 6

    目录 1.SCRUM部分: 每个成员进度 SCRUM 会议的照片 签入记录 代码运行截图 用户浏览界面 订单详情界面 管理员浏览界面 新增后台界面 2.PM 报告: 时间表 燃尽图 任务总量变化曲线 ...

  4. Springboot项目中 前端展示本地图片

    Springboot项目中 前端展示本地图片 本文使用的是Springboot官方推荐的thymeleaf(一种页面模板技术) 首先在pom文件加依赖 <dependency> <g ...

  5. 微信小程序animation有趣的自定义动画

    这几天在看代码时遇到了一些问题:关于微信小程序的animation自定义动画自己没有系统的学习过 做动画需要我们将一个复杂的动作过程,拆解为一步一步的小节过程 微信中已经为我们写好了端口我们只需要实例 ...

  6. 原生JS实现Ajax的跨域请求

    原生JS如何实现Ajax的跨域请求? 在解决这个问题之前,我们务必先清楚为什么我们要跨域请求,以及在什么情况下会跨域请求. 了解一下:“同源策略”,你就知道了: 同源策略限制从一个源加载的文档或脚本如 ...

  7. Linux网络基础,路由的追踪

    一.traceroute traceroute [-46ndFT] [-f<存活数值>] [-g<网关>] [-i(--interface)<device>] [- ...

  8. Mac 系统root

    没错,你没看错,就是root mac系统安装件的时候,你有没有遇到过这种情况 总之,就是安装不上软件,肿么办? 网上解觉办法是: 进入系统偏好设置,设置为允许任何人,可是进去后这样: 别着急,打开命令 ...

  9. 从JDK源码学习HashSet和HashTable

    HashSet Java中的集合(Collection)有三类,一类是List,一类是Queue,再有一类就是Set. 前两个集合内的元素是有序的,元素可以重复:最后一个集合内的元素无序,但元素不可重 ...

  10. 操作文件-取出一个60s内log日志中ip访问次数超过100次的ip

    import timea=0while True: d={} f = open(r"/Users/**juan/Downloads/access.log",encoding=&qu ...