ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Win内核】从TEB到模块遍历

2021-11-01 16:34:35  阅读:258  来源: 互联网

标签:pBase 遍历 LDR Win TEB mov eax ENTRY PLIST


最近逐步接触内核结构,有些感觉就是其实大体的都知道,但一到细节就gg。仔细想想,其实之前学的系统结构都是基于最早的,而当代的计算机结构是经历过n年优化了的结果,所以不能以管窥豹,对于内核的学习更是需要手动去实操。个人觉得可以自己去推导计算机的组件和发展流程,有益于你更深入的理解内核结构的设计,提高思维记忆

通过TEB遍历模块

主要的流程是全局变量-》TEB-》PEB-》LDR-》遍历LDR_ENTRY

  • 我是怎么知道TEB的地址呢?
    其实是3环的时候,FS:[0x18]默认就是存储TEB的指针;而0环的时候存储的数据有区别
#include "stdafx.h"
#include <windows.h>
#include <Ntsecapi.h>    //for unicode_string
typedef struct _PEB_LDR_DATA  
{
	ULONG Length;
	BOOLEAN Initialized;
	PVOID SsHandle; 
	LIST_ENTRY InLoadOrderModuleList;
	LIST_ENTRY InMemoryOrderModuleList;
	LIST_ENTRY InInitializationOrderModuleList; 
	PVOID EntryInProgress;
} PEB_LDR_DATA,*PPEB_LDR_DATA; 





int TebAddress;
int PebAddress;
int Ldr;

void GetAddress(){
	//获取Teb\Peb\Ldr的地址
	__asm{
		mov eax,fs:[0x18]
		mov TebAddress,eax
		mov eax,[eax+0x30]
		mov PebAddress,eax
		mov eax,[eax+0xc]
		mov Ldr,eax
	}
	printf("TebAddress:\t%08X\n",TebAddress);
	printf("PebAddress:\t%08X\n",PebAddress);
	printf("Ldr:\t\t%08X\n",Ldr);
}

void ShowModuleInfo(PLIST_ENTRY pEntry){
    BYTE * pBase = (BYTE *)pEntry;
    PUNICODE_STRING pUnicode = (PUNICODE_STRING)(pBase + sizeof(_LIST_ENTRY) + 
    sizeof(DWORD)* 3 + sizeof(UNICODE_STRING));
    
    printf("DllBase=%p EntryPoint=%p BaseDllName = %ws\n",    
            *(DWORD *)(pBase + sizeof(_LIST_ENTRY)),                        //DllBase
            *(DWORD *)(pBase + sizeof(_LIST_ENTRY) + sizeof(DWORD)),        //EntryPoint
            pUnicode->Buffer);                                                //BaseDllName

	printf("%08x-%08x\n",((PLIST_ENTRY)(pBase-0x10))->Flink,((PLIST_ENTRY)(pBase-0x10))->Blink);
	printf("%08x-%08x\n",((PLIST_ENTRY)(pBase-0x8))->Flink,((PLIST_ENTRY)(pBase-0x8))->Blink);
}

void GetInLoadOrderModuleList(){
	PPEB_LDR_DATA LdrF = (PPEB_LDR_DATA)Ldr;

	PLIST_ENTRY pFirst = LdrF->InInitializationOrderModuleList.Flink;
	PLIST_ENTRY pLast = LdrF->InInitializationOrderModuleList.Blink;

	while(pFirst!=pLast){		
		ShowModuleInfo(pFirst);
		Sleep(2000);
		pFirst = pFirst->Flink;
	}
	
}


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

GetInLoadOrderModuleList();

getchar();
return 0;
}

相关的内核结构你们就自己查吧,正好提高你们的能力。

陷入的坑

最近其实搞这个搞了好久。最开始是想构造一个简单的shellcode,所以一开始就需要能遍历模块。但碍于刚接触,很多内核结构都不熟悉,所以一直没能成功。

主要还是对结构中的双向链表有误解。习惯性以为链表中的指针指向的就是节点的头部,但后面发现都只是指向List_ENTRY结构首部,也就是节点的中间部分。
但我还是有个疑问,这样的话,相当于三个圈,第三个,算了画个图描述下
image

叫我灵魂画师

大概就是这个意思,也就是相当于三个环扣在LDR_DATA上。但我有个疑问,既然是一个链,为什么每个节点都有三个链孔,按道理一个不就已经足够了

M猜想

  • 猜想1:其他两个仅是结构需求,不用
    本来以为其他两个孔都是0,仅是因为结构设计,但好像又没那么简单。其他的两个链孔有值
    image
  • 猜想2:难不成这是个套娃?下一个节点其实也有三个环???
    想想就头大,以后再搞。

如果有师傅会的,欢迎交流。

标签:pBase,遍历,LDR,Win,TEB,mov,eax,ENTRY,PLIST
来源: https://www.cnblogs.com/Aurora-M/p/15494296.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有