📄 wordsys.asm
字号:
;WORDSYS.ASM
; *******************************************************************************
; * 全屏截词DLL,通过修改TextOutW,ExtTextOutA,ExtTextOutW三个函数的首 *
; * 条指令实现的截词。 *
; * *
; * 支持Windows 2000 Windows XP *
; * *
; * 版本:0.93 *
; * 代码:江华 2001年6月20日。 *
; * *
; * ml /c /coff /Cp WORDSYS.ASM *
; * Link /SECTION:.data,S /subsystem:windows /dll /def:WORDSYS.def WORDSYS.obj *
; *******************************************************************************
;ml /c /coff /Cp WORDSYS.asm
;Link /SECTION:.data,S /subsystem:windows /dll /def:WORDSYS.def WORDSYS.obj
.386
.model flat, stdcall
option casemap :none
include ..\include\windows.inc
include ..\include\user32.inc
include ..\include\kernel32.inc
includelib ..\lib\user32.lib
includelib ..\lib\kernel32.lib
;---------------------------------------------------------------------------
ProcessBufS STRUCT ;每个进程私有
ProcessHandle dd ? ;进程句柄
BufNo dd ? ;缓冲区号,指明这个进程最后一次用的缓冲区号
ProcessBufS ENDS
PublicBufS STRUCT ;共享结构
ProcessHandle dd ? ;进程句柄
WirteCount dd ? ;访问的频烦程度
LastBufNo dw ?
Pos dw ? ;当前缓冲区的偏移
PublicBufS ENDS
;---------------------------------------------------------------------------
.data ;共享数据段,所有进程共享
AllWCharNum dd 0
AllACharNum dd 0
Busy db 0
TextOutWName db 'TextOutW',0
ExtTextOutWName db 'ExtTextOutW',0
ExtTextOutAName db 'ExtTextOutA',0
gdi32 db '\gdi32.dll' ,0
SystemPath db MAX_PATH dup(0)
gdiModuleHandle dd 0
Allp dd 0
PublicBufW PublicBufS 30 dup (<0,0,0>)
SaveBufferW db 256*30 dup(' ') ;unicode缓冲区
PublicBufA PublicBufS 10 dup (<0,0,0>)
SaveBufferA db 256*10 dup(' ') ;ansi缓冲区
;PublicBufW中的30个结构按顺序,与SaveBufferW中的内容对应,每个缓冲区长256个字节
;---------------------------------------------------------------------------
.data?
ModuleHandle dd ?
TextOutWAddr dd ?
TextOutWretAddr dd ?
ExtTextOutWAddr dd ?
ExtTextOutWretAddr dd ?
ExtTextOutAAddr dd ?
ExtTextOutAretAddr dd ?
ProcessBufW ProcessBufS <?>
ProcessBufA ProcessBufS <?>
pflOldProtect dd ?
temp dd ?
;---------------------------------------------------------------------------
.code
GetWord PROC
push ebp
mov ebp,esp
cld
mov esi, offset PublicBufW
mov edi, [ebp+8]
mov ecx, (30*sizeof(PublicBufS)+256*30)/4
rep movsd
mov esi, offset PublicBufA
mov edi, [ebp+12]
mov ecx, (10*sizeof(PublicBufS)+256*10)/4
rep movsd
xor eax,eax
mov esi,offset PublicBufW
add esi,10
mov ecx,30
clear1:
mov word ptr [esi],ax
add esi,12
loop clear1
mov esi,offset PublicBufA
add esi,10
mov ecx,10
clear2:
mov word ptr [esi],ax
add esi,12
loop clear2
mov edi, offset SaveBufferW
mov ecx,256*30/4
rep stosd
mov edi, offset SaveBufferA
mov ecx,256*10/4
rep stosd
pop ebp
ret 8
GetWord ENDP
;---------------------------------------------------------------------------
GetWBufNo PROC ;eax为进程号,eax返回一个缓冲区号,找出访问频率最小的.并设置WirteCount和Pos域
push edi
push edx
push ecx
push ebx
push eax
mov eax,30
mov ecx,30-1
mov ebx,offset PublicBufW
mov edi,ebx
mov edx,[ebx+4]
loopCompareW:
add ebx,sizeof(PublicBufS)
cmp edx,[ebx+4]
jle NextCompareW
mov eax,ecx
mov edi,ebx
mov edx,[ebx+4]
NextCompareW:
loop loopCompareW
mov ecx,eax
mov eax,30
sub eax,ecx
mov ecx,AllWCharNum
mov [edi+4],ecx
xor ecx,ecx
mov [edi+10],cx
pop [edi]
pop ebx
pop ecx
pop edx
pop edi
ret
GetWBufNo ENDP
;---------------------------------------------------------------------------
GetABufNo PROC ;eax为进程号,eax返回一个缓冲区号,找出访问频率最小的.并设置WirteCount和Pos域
push edi
push edx
push ecx
push ebx
push eax
mov eax,10
mov ecx,10-1
mov ebx,offset PublicBufA
mov edi,ebx
mov edx,[ebx+4]
loopCompareA:
add ebx,sizeof(PublicBufS)
cmp edx,[ebx+4]
jle NextCompareA
mov eax,ecx
mov edi,ebx
mov edx,[ebx+4]
NextCompareA:
loop loopCompareA
mov ecx,eax
mov eax,10
sub eax,ecx
mov ecx,AllACharNum
mov [edi+4],ecx
xor ecx,ecx
mov [edi+10],cx
pop [edi]
pop ebx
pop ecx
pop edx
pop edi
ret
GetABufNo ENDP
;---------------------------------------------------------------------------
MainWork PROC
inc AllWCharNum
add ecx,ecx
cmp ecx,0ffh
jl NoLongerw
mov ecx,0feh
NoLongerw:
pushad
cmp ProcessBufW.BufNo,-1
;查看ProcessBuf.BufNo是否为-1,如果=-1则调用GetWBufNo,得到一个空的缓冲区
jnz HaveWBuf
GetWBuf:
mov eax,ProcessBufW.ProcessHandle
Call GetWBufNo
mov ProcessBufW.BufNo,eax
HaveWBuf:
mov eax,ProcessBufW.BufNo
mov ebx,sizeof(PublicBufS)
mul ebx
mov ebx,offset PublicBufW
add ebx,eax
mov eax,[ebx] ;ebx指向当前缓冲区管理队列
cmp eax,ProcessBufW.ProcessHandle
jnz GetWBuf
mov eax,AllWCharNum
mov [ebx+4],eax
xor eax,eax
mov ax,[ebx+10]
mov edx,eax ;当前缓冲区的字符数
add eax,ecx
cmp eax,255
ja GetWBuf
;mov [ebx+8],eax
push eax ;当前字符数
push ebx ;存当前字符数
mov eax,ProcessBufW.BufNo
shl eax,8
mov ebx,offset SaveBufferW
add ebx,eax
add ebx,edx
mov edi,[ebp+7*4]
CopyW:
mov al,[edi]
mov [ebx],al
inc ebx
inc edi
loop CopyW
pop ebx
pop eax
mov [ebx+10],ax
popad
ret
MainWork ENDP
;---------------------------------------------------------------------------
MyExtTextOutW PROC ;从ExtTextOutW跳来
push ebp
mov ebp,esp
push ecx
mov ecx,[ebp+8*4]
cmp ecx,0
jz NoWChar
call MainWork
NoWChar:
pop ecx
sub esp,1ch
jmp dword ptr ExtTextOutWretAddr
MyExtTextOutW ENDP
;---------------------------------------------------------------------------
MyTextOutW2000 PROC ;从win2000中的TextOutW跳来
push ebp
mov ebp,esp
push ecx
push ebx
push ecx
mov ecx,[ebp+6*4]
cmp ecx,0
jz NoWChar1
sub ebp,8
call MainWork
add ebp,8
NoWChar1:
pop ecx
jmp dword ptr TextOutWretAddr
MyTextOutW2000 ENDP
;---------------------------------------------------------------------------
MyTextOutWXP PROC ;从winXP中的TextOutW跳来
push ebp
mov ebp,esp
push ebx
push esi
push ecx
mov ecx,[ebp+6*4]
cmp ecx,0
jz NoWChar1
sub ebp,8
call MainWork
add ebp,8
NoWChar1:
pop ecx
jmp dword ptr TextOutWretAddr
MyTextOutWXP ENDP
;---------------------------------------------------------------------------
MyExtTextOutA PROC ;从ExtTextOutA中跳来
push ebp
mov ebp,esp
push ecx
mov ecx,[ebp+8*4]
cmp ecx,0
jz NoAChar
inc AllACharNum
cmp ecx,0ffh
jl NoLongera
mov ecx,0feh
NoLongera:
pushad
cmp ProcessBufA.BufNo,-1
;查看ProcessBuf.BufNo是否为-1,如果=-1则调用GetABufNo,得到一个空的缓冲区
jnz HaveABuf
GetABuf:
mov eax,ProcessBufA.ProcessHandle
Call GetABufNo
mov ProcessBufA.BufNo,eax
HaveABuf:
mov eax,ProcessBufA.BufNo
mov ebx,sizeof(PublicBufS)
mul ebx
mov ebx,offset PublicBufA
add ebx,eax
mov eax,[ebx] ;ebx指向当缓冲区管理队列
cmp eax,ProcessBufA.ProcessHandle
jnz GetABuf
mov eax,AllACharNum
mov [ebx+4],eax
xor eax,eax
mov ax,[ebx+10]
mov edx,eax ;当前缓冲区的字符数
add eax,ecx
cmp eax,255
ja GetABuf
;mov [ebx+8],eax
push eax
push ebx
mov eax,ProcessBufA.BufNo
shl eax,8
mov ebx,offset SaveBufferA
add ebx,eax
add ebx,edx
mov edi,[ebp+7*4]
CopyA:
mov al,[edi]
mov [ebx],al
inc ebx
inc edi
loop CopyA
pop ebx
pop eax
mov [ebx+10],ax
popad
NoAChar:
pop ecx
push byte ptr 0
jmp dword ptr ExtTextOutAretAddr
MyExtTextOutA ENDP
;---------------------------------------------------------------------------
MyDllMain proc hInstDLL:dword, reason:dword, unused:dword
.if reason == DLL_PROCESS_ATTACH
call GetCurrentProcessId
mov ProcessBufW.ProcessHandle,eax
mov ProcessBufA.ProcessHandle,eax
mov eax,-1
mov ProcessBufW.BufNo,eax ;没有使用缓冲区
mov ProcessBufA.BufNo,eax ;没有使用缓冲区
invoke GetSystemDirectory ,ADDR SystemPath ,MAX_PATH
invoke lstrcat, ADDR SystemPath,ADDR gdi32
invoke GetModuleHandle,ADDR SystemPath
cmp eax,0
jz NoLoadGDI32
mov gdiModuleHandle,eax
;获取ExtTextOutW的地址
invoke GetProcAddress,gdiModuleHandle,ADDR ExtTextOutWName
mov ExtTextOutWAddr,eax
add eax,6
mov ExtTextOutWretAddr,eax ;修改了6字节代码,所以返回到ExtTextOutW+6
;获取TextOutW的地址
invoke GetProcAddress,gdiModuleHandle,ADDR TextOutWName
mov TextOutWAddr,eax
add eax,5
mov TextOutWretAddr,eax
;获取ExtTextOutA的地址
invoke GetProcAddress,gdiModuleHandle,ADDR ExtTextOutAName
mov ExtTextOutAAddr,eax
add eax,5
mov ExtTextOutAretAddr,eax ;修改了5字节代码,所以返回到ExtTextOutA+5
;修改ExtTextOutW的代码
invoke VirtualProtect,ExtTextOutWAddr,8,PAGE_EXECUTE_READWRITE,ADDR pflOldProtect
mov ebx,ExtTextOutWAddr
mov al,0e9h
mov [ebx],al
mov eax,MyExtTextOutW
sub eax,ExtTextOutWAddr
sub eax,5
mov [ebx+1],eax
mov al,90h
mov [ebx+5],al
invoke VirtualProtect,ExtTextOutWAddr,8,pflOldProtect,ADDR temp
;修改TextOutW的代码
invoke VirtualProtect,TextOutWAddr,8,PAGE_EXECUTE_READWRITE,ADDR pflOldProtect
mov ebx,TextOutWAddr
mov al,0e9h
mov [ebx],al
call GetVersion
cmp ah,0
jz is2000
mov eax,MyTextOutWXP
jmp xp2000
is2000: mov eax,MyTextOutW2000
xp2000: sub eax,TextOutWAddr
sub eax,5
mov [ebx+1],eax
invoke VirtualProtect,TextOutWAddr,8,pflOldProtect,ADDR temp
;修改ExtTextOutA的代码
invoke VirtualProtect,ExtTextOutAAddr,8,PAGE_EXECUTE_READWRITE,ADDR pflOldProtect
mov ebx,ExtTextOutAAddr
mov al,0e9h
mov [ebx],al
mov eax,MyExtTextOutA
sub eax,ExtTextOutAAddr
sub eax,5
mov [ebx+1],eax
invoke VirtualProtect,ExtTextOutAAddr,8,pflOldProtect,ADDR temp
NoLoadGDI32:
.endif
ret
MyDllMain Endp
end MyDllMain
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -