http://144.34.164.217/practical-reverse-engineering-notes-part-i.html
https://144.one/practical-reverse-engineering-notes-part-ii.html
将要删除的节点后面的节点叫做EntryC
将要删除的节点叫做EntryB
mov rax, [rbx]
mov rcx, [rax]
mov [rbx], rcx
mov [rcx+8], rbx
模式:
取rbx的值给rax,取rax的值给rcx,将rcx写入rbx,将rbx写入rcx+8
其中rbx为ListHead,rax为要删除的节点,rax是要删除的节点的Flink指向的节点
还有就是会有三个CMP判断,第一个后面紧跟je,后两个后面紧跟jne指令

上图中,r14为ListHead,cmp用于判断链表是否为空,即判断ListHead的Flink是不是ListHead本身
如果不为空则跳转

rsi为要删除的节点,rax为要删除的节点的Flink指向的节点
cmp用于判断要删除的节点的Blink是否指向ListHead(正常情况下是应该指向ListHead的),不跳转,继续向下执行
第二个cmp判断眼删除的节点的Flink所指向的节点的Blink是否指向要删除的节点(成立),不跳转
最后两个mov指令将头结点的Flink指向要删除的节点的Flink指向的节点
将要删除的节点的Flink指向的节点的Blink指向头结点

他这个还玩的挺花里胡哨的
r15是ListHead
rdi是要删除的节点
rcx是EntryC
那么下面这条指令,就是将EntryB的Blink指向的节点地址给了rax,那么rax就是ListHead,和r15的值是一样的
mov rax,qword ptr [rdi+8]
所以最后的两条mov指令依然是将ListHead的Flink指向EntryC,将EntryC的Blink指向ListHead
后面的不看了,没啥意思,都差不多,全看完有点浪费时间
RemoveTailList和RemoveHeadList差不多,和上面正好反着,用了三个+8偏移量,1个+0偏移量,上面是用了一个+8偏移量,3个+0偏移量
之前的文章里虽然并没有介绍RemoveEntryList函数,但是根据之前做过的题,也能总结出一些规律,下面这段代码就是该函数的汇编代码
fffff803`85c8aa8e 488b07 mov rax,qword ptr [rdi]
fffff803`85c8aa91 483bc7 cmp rax,rdi
fffff803`85c8aa94 0f8599000000 jne nt!AlpcSectionDeleteProcedure+0x113 (fffff803`85c8ab33) Branch
fffff803`85c8ab33 488b4f08 mov rcx,qword ptr [rdi+8]
fffff803`85c8ab37 48397808 cmp qword ptr [rax+8],rdi
fffff803`85c8ab3b 7522 jne nt!AlpcSectionDeleteProcedure+0x13f (fffff803`85c8ab5f) Branch
nt!AlpcSectionDeleteProcedure+0x11d:
fffff803`85c8ab3d 483939 cmp qword ptr [rcx],rdi
fffff803`85c8ab40 751d jne nt!AlpcSectionDeleteProcedure+0x13f (fffff803`85c8ab5f) Branch
nt!AlpcSectionDeleteProcedure+0x122:
fffff803`85c8ab42 488901 mov qword ptr [rcx],rax
fffff803`85c8ab45 48894808 mov qword ptr [rax+8],rcx
fffff803`85c8ab49 48897f08 mov qword ptr [rdi+8],rdi
fffff803`85c8ab4d 48893f mov qword ptr [rdi],rdi
这是链表删除节点之前的样子

这是删除之后的样子

后面的我也不看了,都差不多
三个CMP都是紧跟jne
然后最后四个mov操作移除要删除的节点
后面的题是让我在windows7和windows8的x86上再把上面的题做一遍,我也不做了