本来想把这个函数完整的还原出来,后来写着写着就发现头大,老是转不过弯来。它的反编译代码也不是很长,但是经过编译器处理后感觉还原起来很吃力。特别是一些调转,要将整个流程弄清楚才好写出来,还要注意变量的使用。因为完整的代码写不下出了,这里就对照反编译的代码分析(有兴趣的可以试一试,写完最好能分享一下:)):
原型:BOOLEAN KeInsertQueueDpc( IN PRKDPC Dpc,IN PVOID SystemArgument1,
IN PVOID SystemArgument2 );
nt!KeInsertQueueDpc:
8407e739 8bff mov edi,edi
8407e73b 55 push ebp
8407e73c 8bec mov ebp,esp
8407e73e 83e4f8 and esp,0FFFFFFF8h
8407e741 83ec1c sub esp,1Ch
8407e744 53 push ebx
8407e745 56 push esi
8407e746 57 push edi
8407e747 8b7d08 mov edi,dword ptr [ebp+8];第一个参数Dpc
8407e74a 668b4702 mov ax,word ptr [edi+2];Dpc->Number
8407e74e b11f mov cl,1Fh
8407e750 0fb7f0 movzx esi,ax
8407e753 c644241100 mov byte ptr [esp+11h],0;NewIrql
8407e758 ff155c210084 call dword ptr [nt!_imp_KfRaiseIrql (8400215c)];KeRaiseIrql()
8407e75e 88442413 mov byte ptr [esp+13h],al;OldIrql
8407e762 e81d020000 call nt!KeDisableInterrupts (8407e984)
8407e767 648b1d20000000 mov ebx,dword ptr fs:[20h];KPCR->KPRCB
8407e76e 88442412 mov byte ptr [esp+12h],al
8407e772 895c2414 mov dword ptr [esp+14h],ebx
8407e776 6683fe20 cmp si,20h ;Dpc->Number<0x20
8407e77a 722a jb nt!KeInsertQueueDpc+0x6c (8407e7a6)
nt!KeInsertQueueDpc+0x43:
8407e77c 0fb7c6 movzx eax,si
8407e77f 8d48e0 lea ecx,[eax-20h]
8407e782 8b1c8dc0b81684 mov ebx,dword ptr nt!KiProcessorBlock (8416b8c0)[ecx*4]
8407e789 894c2418 mov dword ptr [esp+18h],ecx
8407e78d 85db test ebx,ebx
8407e78f 751f jne nt!KeInsertQueueDpc+0x76 (8407e7b0)
nt!KeInsertQueueDpc+0x58:
8407e791 ff356cb91684 push dword ptr [nt!KeNumberProcessors (8416b96c)]
8407e797 50 push eax
8407e798 57 push edi
8407e799 6a03 push 3
8407e79b 68c7000000 push 0C7h ;TIMER_OR_DPC_INVALID
8407e7a0 e85d170600 call nt!KeBugCheckEx (840dff02);去检查bug
8407e7a5 cc int 3
nt!KeInsertQueueDpc+0x6c:
8407e7a6 8b83cc030000 mov eax,dword ptr [ebx+3CCh]KPRCB->Number
8407e7ac 89442418 mov dword ptr [esp+18h],eax
nt!KeInsertQueueDpc+0x76:
8407e7b0 803f18 cmp byte ptr [edi],18h
8407e7b3 750f jne nt!KeInsertQueueDpc+0x8a (8407e7c4)
nt!KeInsertQueueDpc+0x7b:
8407e7b5 80bb3019000000 cmp byte ptr [ebx+1930h],0;KPRCB->ThreadDpcEnable
8407e7bc 8db3f4180000 lea esi,[ebx+18F4h];KPRCB->DpcDadta[1]
8407e7c2 7506 jne nt!KeInsertQueueDpc+0x90 (8407e7ca)
nt!KeInsertQueueDpc+0x8a:
8407e7c4 8db3e0180000 lea esi,[ebx+18E0h];KPRCB->DpcData[0]
nt!KeInsertQueueDpc+0x90:
8407e7ca 8d4e08 lea ecx,[esi+8] ;DpcData.DpcLock
8407e7cd e84eaaffff call nt!KefAcquireSpinLockAtDpcLevel (84079220)
8407e7d2 8bce mov ecx,esi
8407e7d4 8d571c lea edx,[edi+1Ch];Dpc->DpcData
8407e7d7 33c0 xor eax,eax
8407e7d9 f00fb10a lock cmpxchg dword ptr [edx],ecx
8407e7dd 85c0 test eax,eax
8407e7df 753b jne nt!KeInsertQueueDpc+0xe2 (8407e81c)
nt!KeInsertQueueDpc+0xa7:
8407e7e1 ff460c inc dword ptr [esi+0Ch];DpcData->DpcQueueDepth++
8407e7e4 ff4610 inc dword ptr [esi+10h];DpcData->DpcCount++
8407e7e7 807f0102 cmp byte ptr [edi+1],2 ;Dpc->Importance
8407e7eb 8b450c mov eax,dword ptr [ebp+0Ch]
8407e7ee 894714 mov dword ptr [edi+14h],eax ;Dpc->SystemArgument1
8407e7f1 8b4510 mov eax,dword ptr [ebp+10h]
8407e7f4 894718 mov dword ptr [edi+18h],eax
8407e7f7 c644241101 mov byte ptr [esp+11h],1
8407e7fc 8d4704 lea eax,[edi+4] ;Dpc->DpcListEntry要加入Dpc双向循环链表里
8407e7ff 750e jne nt!KeInsertQueueDpc+0xd5 (8407e80f)
nt!KeInsertQueueDpc+0xc7:;链表操作,加到队头
8407e801 8b0e mov ecx,dword ptr [esi]
8407e803 8908 mov dword ptr [eax],ecx
8407e805 897004 mov dword ptr [eax+4],esi
8407e808 894104 mov dword ptr [ecx+4],eax
8407e80b 8906 mov dword ptr [esi],eax
8407e80d eb0d jmp nt!KeInsertQueueDpc+0xe2 (8407e81c)
nt!KeInsertQueueDpc+0xd5;链表操作,加到队尾
8407e80f 8b4e04 mov ecx,dword ptr [esi+4]
8407e812 8930 mov dword ptr [eax],esi
8407e814 894804 mov dword ptr [eax+4],ecx
8407e817 8901 mov dword ptr [ecx],eax
8407e819 894604 mov dword ptr [esi+4],eax
nt!KeInsertQueueDpc+0xe2:
8407e81c 8d4e08 lea ecx,[esi+8]
8407e81f e8acaaffff call nt!KefReleaseSpinLockFromDpcLevel (840792d0);释放自旋锁
8407e824 807c241100 cmp byte ptr [esp+11h],0
8407e829 0f842e010000 je nt!KeInsertQueueDpc+0x223 (8407e95d)
nt!KeInsertQueueDpc+0xf5:
8407e82f 8d83f4180000 lea eax,[ebx+18F4h];KPRCB->DpcData[1]
8407e835 6a2f push 2Fh
8407e837 59 pop ecx
8407e838 3bf0 cmp esi,eax
8407e83a 752b jne nt!KeInsertQueueDpc+0x12d (8407e867)
nt!KeInsertQueueDpc+0x102:
8407e83c 6a02 push 2
8407e83e 58 pop eax
8407e83f 668bd0 mov dx,ax
8407e842 8db336190000 lea esi,[ebx+1936h];KPRCB->ThreadDpcState
8407e848 668b06 mov ax,word ptr [esi]
nt!KeInsertQueueDpc+0x111:
8407e84b 668bf8 mov di,ax
8407e84e 660bfa or di,dx
8407e851 66f00fb13e lock cmpxchg word ptr [esi],di
8407e856 75f3 jne nt!KeInsertQueueDpc+0x111 (8407e84b)
nt!KeInsertQueueDpc+0x11e:
8407e858 0fb7c0 movzx eax,ax
8407e85b 84c1 test cl,al
8407e85d 0f85fa000000 jne nt!KeInsertQueueDpc+0x223 (8407e95d)
nt!KeInsertQueueDpc+0x129:
8407e863 6a04 push 4
8407e865 eb26 jmp nt!KeInsertQueueDpc+0x153 (8407e88d)
nt!KeInsertQueueDpc+0x12d:
8407e867 8b460c mov eax,dword ptr [esi+0Ch];DpcData->DpcQueueDepth
8407e86a 3b830c190000 cmp eax,dword ptr [ebx+190Ch];MaximumDpcQueueDepth
8407e870 7d19 jge nt!KeInsertQueueDpc+0x151 (8407e88b)
nt!KeInsertQueueDpc+0x138:
8407e872 395c2414 cmp dword ptr [esp+14h],ebx
8407e876 0f84ae000000 je nt!KeInsertQueueDpc+0x1f0 (8407e92a)
nt!KeInsertQueueDpc+0x142:
8407e87c 8a4701 mov al,byte ptr [edi+1];Dpc->Importance
8407e87f 3c02 cmp al,2
8407e881 7408 je nt!KeInsertQueueDpc+0x151 (8407e88b)
nt!KeInsertQueueDpc+0x149:
8407e883 3c03 cmp al,3
8407e885 0f85bb000000 jne nt!KeInsertQueueDpc+0x20c (8407e946)
nt!KeInsertQueueDpc+0x151:
8407e88b 6a02 push 2
nt!KeInsertQueueDpc+0x153:
8407e88d 58 pop eax
8407e88e 3b5c2414 cmp ebx,dword ptr [esp+14h]
8407e892 7506 jne nt!KeInsertQueueDpc+0x160 (8407e89a)
nt!KeInsertQueueDpc+0x15a:
8407e894 6a29 push 29h
8407e896 59 pop ecx
8407e897 83c820 or eax,20h
nt!KeInsertQueueDpc+0x160:
8407e89a 668bd0 mov dx,ax
8407e89d 8db334190000 lea esi,[ebx+1934h];KPRCB->NormalDpcState---这里好像是一个union
8407e8a3 668b06 mov ax,word ptr [esi]
nt!KeInsertQueueDpc+0x16c:
8407e8a6 668bf8 mov di,ax
8407e8a9 660bfa or di,dx
8407e8ac 66f00fb13e lock cmpxchg word ptr [esi],di
8407e8b1 75f3 jne nt!KeInsertQueueDpc+0x16c (8407e8a6)
nt!KeInsertQueueDpc+0x179:
8407e8b3 0fb7c0 movzx eax,ax
8407e8b6 23c8 and ecx,eax
8407e8b8 6685c9 test cx,cx
8407e8bb 0f859c000000 jne nt!KeInsertQueueDpc+0x223 (8407e95d)
nt!KeInsertQueueDpc+0x187:
8407e8c1 3b5c2414 cmp ebx,dword ptr [esp+14h]
8407e8c5 0f848a000000 je nt!KeInsertQueueDpc+0x21b (8407e955)
nt!KeInsertQueueDpc+0x191:
8407e8cb 33c0 xor eax,eax
8407e8cd 40 inc eax
8407e8ce 668944241c mov word ptr [esp+1Ch],ax
8407e8d3 668944241e mov word ptr [esp+1Eh],ax
8407e8d8 33c0 xor eax,eax
8407e8da 8d7c2424 lea edi,[esp+24h]
8407e8de ab stos dword ptr es:[edi];
8407e8df 8b442418 mov eax,dword ptr [esp+18h]
8407e8e3 8b0c85806b1684 mov ecx,dword ptr nt!KiProcessorIndexToNumberMappingTable (84166b80)[eax*4]
8407e8ea 0fb754241c movzx edx,word ptr [esp+1Ch]
8407e8ef 8bc1 mov eax,ecx
8407e8f1 c1e806 shr eax,6
8407e8f4 83e13f and ecx,3Fh
8407e8f7 3bd0 cmp edx,eax
8407e8f9 7708 ja nt!KeInsertQueueDpc+0x1c9 (8407e903)
nt!KeInsertQueueDpc+0x1c1:
8407e8fb 8d5001 lea edx,[eax+1]
8407e8fe 668954241c mov word ptr [esp+1Ch],dx
nt!KeInsertQueueDpc+0x1c9:
8407e903 8b0c8d807f0484 mov ecx,dword ptr nt!KiMask32Array (84047f80)[ecx*4]
8407e90a 8d448424 lea eax,[esp+eax*4+24h]
8407e90e 0908 or dword ptr [eax],ecx
8407e910 64a120000000 mov eax,dword ptr fs:[00000020h]
8407e916 ff8074350000 inc dword ptr [eax+3574h]
8407e91c 6a02 push 2
8407e91e 5a pop edx
8407e91f 8d4c241c lea ecx,[esp+1Ch]
8407e923 e840f4ffff call nt!KiIpiSend (8407dd68)
8407e928 eb33 jmp nt!KeInsertQueueDpc+0x223 (8407e95d)
nt!KeInsertQueueDpc+0x1f0:
8407e92a 807f0100 cmp byte ptr [edi+1],0;Dpc->Importance
8407e92e 0f8557ffffff jne nt!KeInsertQueueDpc+0x151 (8407e88b)
nt!KeInsertQueueDpc+0x1fa:
8407e934 8b8310190000 mov eax,dword ptr [ebx+1910h]
8407e93a 3b8314190000 cmp eax,dword ptr [ebx+1914h]
8407e940 0f8245ffffff jb nt!KeInsertQueueDpc+0x151 (8407e88b)
nt!KeInsertQueueDpc+0x20c:
8407e946 6a10 push 10h
8407e948 58 pop eax
8407e949 81c334190000 add ebx,1934h
8407e94f 66f00903 lock or word ptr [ebx],ax
8407e953 eb08 jmp nt!KeInsertQueueDpc+0x223 (8407e95d)
nt!KeInsertQueueDpc+0x21b:
8407e955 b102 mov cl,2
8407e957 ff158c210084 call dword ptr [nt!_imp_HalRequestSoftwareInterrupt (8400218c)]
nt!KeInsertQueueDpc+0x223:
8407e95d 807c241200 cmp byte ptr [esp+12h],0
8407e962 7401 je nt!KeInsertQueueDpc+0x22b (8407e965)
nt!KeInsertQueueDpc+0x22a:
8407e964 fb sti
nt!KeInsertQueueDpc+0x22b:
8407e965 8a4c2413 mov cl,byte ptr [esp+13h]
8407e969 ff1558210084 call dword ptr [nt!_imp_KfLowerIrql (84002158)]
8407e96f 8a442411 mov al,byte ptr [esp+11h]
8407e973 5f pop edi
8407e974 5e pop esi
8407e975 5b pop ebx
8407e976 8be5 mov esp,ebp
8407e978 5d pop ebp
8407e979 c20c00 ret 0Ch
从这个函数的名字来看,就是要将之前初始化过的Dpc插入到Dpc链表中,在这个过程中会涉及大量的结构体的操作,主要是确定这个动作是否在安全范围内进行,真正的有效操作并不多。不仅仅是这个函数,其它的也都会对各种结构体进行操作来实现其功能。在目前看来我的想法不会实现的,但还是有收获的。
可以想象写操作系统的程序员是多么的牛!还有那些逆向工程师需要掌握多少知识才能够较好的还原未公开的代码。