首先,我是新来的,所以如果我错过了什么,请不要把坏事当回事。 这是我在这个论坛上的第一个问题,我希望得到正确答案。
我正在尝试使用CallWindowProc来动态调用API,但是因为你们都知道它很复杂,因为CallWindowProc的参数数量有限。所以需要使用asm代码。借助互联网上的各种资源我能够获得有效的代码,但仅适用于x86架构(在x64机器上为x86编译)。问题是x64架构严格使用__fastcall调用约定而x86不是。
我需要一些建议,为什么下面的代码不起作用。我也尝试使用Asm示例的操作码进行一些组合,但没有成功。
Asm代码{MASM 64}
; Sample x64 Assembly Program
; Chris Lomont 2009 www.lomont.org
extrn ExitProcess: PROC ; external functions in system libraries
extrn MessageBoxA: PROC
.data
caption db 'Test', 0
message db 'Test msg!', 0
.code
Start PROC
sub rsp,28h ; shadow space, aligns stack
mov rcx, 0 ; hWnd = HWND_DESKTOP
lea rdx, message ; LPCSTR lpText
lea r8, caption ; LPCSTR lpCaption
mov r9d, 0 ; uType = MB_OK
call MessageBoxA ; call MessageBox API function
mov ecx, eax ; uExitCode = MessageBox(...)
call ExitProcess
Start ENDP
End
来自反汇编窗口的代码。
sub rsp,28h ; shadow space, aligns stack
000000013F4C1010 48 83 EC 28 sub rsp,28h
mov rcx, 0 ; hWnd = HWND_DESKTOP
000000013F4C1014 48 C7 C1 00 00 00 00 mov rcx,0
lea rdx, message ; LPCSTR lpText
000000013F4C101B 48 8D 15 E3 2F 00 00 lea rdx,[message (13F4C4005h)]
lea r8, caption ; LPCSTR lpCaption
000000013F4C1022 4C 8D 05 D7 2F 00 00 lea r8,[caption (13F4C4000h)]
mov r9d, 0 ; uType = MB_OK
000000013F4C1029 41 B9 00 00 00 00 mov r9d,0
call MessageBoxA ; call MessageBox API function
000000013F4C102F E8 18 00 00 00 call MessageBoxA (13F4C104Ch)
mov ecx, eax ; uExitCode = MessageBox(...)
000000013F4C1034 8B C8 mov ecx,eax
call ExitProcess
000000013F4C1036 E8 0B 00 00 00 call ExitProcess (13F4C1046h)
Vb.net代码
Imports System.Runtime.InteropServices
Module CallApiByName64
#Region "Declaration"
#Region "Functions"
Private Declare Unicode Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcW" (ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Private Declare Unicode Function GetModuleHandle Lib "kernel32.dll" Alias "GetModuleHandleW" (ByVal moduleName As String) As IntPtr
Private Declare Unicode Function LoadLibraryEx Lib "kernel32.dll" Alias "LoadLibraryExW" (ByVal lpFileName As String, ByVal hFile As IntPtr, ByVal dwFlags As Integer) As IntPtr
Private Declare Function FreeLibrary Lib "kernel32.dll" Alias "FreeLibrary" (ByVal hModule As IntPtr) As Integer
Private Declare Function VirtualAlloc Lib "kernel32.dll" Alias "VirtualAlloc" (ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal flAllocationType As Integer, ByVal flProtect As Integer) As IntPtr
Private Declare Function VirtualFree Lib "kernel32.dll" Alias "VirtualFree" (ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal dwFreeType As Integer) As Integer
Private Declare Function GetProcAddress Lib "kernel32.dll" Alias "GetProcAddress" (ByVal hModule As IntPtr, ByVal methodName As String) As IntPtr
Private Declare Sub RtlMoveMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByVal Destination As IntPtr, ByVal Source() As Byte, ByVal Length As Integer)
#End Region
#Region "Constants"
Private Const MEM_COMMIT As Integer = &H1000
Private Const MEM_RESERVE As Integer = &H2000
Private Const MEM_EXECUTE_READWRITE As Integer = &H40
#End Region
#End Region
Dim FunctionAdress As IntPtr
Dim MemAdressOffset As IntPtr
Function Call_64(ByVal sLib As String, ByVal sMod As String, ByVal ParamArray Params() As IntPtr) As IntPtr
Dim MemAdress As IntPtr
'## CODE
FunctionAdress = GetProcAddress(LoadLibraryEx(sLib, IntPtr.Zero, 0), sMod)
If FunctionAdress = 0 Then Exit Function
MemAdress = VirtualAlloc(IntPtr.Zero, 256, MEM_COMMIT Or MEM_RESERVE, MEM_EXECUTE_READWRITE)
MemAdressOffset = MemAdress
'## PREPARE STACK
AddBytes({&H48, &H83, &HEC, &H28})
'## FUNCTION PARAMETERS
AddBytes({&H48, &HC7}) 'mov {opcode}
AddBytes(BitConverter.GetBytes(CInt(Params(0)))) 'Parameter 1 (stored in 4 bytes)
AddBytes({&H48, &H8D}) 'lea {opcode}
AddBytes(BitConverter.GetBytes(CInt(Params(1)))) 'Parameter 2 (stored in 4 bytes) (address of string)
AddBytes({&H4C, &H8D}) 'lea {opcode}
AddBytes(BitConverter.GetBytes(CInt(Params(2)))) 'Parameter 3 (stored in 4 bytes) (address of string)
AddBytes({&H41, &HB9}) 'mov {opcode} {B8+r}
AddBytes(BitConverter.GetBytes(CInt(Params(3)))) 'Parameter 4 (stored in 4 bytes)
'## CALL FUNCTION
AddBytes({&HE8}) 'call {opcode}
AddBytes(BitConverter.GetBytes(CInt(FunctionAdress) - CInt(MemAdressOffset) - 16))
AddBytes({&H8B, &HC8}) ' mov ecx,eax
'% IGNORE %
Dim DumpBytes(CInt(MemAdressOffset) - CInt(MemAdress)) As Byte
Marshal.Copy(MemAdress, DumpBytes, 0, CInt(MemAdressOffset) - CInt(MemAdress))
'% END %
'## EXECUTE CODE
Call_64 = CallWindowProc(MemAdressOffset, 0, 0, 0, 0)
End Function
Private Sub AddBytes(ByVal Data() As Byte)
RtlMoveMemory(MemAdressOffset, Data, Data.Length)
MemAdressOffset = CInt(MemAdressOffset) + Data.Length
End Sub
End Module
通话功能
Call_64("user32", "MessageBoxW", 0, Marshal.StringToHGlobalUni("Test"), Marshal.StringToHGlobalUni("Test msg!"), 0)