阅读:906回复:7
请大虾来看一下!
如何在os系统中添加一个中断门和一段中断处理程序。
我的疑问是: 中断处理程序的地址是线性地址,是否应该将其放在非分页 内存中才行呢? 第二个问题是: 如何把一段代码加载到非分页内存中去呢? |
|
沙发#
发布于:2004-09-13 15:53
竟然没人赐教
|
|
板凳#
发布于:2004-09-13 16:30
如何在os系统中添加一个中断门和一段中断处理程序。 自己分配,或使用系统自身的..... |
|
|
地板#
发布于:2004-09-13 16:32
如果你不能确保中断程序运行在APC以下的话,还是放到非分页中的好...
|
|
|
地下室#
发布于:2004-09-13 16:33
wowocock详细点解释一下好不好?
还是不明白。 按我的理解,中断处理程序应该是系统段 |
|
5楼#
发布于:2004-09-13 16:41
问题是如何在程序中把一段代码放入系统段中。如何
保证地址的有效性? |
|
6楼#
发布于:2004-09-13 16:42
参考我的XP内核DIY,运行后在IDT 20H处生成中断门,以后在你的应用中将要生成的调用门地址放入EAX中,通过INT20H即可在GDT上动态生成调用门,以后可以随意进出RING0,嘿嘿......
.686p .model flat, stdcall option casemap :none ; case sensitive ; ######################################################################### include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\advapi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\advapi32.lib DEBUG = TRUE MmIsAddressValid proto :dword HMODULE typedef dword NTSTATUS typedef dword PACL typedef dword PSECURITY_DESCRIPTOR typedef dword OBJ_INHERIT=2 OBJ_PERMANENT=10h OBJ_EXCLUSIVE=20h OBJ_CASE_INSENSITIVE=40h OBJ_OPENIF=80h OBJ_OPENLINK =100h OBJ_KERNEL_HANDLE=200 OBJ_VALID_ATTRIBUTES=3F2h SE_KERNEL_OBJECT = 6 GRANT_ACCESS =1 NO_INHERITANCE =0 TRUSTEE_IS_NAME=1 TRUSTEE_IS_USER=1 STATUS_SUCCESS =0 STATUS_ACCESS_DENIED =0C0000022h STATUS_ACCESS_VIOLATION equ 0C0000005h STATUS_INFO_LENGTH_MISMATCH equ 0C0000004h SystemModuleInformation equ 11 PVOID TYPEDEF DWORD UNLONG TYPEDEF DWORD CHAR TYPEDEF BYTE UNICODE_STRING struct nLength word ? MaximumLength word ? Buffer dword ? UNICODE_STRING ends OBJECT_ATTRIBUTES struct nLength dword ? RootDirectory HANDLE ? ObjectName dword ?;PUNICODE_STRING Attributes dword ?; SecurityDescriptor dword ?; PVOID // Points to type SECURITY_DESCRIPTOR SecurityQualityOfService dword ?;PVOID // Points to type SECURITY_QUALITY_OF_SERVICE OBJECT_ATTRIBUTES ends TRUSTEE struct pMultipleTrustee dword ?;PTRUSTEE MultipleTrusteeOperation dword ?; MULTIPLE_TRUSTEE_OPERATION TrusteeForm dword ?;TRUSTEE_FORM TrusteeType dword ?;TRUSTEE_TYPE ptstrName dword ?;LPTSTR TRUSTEE ends EXPLICIT_ACCESS struct grfAccessPermissions DWORD ? grfAccessMode dword ? ;ACCESS_MODE grfInheritance DWORD ? ; Trustee TRUSTEE <> ; EXPLICIT_ACCESS ends MyGATE struct ;门结构类型定义 OFFSETL WORD ? ;32位偏移的低16位 SELECTOR WORd ? ;选择子 DCOUNT BYTE ? ;双字计数字段 GTYPE BYTE ? ;类型 OFFSETH WORD ? ;32位偏移的高16位 MyGATE ends SYSTEM_MODULE_INFORMATION STRUCT Reserved ULONG 2 DUP(?) Base PVOID ? SysModSize ULONG ? Flags ULONG ? Index USHORT ? Unknown USHORT ? LoadCount USHORT ? ModuleNameOffset USHORT ? ImageName CHAR 256 DUP(?) SYSTEM_MODULE_INFORMATION ENDS SetPhyscialMemorySectionCanBeWrited proto :dword MiniMmGetPhysicalAddress proto :dword ENTERRING0 macro pushad pushfd cli mov eax,cr0 ;get rid off readonly protect and eax,0fffeffffh mov cr0,eax endm LEAVERING0 macro mov eax,cr0 ;restore readonly protect or eax,10000h mov cr0,eax sti popfd popad retf endm UNICODE_STR macro str irpc _c,<str> db '&_c' db 0 endm endm .data? GdtLimit dw ? GdtAddr dd ? IdtLimit dw ? IdtAddr dd ? mapAddr dd ? OldEsp dd ? AddrZwQuerySystemInformation dd ? .data align 4 objname dw objnamestr_size,objnamestr_size+2 objnameptr dd 0 objnamestr equ this byte UNICODE_STR <\Device\PhysicalMemory> objnamestr_size equ $-objnamestr ModNtdll dd 0 IsIdtFlag dd 0 MyIntGate MyGATE <0000,0008,00,0eeh,0000> Ntoskrnl dd 0 ntos db "ntoskrnl.exe",0 align 4 ObjAttr db 24 dup (0) Callgt dq 0 ;call gate's sel:off .code _Ring0Proc proc pushad pushfd cli mov eax,cr0 ;get rid off readonly protect and eax,0fffeffffh mov cr0,eax call GetNtoskrnlAddr or eax,eax jz _Ring0ProcExit mov Ntoskrnl,eax call @f db "KeI386AllocateGdtSelectors",0 @@: push eax call MyGetProcAddress mov KeI386AllocateGdtSelectors,eax call @f db "KeI386SetGdtSelector",0 @@: push Ntoskrnl call MyGetProcAddress mov KeI386SetGdtSelector,eax call @f db "KeI386ReleaseGdtSelectors",0 @@: push Ntoskrnl call MyGetProcAddress mov KeI386ReleaseGdtSelectors,eax ;set My IntGate in Idt sidt IdtLimit mov esi,IdtAddr movzx eax,word ptr IdtLimit mov edx,eax inc edx add edx,esi;edx->End Idt+1 mov word ptr[MyIntGate],dx ror edx,16 mov word ptr[MyIntGate+6],dx ror edx,16 mov IsIdtFlag,1 call Search_XDT ;mov IntCode to Ring0 code realm (use Idt address space) push eax shr eax,3 mov ecx,ModNtdll or ecx,ecx jz @f mov [ecx+38h],eax;set Int number in Ntdll @@: pop eax mov edi,eax add edi,esi ;edi->Empty Gate lea esi,MyIntGate cld movsd movsd ;Set MyIntGate mov edi,edx ;copy MyIntCode to End Idt+1 lea esi,MyIntCode mov ecx,IntLen cld rep movsb _Ring0ProcExit: mov eax,cr0 ;restore readonly protect or eax,10000h mov cr0,eax sti popfd popad ret _Ring0Proc endp MyGetProcAddress proc hModule:HMODULE,lpProcName:LPCSTR local ProcNameLen:dword push ebx push esi push edi mov esi,lpProcName cmp esi,10000h ja @f mov ecx,lpProcName ;lpProcName为函数序号 mov esi,hModule mov edi,dword ptr[esi+3ch] add edi,esi mov edi,[edi+78h] add edi,esi jmp Ordinals @@: xor ecx,ecx ;lpProcName为函数指针 GetlpProcNameLength: cmp byte ptr[esi],0 jz @f inc cl inc esi jmp GetlpProcNameLength @@: ;cl=ProcName Length mov ProcNameLen,ecx mov edi,hModule mov esi,dword ptr[edi+3ch] add esi,edi ;esi->PE HEADER mov edi,[esi+78h] add edi,hModule assume edi:ptr IMAGE_EXPORT_DIRECTORY GetExportNameList: mov ebx,[edi].AddressOfNames ;//得到输出函数名表 add ebx,hModule ;ebx->AddressOfNames(函数名字的指针地址). xor eax,eax ;//函数序号计数 mov edx,hModule ;//暂存模块句柄;edx->ntoskrnl push edi ;保存EDI LoopFindApiStr: mov ecx,ProcNameLen add ebx,04 inc eax ;//增加函数计数 mov edi,dword ptr[ebx] add edi,edx ;//得到一个Api函数名字符串.edi->函数名 StrGetProcAddress: mov esi,lpProcName ;//得到Api名字字符串 cmpsd;比较前4个字符是否相等 jnz short LoopFindApiStr ;eax=函数名的INDEX sub cl,4 ;//比较剩余的GetProcAddress串 cld Goon: cmpsb jnz short LoopFindApiStr ;eax=函数名的INDEX loop Goon pop edi ;恢复EDI mov esi,edx mov ebx,[edi].AddressOfNameOrdinals add ebx,esi ;//取函数序号地址列表,ebx->AddresssOfNameOrdinals movzx ecx,word ptr [ebx+eax*2] Ordinals: mov ebx,[edi].AddressOfFunctions add ebx,esi ;//得到ntoskrnl函数地址列表 mov ebx,dword ptr[ebx+ecx*4] add ebx,esi ;//计算函数地址 mov eax,ebx ;eax=API函数地址,esi=Kernel32.dll hModule pop edi pop esi pop ebx ret MyGetProcAddress endp Search_XDT proc near ;entry esi==Base of Idt or GDT ;Eax==Limit pushad mov ebx,eax ;ebx=limit mov eax,8 ; skipping null selector @@1: cmp IsIdtFlag,1 jz IsIdt cmp dword ptr [esi+eax+0],0 ;gdt jnz @@2 cmp dword ptr [esi+eax+4],0 jz @@3 jmp @@2 IsIdt: cmp dword ptr [esi+eax+0],80000h ;idt jnz @@2 cmp dword ptr [esi+eax+4],0 jz @@3 @@2: add eax,8 cmp eax,ebx jb @@1 ;if we haven't found any free GDT entry, ;lets use the last two entries mov eax,ebx sub eax,7 @@3: mov [esp+4*7],eax ; return off in eax popad ; eax=free GDT or IDT entry selector ret Search_XDT endp MyIntCode:;input eax->code execute in Ring0;0 to release Selector push ebx ;failure eax=0 push esi push edi call IntNext IntNext: pop ebx sub ebx,offset IntNext test eax,eax ;if Release Selector? jz ReleaseSel cmp CallGateSel[ebx],0;if the former Selector has not been released,use the same Selector jnz SetGdtSelector;the former Selector has not been realease ,use the same Selector push eax push 1 lea eax,CallGateSel[ebx] push eax call dword ptr KeI386AllocateGdtSelectors[ebx] test eax,eax pop eax;set callgate clc jnz SetExit SetGdtSelector: mov word ptr MyCallGate[ebx],ax shr eax,16 mov word ptr [MyCallGate+6][ebx],ax lea esi,MyCallGate[ebx] push esi push CallGateSel[ebx] call dword ptr KeI386SetGdtSelector[ebx] test eax,eax jz SetOk push 1 lea eax,CallGateSel[ebx] push eax call dword ptr KeI386ReleaseGdtSelectors[ebx] clc jmp SetExit ReleaseSel: cmp CallGateSel[ebx],0;if Released already? clc jz SetExit @@: push 1 lea eax,CallGateSel[ebx] push eax call dword ptr KeI386ReleaseGdtSelectors[ebx] stc SetExit: xor eax,eax xor edx,edx inc edx cmovc eax,edx;set success flag pop edi pop esi pop ebx iretd SetOk: mov eax,CallGateSel[ebx] pop edi pop esi pop ebx if DEBUG mov ecx,IntLen endif iretd CallGateSel dd 0 MyCallGate MyGATE <0000,0008,00,0ech,0000> KeI386AllocateGdtSelectors dd 0 KeI386SetGdtSelector dd 0 KeI386ReleaseGdtSelectors dd 0 int 3 Ring0CodeLen=$-_Ring0Proc IntLen=$-MyIntCode GetNtoskrnlAddr proc pushad pushfd mov ebx,80500000h search_addr_@1: sub ebx,1000h invoke MmIsAddressValid,ebx test eax,eax jz search_addr_@1 ;ntoskrnl can be rebased,and it's not certain whether can found it,so not to ;search too high address to avoid blue screen cmp ebx,80400000h jb short search_seh_restore1 cmp word ptr [ebx],'ZM' jnz short search_addr_@1 mov eax,[ebx+3ch] add eax,ebx cmp word ptr [eax],'EP' jnz short search_addr_@1 mov eax,[eax+78h] add eax,ebx mov edx,[eax+3*4] add edx,ebx ;edx->pe(dll) file name call @f db "ntoskrnl",0 @@: pop edi mov ecx,dword ptr[edi];edi->ntoskrnl cmp dword ptr [edx],ecx jnz short search_addr_@1 mov ecx,dword ptr[edi+4] cmp dword ptr [edx+4],ecx jnz short search_addr_@1 search_seh_restore=$ search_seh_restore1: popfd mov eax,ebx mov [esp+4*7],eax popad ret GetNtoskrnlAddr endp IsAddressExist proc lAddress:dword local PageDirectoryEntry:dword ;=(unsigned int *)0xC0300000; local PageTableEntry:dword ;=(unsigned int *)0xC0000000; ;判断页目录是否有效,第0位(P)为存在位,请参阅相关书籍 mov PageDirectoryEntry,0C0300000h mov PageTableEntry,0C0000000h mov eax,lAddress shr eax,22 shl eax,2 add eax,PageDirectoryEntry test dword ptr[eax],1 jnz @f xor eax,eax ret @@: ;//@(C0000000h+(LA&0xFFFFF000)>>10d)&0fffff000h+PO mov eax,lAddress and eax,0FFFFF000h shr eax,10 add eax,PageTableEntry test dword ptr[eax],1 jz @b ret IsAddressExist endp MmIsAddressValid proc lAddress:dword mov ecx,lAddress mov eax, ecx shr eax, 14h mov edx, 0FFCh and eax, edx ;offset in PageDirectoryEntry sub eax, 3FD00000h;add eax,0c0300000h mov eax, [eax] test al, 1 jz AddressInValid test al, al js AddressValid shr ecx, 0Ah and ecx, 3FFFFCh;offset in PageTableEntry sub ecx, 40000000h;add ecx,0c0000000h mov eax, [ecx] test al, 1 jz AddressInValid test al, al js @f AddressValid: mov eax,1 ret AddressInValid: xor eax,eax ret @@: and ecx, edx mov eax, [ecx-3FD00000h] and ax, 81h cmp al, 81h jnz AddressValid jmp AddressInValid MmIsAddressValid endp SetPhyscialMemorySectionCanBeWrited proc uses ebx esi edi hSection:HANDLE local pDacl: PACL local pNewDacl:PACL local pSD :PSECURITY_DESCRIPTOR local dwRes:DWORD ; local ea:EXPLICIT_ACCESS ; invoke GetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,\ NULL,NULL, addr pDacl,NULL, addr pSD cmp eax,ERROR_SUCCESS jz @f jmp OutSet @@: mov dwRes,eax mov ea.grfAccessPermissions ,SECTION_MAP_WRITE;2 mov ea.grfAccessMode ,GRANT_ACCESS;1 mov ea.grfInheritance,NO_INHERITANCE;0 mov ea.Trustee.pMultipleTrustee,0 mov ea.Trustee.MultipleTrusteeOperation,0 mov ea.Trustee.TrusteeForm,TRUSTEE_IS_NAME;1 mov ea.Trustee.TrusteeType,TRUSTEE_IS_USER;1 call @f db "CURRENT_USER",0 @@: pop edx mov ea.Trustee.ptstrName,edx invoke SetEntriesInAcl,1,addr ea,pDacl,addr pNewDacl cmp eax,ERROR_SUCCESS jz @f jmp OutSet @@: invoke SetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,\ NULL,NULL,pNewDacl,NULL OutSet: cmp pSD,0 jz @f invoke LocalFree,pSD @@: cmp pNewDacl,0 jz @f invoke LocalFree,pNewDacl @@: ret SetPhyscialMemorySectionCanBeWrited endp MiniMmGetPhysicalAddress proc virtualaddress:dword mov eax,virtualaddress cmp eax,80000000h jb @f cmp eax,0a0000000h jae @f and eax,1FFFF000h ret @@: mov eax,0 ret MiniMmGetPhysicalAddress endp ExecRing0Proc proc Entry:ULONG,seglen:ULONG local tmpSel:dword local setcg:dword local BaseAddress:dword local NtdllMod :dword local hSection:HANDLE local status:NTSTATUS local objectAttributes:OBJECT_ATTRIBUTES local objName:UNICODE_STRING mov status,STATUS_SUCCESS; sgdt GdtLimit invoke MiniMmGetPhysicalAddress,GdtAddr mov mapAddr,eax test eax,eax jz Exit1 call @f db "Ntdll.dll",0 @@: call LoadLibraryA mov NtdllMod,eax lea edx,objnamestr mov objnameptr,edx lea edi,ObjAttr and di,0fffch ;align to 4 bytes,or ZwOpenSection will fail push edi ;edi->ObjAttr push 24 ;length of <\Device\PhysicalMemory> pop ecx push ecx xor eax,eax rep stosb ;put ObjAttr with 0 pop ecx pop edi mov esi,edi stosd mov dword ptr[esi],ecx stosd lea eax,[edx-8] ;eax->objname stosd ;ObjAddr(18h,00,00,00,00,00,00,00,offset objname,40,02,00,00,dd 2 dup(0) mov dword ptr [edi],240h call @f db "ZwOpenSection",0 @@: push NtdllMod call GetProcAddress mov ebx,eax ;ebx=ZwOpenSection push esi ;esi->ObjAttr push SECTION_MAP_READ or SECTION_MAP_WRITE lea edi,hSection push edi ;edi->hSection call eax ;ZwOpenSection(&hSection,SECTION_MAP_READ or SECTION_MAP_WRITE,ObjAttr) mov status,eax cmp status,STATUS_ACCESS_DENIED jnz AccessPermit mov eax,ebx push esi push READ_CONTROL or WRITE_DAC push edi call eax mov status,eax invoke SetPhyscialMemorySectionCanBeWrited,hSection call @f db "ZwClose",0 @@: push NtdllMod call GetProcAddress push hSection call eax ;zwClose hSection mov eax,ebx push esi push SECTION_MAP_READ or SECTION_MAP_WRITE lea edi,hSection push edi call eax mov status ,eax ;status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes); AccessPermit: cmp status ,STATUS_SUCCESS jz @f ;printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status); ;return 0; mov eax,0 ret @@: movzx eax,word ptr[GdtLimit] inc eax invoke MapViewOfFile,hSection, FILE_MAP_READ or FILE_MAP_WRITE, 0, mapAddr, \ eax mov BaseAddress,eax cmp BaseAddress,0 jnz @f ;printf("Error MapViewOfFile:"); ;PrintWin32Error(GetLastError()); return 0; mov eax,0 ret @@: mov esi,eax ;esi->gdt base movzx eax,word ptr GdtLimit ;eax=gdt limit mov IsIdtFlag,0 call Search_XDT mov tmpSel,eax mov setcg,FALSE; mov esi,BaseAddress mov ebx,eax add ebx,esi assume ebx:ptr MyGATE mov edx,Entry mov [ebx].OFFSETL,dx mov [ebx].SELECTOR ,8 mov [ebx].DCOUNT ,0 mov [ebx].GTYPE,0ech shr edx,16 mov [ebx].OFFSETH,dx mov setcg,TRUE cmp setcg,0 jnz ChangeOK call @f db "ZwClose",0 @@: push NtdllMod call GetProcAddress push hSection call eax xor eax,eax ret ChangeOK: and dword ptr Callgt,0 or al,3h mov word ptr [Callgt+4],ax ;farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate; invoke VirtualLock,Entry,seglen test eax,eax jnz @f xor eax,eax ret @@: invoke GetCurrentThread invoke SetThreadPriority,eax,THREAD_PRIORITY_TIME_CRITICAL invoke Sleep,0 call fword ptr [Callgt] ;use callgate to Ring0! ;_asm call fword ptr [farcall] invoke GetCurrentThread invoke SetThreadPriority,eax,THREAD_PRIORITY_NORMAL invoke VirtualUnlock,Entry,seglen ;//Clear callgate ;*(ULONG *)cg=0; ;*((ULONG *)cg+1)=0; mov esi,BaseAddress mov eax,tmpSel add eax,esi mov dword ptr[eax],0 mov dword ptr[eax+4],0 ;ZwClose(hSection); call @f db "ZwClose",0 @@: push NtdllMod call GetProcAddress push hSection call eax mov eax,TRUE ret ExecRing0Proc endp main: assume fs:nothing push offset MySEH push fs:[0] mov fs:[0],esp mov OldEsp,esp mov ax,ds ;if Win9x? test ax,4 jnz Exit1 invoke VirtualLock,offset _Ring0Proc,Ring0CodeLen ;invoke VirtualLock,offset r0Data,sizeof(RING0DATA) invoke ExecRing0Proc,offset _Ring0Proc,Ring0CodeLen ;invoke VirtualUnlock,offset r0Data,sizeof(RING0DATA) invoke VirtualUnlock,offset _Ring0Proc,Ring0CodeLen Exit1: pop fs:[0] add esp,4 invoke ExitProcess,0 MySEH : mov esp,OldEsp pop fs:[0] add esp,4 invoke ExitProcess,-1 end main |
|
|
7楼#
发布于:2004-09-13 16:52
老师,我这人比较笨。
程序太长了,理解起来也比较困难。 中断处理例程应该是处于共享的系统段,直接引用它的地址, 我觉得也应该有效。 |
|