consiste en escribir una funcion de usuario publica con los parametros que tendria la funcion api, luego sobreescribir el inicio de esa funcion con la instruccion en ensablador "jmp" (salto a una direccion) para saltar a una direccion que seria la direccion de la api que queremos llamar, luego al llamar a esa funcion de usuario ejecutariamos la api, ejemplo de como llamar a ShowWindow sin haberlo puesto en la sección Declaraciones:
en un form1: (abrir el notepad para ocultarlo y volverlo visble)
form1
'form1
'agregar controles:
'1 command1
'1 command2
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Dim hModule As Long
Dim DirProc As Long
Dim DirMiFun As Long
Dim Codigo(1 To 20) As Byte
Dim Distancia As Long
Dim ViejaProte As Long
Const jmp = &HE9
Const PAGE_EXECUTE_READWRITE As Long = &H40
Private Sub Command1_Click()
Dim hwnd As Long
hwnd = FindWindow("notepad", vbNullString)
If hwnd = 0 Then
MsgBox "No se encontro el notepad", vbCritical, ""
Exit Sub
Else
Call MostrarVentana(hwnd, 5)
End If
End Sub
Private Sub Command2_Click()
Dim hwnd As Long
hwnd = FindWindow("notepad", vbNullString)
If hwnd = 0 Then
MsgBox "No se encontro el notepad", vbCritical, ""
Exit Sub
Else
Call MostrarVentana(hwnd, 0)
End If
End Sub
Private Sub Form_Load()
hModule = GetModuleHandle("user32")
DirProc = GetProcAddress(hModule, "ShowWindow")
DirMiFun = ObtenerMiDir(AddressOf MostrarVentana)
Distancia = DirProc - DirMiFun - Len(Distancia) - 1
'intenta cambiar los atributos de esa zona de memoria para sobreescribirlo
'si se sobreescribe sin cambiar los atributos la aplicacion se cerrara
If VirtualProtect(ByVal DirMiFun, 1 + Len(Distancia), PAGE_EXECUTE_READWRITE, ViejaProte) <> 0 Then
Codigo(1) = jmp
Call CopyMemory(Codigo(2), Distancia, Len(Distancia))
Call CopyMemory(ByVal DirMiFun, Codigo(1), 1 + Len(Distancia))
MsgBox "Listo", vbInformation, ""
Else
MsgBox "No se pudo cambiar los atributos de la region de memoria: " & DirMiFun & " (MostrarVentana)", vbCritical, ""
End If
Command1.Caption = "notepad visible"
Command2.Caption = "notepad oculto"
End Sub
Private Function ObtenerMiDir(FunAddress As Long) As Long
ObtenerMiDir = FunAddress
End Function
module1.bas
Option Explicit
Public Function MostrarVentana(ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
'esto es nada mas para que tenga un sitio donde sobreescribir, por
'seguridad sin que vaya afectar a otras instrucciones
Dim algo As Boolean
algo = True
algo = False
End Function
edit:
para que funcione compilen el proyecto.
No me funcionó en windows 7 :P
compila el proyecto, lo probe en XP y 7 y si me anda.
Es verdad, funciona compilado :¬¬