Note that there are some explanatory texts on larger screens.

plurals
  1. POVB.NET Dynamic API calls x64
    primarykey
    data
    text
    <p>First of all, i'm new here so please not take the bad if I missed something. This is my first question on this forum, and I hope to get the right answer.</p> <h2>Problem description:</h2> <p>I'm trying to use CallWindowProc to call API dynamically, but as all of you know it's complicated cause CallWindowProc have limited number of arguments.So there is a need to use asm codes.With the help of various resources from the internet I was able to get the code that works, but only for x86 architecture (compiled for x86 on x64 machine).The problem is that x64 architecture strictly using __fastcall calling convention while x86 not.</p> <h2>Question:</h2> <p>I need some advices why the code below not working.I'm also tried some combinations using opcode from Asm example but without success.</p> <p><strong>Asm code {MASM 64}</strong></p> <pre><code>; 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 </code></pre> <p><strong>Code from disassembly window.</strong></p> <pre><code> 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) </code></pre> <p><strong>Vb.net code</strong></p> <pre><code> 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 = &amp;H1000 Private Const MEM_RESERVE As Integer = &amp;H2000 Private Const MEM_EXECUTE_READWRITE As Integer = &amp;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({&amp;H48, &amp;H83, &amp;HEC, &amp;H28}) '## FUNCTION PARAMETERS AddBytes({&amp;H48, &amp;HC7}) 'mov {opcode} AddBytes(BitConverter.GetBytes(CInt(Params(0)))) 'Parameter 1 (stored in 4 bytes) AddBytes({&amp;H48, &amp;H8D}) 'lea {opcode} AddBytes(BitConverter.GetBytes(CInt(Params(1)))) 'Parameter 2 (stored in 4 bytes) (address of string) AddBytes({&amp;H4C, &amp;H8D}) 'lea {opcode} AddBytes(BitConverter.GetBytes(CInt(Params(2)))) 'Parameter 3 (stored in 4 bytes) (address of string) AddBytes({&amp;H41, &amp;HB9}) 'mov {opcode} {B8+r} AddBytes(BitConverter.GetBytes(CInt(Params(3)))) 'Parameter 4 (stored in 4 bytes) '## CALL FUNCTION AddBytes({&amp;HE8}) 'call {opcode} AddBytes(BitConverter.GetBytes(CInt(FunctionAdress) - CInt(MemAdressOffset) - 16)) AddBytes({&amp;H8B, &amp;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 </code></pre> <p><em>Call function</em></p> <pre><code>Call_64("user32", "MessageBoxW", 0, Marshal.StringToHGlobalUni("Test"), Marshal.StringToHGlobalUni("Test msg!"), 0) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload