|

提醒:若下载的软件是收费的"请不要付款",可能是骗子,请立即联系本站举报,执意要付款被骗后本站概不负责。(任何交易请走第三方中介,请勿直接付款交易以免被骗!切记).
本帖最后由 Super Man 于 2015-2-6 22:33 编辑
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
*/ ,y%4QvG7a
f79bd4f8 c745f400000000 mov dword ptr [ebp-0Ch],0 //局部变量清0
ULONG i=0; //计数
InitializeListHead(&link_head); //链表地址初始化
f79bd4ff 8d45e8 lea eax,[ebp-18h] 获得指针
LIST_ENTRY link_head;链表
InitializeListHead( S(nZ]QEG
__out PLIST_ENTRY ListHead
ListHead->Flink = ListHead->Blink = ListHead; //指针都是相同的
} *RpBKm&^7
ZwCreateFile!InitializeListHead: 6%nKrK
f79c95f0 8bff mov edi,edi
f79c95f2 55 push ebp
f79c95f3 8bec mov ebp,esp
f79c95f5 8b4508 mov eax,dword ptr [ebp+8] 获得一个ListHead结构地址 地址
// ss:0010:f78eec40=f78eec48
f79c95f8 8b4d08 mov ecx,dword ptr [ebp+8]//同样
f79c95fb 894804 mov dword ptr [eax+4],ecx
//ff78eec48 +4 也就是ListHead->Blink = ListHead
f79c95fe 8b5508 mov edx,dword ptr [ebp+8]
f79c9601 8b4508 mov eax,dword ptr [ebp+8]
f79c9604 8902 mov dword ptr [edx],eax
ListHead->Flink = ListHead
f79c9606 5d pop ebp
主要 listhead->Flink和Blink都是指针类型的
清0
7a234ff 8d45e8 lea eax,[ebp-18h] ;获得链表结构变量指针
/*typedef struct _LIST_ENTRY
struct _LIST_ENTRY *Flink; //指向下一个双链表结构的指针
struct _LIST_ENTRY *Blink; //指向前一个双链表结构的指针
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
*/
f7a23502 50 push eax
f7a23503 e8e8000000 call ZwCreateFile!InitializeListHead
push 链表结构指针。
调用InitializeListHead函数
走进去看看
(注意这是堆栈信息)
[链表结构地址]
ChildEBP RetAddr Args to Child
f78e6c38 f7a29508 f78e6c48//双链表指针 e10f8352 00000000 ZwCreateFile!InitializeListHead
InitializeListHead函数源代码
/*wdm.h*/
FORCEINLINE
VOID
InitializeListHead(
__out PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
从函数源代码来看,这个函数的作用,就是把传进来的双链表结构变量的Flink成员和Blink成员都指向自己,这样一个初始化的动作
Disassembly Code:
f7a235f0 8bff mov edi,edi
f7a235f2 55 push ebp
f7a235f3 8bec mov ebp,esp ;ebp为堆栈指针
;f7a295f5 8b4508 mov eax,dword ptr [ebp+8] ;得到传进来的参数内容也就是传进来的_LIST_ENTRY结构的地址 ss:0010:f78e6c40=f78e6c48
f7a235f8 8b4d08 mov ecx,dword ptr [ebp+8]
;同上
f7a295fb 894804 mov dword ptr [eax+4],ecx ;ds:0023:f78e6c4c=f78e6c60 ;因为blink是 一个_LIST_ENTRY *类型,所以eax+4这个地址存放的是指针,需要进一步通过指针地址里面存;放的值
;来得到,结构的地址
; Listhead->Blink = ListHead; Blink= 0xf78e6c60(注意,结构地址和上边) [ 0xf78e6c84 - 0xf7a29f9e ] struct _LIST_ENTRY *
f7a235fe 8b5508 mov edx,dword ptr [ebp+8];还是得到传进来参数的内容;
f7a23601 8b4508 mov eax,dword ptr [ebp+8]
;同上
f7a29604 8902 mov dword ptr [edx],eax ds:0023:f78e6c48=00000000;
;ListHead->Flink = ListHead; 给Flink成员赋值,内容是指向本结构的地址
f7a23606 5d pop ebp ;....
f7a23607 c20400 ret 4 ;平衡堆栈
pData = (PMYDATASTRUCT)ExAllocatePool(PagedPool,sizeof (MYDATASTRUCT));//分配内存,
pData->number = i;
InsertHeadList(&link_head,&pData->List_Entry);
f7a3554c 8945f8 mov dword ptr [ebp-8],eax ;返回ExAllocatePool分配的内存地址
f7a3554f 8b45f8 mov eax,dword ptr [ebp-8] ; pData
f7a35552 8b4df4 mov ecx,dword ptr [ebp-0Ch]; i
f7a35555 8908 mov dword ptr [eax],ecx; [eax]== pData->number 的值 , 也就是pData->number = i
f7a35557 8b55f8 mov edx,dword ptr [ebp-8] ; pdata
f7a3555a 83c204 add edx,4 ;pData+4
/*
typedef struct _MYDATASTRUCT
{
ULONG number;
LIST_ENTRY List_Entry;//链表结构
}MYDATASTRUCT,*PMYDATASTRUCT;
*/
地址 +0x4偏移 就是链表结构的地址
f7a3555d 52 push edx ; pData->List_Entry入栈
f7a3555e 8d45e8 lea eax,[ebp-18h] &link_head
f7a35561 50 push eax; &link_head
f7a35562 e809010000 call ZwCreateFile!InsertHeadList
InsertHeadList函数源代码(wdm.h)
FORCEINLINE
VOID
InsertHeadList(
__inout PLIST_ENTRY ListHead,
__inout __drv_aliasesMem PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;//得到下一个_LIST_ENTRY结构指针
Entry->Flink = Flink; // Entry->Flink = Next ListHead
Entry->Blink = ListHead; //Blink = ListHead
Flink->Blink = Entry; //Next ListHead ->Blink = pData->Entry
ListHead->Flink = Entry; // ListHead->Flink = pData->Entry
}
Entry.Flink--> Next_List_Head->Flink
Entry.Blink --> ListHead;
Next_List_Head->Blink =Entry
ListHead->Flink = Entry
f7a35670 8bff mov edi,edi
f7a35672 55 push ebp
f7a35673 8bec mov ebp,esp
f7a35675 51 push ecx
f7a35676 8b4508 mov eax,dword ptr [ebp+8] ;link_head结构变量的地址
f7a35679 8b08 mov ecx,dword ptr [eax] ;取Flink成员的值
f7a3567b 894dfc mov dword ptr [ebp-4],ecx ;存入到PLIST_ENTRY结构变量 Flink中...
f7a3567e 8b550c mov edx,dword ptr [ebp+0Ch]; pData->List_Entry变量的地址
f7a35681 8b45fc mov eax,dword ptr [ebp-4] ss:0010:f78eec30=f78eec48 ;pData->List_Entry = Entry->Flink = Flink = ListHead->Flink
f7a35684 8902 mov dword ptr [edx],eax ;pData->List_Entry = Entry->Flink = ListHead->Flink
f7a35686 8b4d0c mov ecx,dword ptr [ebp+0Ch] ss:0010:f78eec40=e15bd9fc ;得到Entry的地址
f7a35689 8b5508 mov edx,dword ptr [ebp+8] ;listhead
f7a3568c 895104 mov dword ptr [ecx+4],edx ds:0023:e15bda00=00000000 ; Entry-blink = listhead
f7a3568f 8b45fc mov eax,dword ptr [ebp-4] ;Flink
f7a35692 8b4d0c mov ecx,dword ptr [ebp+0Ch] ; Entry
f7a35695 894804 mov dword ptr [eax+4],ecx ds:0023:f78eec4c=f78eec48 ; Flink->Blink,Entry
f7a35698 8b5508 mov edx,dword ptr [ebp+8];ListHead
f7a3569b 8b450c mov eax,dword ptr [ebp+0Ch];Entry
f7a3569e 8902 mov dword ptr [edx],eax;ListHead->Flink = Entry
f7a356a0 8be5 mov esp,ebp
f7a356a2 5d pop ebp
f7a356a3 c20800 ret 8
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;//得到下一个_LIST_ENTRY结构指针
Entry->Flink = Flink; // Entry->Flink = Next ListHead
Entry->Blink = ListHead; //Blink = ListHead
Flink->Blink = Entry; //Next ListHead ->Blink = pData->Entry
ListHead->Flink = Entry; // ListHead->Flink = pData->Entry
}
Entry.Flink--> Next_List_Head->Flink
Entry.Blink --> ListHead;
Next_List_Head->Blink =Entry
ListHead->Flink = Entry
这个关系是这样的
原始的 LIST_ENTRY链表
首先要有一个链表头,那么头插入,就是每次都是从头部插入,具体是这个样子
ListHead->Flink 这个是本身的下一个节点的指针,我们就是把这个指针,换成我们的 一个新的插入节点
也就是
ListHead-> New List_Entry Struct
当然了,这个节点域 也是相互的
所以 这个New List_Entry的Flink 等于 ListHead->Flink 也就是 老的节点,或者叫做 Old List_Entry Struct也行
这样~
ListHead->Flink 里面就是变成了 --> New List_Entry,而New List_Entry的 Flink成员当然就是 -->Old List_Entry,
这样就串联了起来
此时 每当有新的节点插入~
ListHead->Flink --> New List_entry->Flink --> old ListEntry 这样~
而 New List_entry->Blink成员 就只想 ListHead域,而 old List_Entry->Blink成员 只想 new List_Entry Struct
连起来就是
头结点 新插入的节点 老的节点
ListHead --> New List_Entry <-- Old List_Entry
经过调试得知的
ListHead->Blink成员时刻等于 第一个插入的节点值
Flink = ListHead->Flink;//得到下一个_LIST_ENTRY结构指针 //第一次的时候就是自身
Entry->Flink = Flink; // Entry->Flink = Next ListHead
Flink->Blink = Entry; //Next ListHead ->Blink = pData->Entry ;//这里.~~就把Blink成员定义为~第一个节点了~~
而且 每次 调用 InsertHeadList 改变的只有 Old_List_EnTry->Blink, List_Entry_Flink不会改变,只有被当做new的时候 才会改写一次Flink~~
FORCEINLINE
PLIST_ENTRY
RemoveTailList(
__inout PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Blink; //得到第一个尾部节点,也就是第一个插入的节点
PLIST_ENTRY Entry;
Entry = ListHead->Blink; //得到第一个插入的节点
Blink = Entry->Blink; ;//得到第二个插入的节点
ListHead->Blink = Blink; // ListHead->Blink变成第二个节点
Blink->Flink = ListHead; //第二个节点,变成top 节点
return Entry; 返回第一个节点的数据
}
函数源代码(wdm.c)
#define CONTAINING_RECORD(address, type, field) ((type *)((PCHAR)(address) -(ULONG_PTR)(&((type *)0)->field)))
(MYDATASTRUCT*)((PCHAR)( return Entry) - (ulong_ptr)(&((MYDATASTRUCT *)0)->field) )
pData = CONTAINING_RECORD(pEntry,MYDATASTRUCT,List_Entry);
f7a3b5a7 8945e4 mov dword ptr [ebp-1Ch],eax //得到 RemoveTaiList返回的Entry结构地址
f7a3b5aa 8b4de4 mov ecx,dword ptr [ebp-1Ch] ;// 得到
f7a3b5ad 83e904 sub ecx,4 // 是因为传入到这个宏的是,List_Entry这个结构成员的指针,通过"成员地址 - 成员偏移"的方式,得到结构首地址
/*
typedef struct _MYDATASTRUCT
{
ULONG number; 结构首地址
LIST_ENTRY List_Entry;//链表结构 首地址+4
}MYDATASTRUCT,*PMYDATASTRUCT;
*/
f7a3b5b0 894df8 mov dword ptr [ebp-8],ecx
f7a3b5b3 8b55f8 mov edx,dword ptr [ebp-8] ss:0010:f78e6c58=e184d3e8 ;pData->number
f7a3b5b6 8b02 mov eax,dword ptr [edx] ;得到值
f7a3b5b8 50 push eax; 准备输出
f7a3b5b9 6840b7a3f7 push offset ZwCreateFile! ?? ::FNODOBFM::`string' (f7a3b740)
f7a3b5be e805010000 call ZwCreateFile!DbgPrint (f7a3b6c8)
f7a3b5c3 83c408 add esp,8
反汇编代码
至此双链表逆向完毕~~~
- -
代码~~~~~~~~
00000: VOID LinkList_One()
00001: {
00002: /*
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
*/
00003:
00004: LIST_ENTRY link_head;//链表结构
00005: PMYDATASTRUCT pData;//链表指针
00006: ULONG i=0; //计数
00007: KSPIN_LOCK spin_lock;//锁,对付多线程
00008: KIRQL irql;
00009: //初始化链表
00010:
00011: InitializeListHead(&link_head);
00012: KeInitializeSpinLock(&spin_lock);//初始化一个锁
00013:
00014: //插!
00015: KdPrint(("[Link_Learn] Begin Insert to link list~~\n"));
00016:
00017: //锁住
00018:
00019: KeAcquireSpinLock(&spin_lock,&irql);
00020: //干活!
00021:
00022: for (i=0;i<10;i++)
00023: {
00024: pData = (PMYDATASTRUCT)ExAllocatePool(PagedPool,sizeof (MYDATASTRUCT));//分配内存,
00025: pData->number = i;
00026: InsertHeadList(&link_head,&pData->List_Entry);
00027:
00028: }
00029:
00030: KeReleaseSpinLock(&spin_lock,irql);
00031:
00032:
00033: //取数据
00034:
00035: KdPrint(("[Link_Learn] Begin remove link list\n"));
00036:
00037: //锁~住
00038: KeAcquireSpinLock(&spin_lock,&irql);
00039:
00040:
00041: while (!IsListEmpty(&link_head))
00042: {
00043:
00044: PLIST_ENTRY pEntry = RemoveTailList(&link_head);
00045:
00046: //得到节点数据
00047: pData = CONTAINING_RECORD(pEntry,MYDATASTRUCT,List_Entry);
00048:
00049: KdPrint(("[Link_Learn] %d\n",pData->number));
00050: ExFreePool(pData);
00051: }
00052:
00053: KeReleaseSpinLock(&spin_lock,irql);
00054: }
00055:
00056:
联系我时,请说是在 挂海论坛 上看到的,谢谢! |
免费评分
-
上一篇: 键盘钩子注入(vc版)下一篇: 特征码修改技术总结
免责声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关。一切关于该内容及资源商业行为与www.52ghai.com无关。
2、本站提供的一切资源内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。
3、本站信息来自第三方用户,非本站自制,版权归原作者享有,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
4、如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵犯你版权的,请邮件与我们联系删除(邮箱:xhzlw@foxmail.com),本站将立即改正。
|