最近逐步接触内核结构,有些感觉就是其实大体的都知道,但一到细节就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结构首部,也就是节点的中间部分。
但我还是有个疑问,这样的话,相当于三个圈,第三个,算了画个图描述下
叫我灵魂画师
大概就是这个意思,也就是相当于三个环扣在LDR_DATA上。但我有个疑问,既然是一个链,为什么每个节点都有三个链孔,按道理一个不就已经足够了
M猜想
- 猜想1:其他两个仅是结构需求,不用
本来以为其他两个孔都是0,仅是因为结构设计,但好像又没那么简单。其他的两个链孔有值
- 猜想2:难不成这是个套娃?下一个节点其实也有三个环???
想想就头大,以后再搞。
如果有师傅会的,欢迎交流。