CODE SECTION
VER_MAJOR_WIN2K equ 5
PAGE_EXECUTE_READWRITE equ 0x40
; NTSYSAPI NTSTATUS NTAPI
; RtlMultiByteToUnicodeN (
; PWCHAR UnicodeString,
; ULONG UnicodeSize,
; PULONG ResultSize,
; PCSTR MbString,
; ULONG MbSize
; );
OSVERSIONINFO STRUCT
dwOSVersionInfoSize dd ?
dwMajorVersion dd ?
dwMinorVersion dd ?
dwBuildNumber dd ?
dwPlatformId dd ?
szCSDVersion db 128 dup ?
ENDS
DATA SECTION(".data")
ALIGN 4
dwCodePage dd 0
hNtDLL dd 0
lpFuncAddress dd ?
bInternalCall db ?
szNtDLLName db "ntdll.dll",0
szFunctionName db "RtlMultiByteToUnicodeN",0
CODE SECTION(".text")
start:
DllMain:
xor eax,eax
inc eax
retn 12
ALIGN 16
InitUnicodeLayer:
push esi
push ebx
push edi
xor ebx,ebx
mov esi,esp
sub esp,SIZEOF OSVERSIONINFO
mov D[esp + OSVERSIONINFO.dwOSVersionInfoSize],SIZEOF OSVERSIONINFO
push esp
call [kernel32:GetVersionExA]
cmp D[esp + OSVERSIONINFO.dwMajorVersion],VER_MAJOR_WIN2K
mov esp,esi
jb >E0
mov B[bInternalCall],bl
push ADDR HookMultiByteToWideChar
push ADDR szFunctionName
call HookNtDllFunc
add esi,edi
mov [lpFuncAddress],esi
E0:
pop edi
pop ebx
pop esi
retn
ALIGN 16
SetCodePage:
mov eax,[esp + 4]
mov [dwCodePage],eax
retn 4
ALIGN 16
HookMultiByteToWideChar FRAME UnicodeBuffer, WideCharLength, lpNumberOfBytesConverted, AnsiBuffer, MultiByteLength
cmp [bInternalCall],bl
je >L0
jmp [lpFuncAddress]
L0:
mov ecx,[WideCharLength]
mov edx,[UnicodeBuffer]
push ecx
push edx
mov ecx,[MultiByteLength]
mov edx,[AnsiBuffer]
push ecx
push edx
mov eax,[dwCodePage]
inc B[bInternalCall]
push ebx
push eax
call [kernel32:MultiByteToWideChar]
mov ecx,[lpNumberOfBytesConverted]
shl eax,1
mov [bInternalCall],bl
test ecx,ecx
jz >L1
mov [ecx],eax
L1:
xor eax,eax
ret
ENDF
ALIGN 16
HookNtDllFunc FRAME lpstrFuncName, lpHookAddress
mov eax,[hNtDLL]
mov ecx,[lpstrFuncName]
test eax,eax
push ecx
jnz >L0
push ADDR szNtDLLName
call [kernel32:LoadLibraryA]
mov [hNtDLL],eax
L0:
push eax
call [kernel32:GetProcAddress]
mov esi,eax
mov edi,5
push ecx
push esp
push PAGE_EXECUTE_READWRITE
push edi
push eax
call [kernel32:VirtualProtect]
mov eax,[lpHookAddress]
mov B[esi],0xE9
sub eax,esi
pop ecx
sub eax,edi
mov [esi + 1],eax
push edi
push esi
push -1
call [kernel32:FlushInstructionCache]
ret
ENDF
以上是我写的一小段HOOK代码,以挂钩RtlMultiByteToUnicodeN的方式实现本地(或目标)进程页码的实时切换。调试时我发现调用SetWindowTextA后程序仍然以系统内码显示标题,跟了一圈才知道,SetWindowTextA和SetWindowTextW分别由两个独立的系统调用提供服务,因此挂勾RtlMultiByteToUnicodeN无效。但是我不能修改由内核使用的那份NTDLL代码,因为WIN32API不能在RING0中执行。我想问一问大家,是否有人能够提供一份Ansi和Wide区别对待的系统调用列表,或者,有没有什么比较好的方法来取得这份列表?
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课