Are you taking about intercepting a function in a .dll and replacing it with your own? Hooking and detouring?
A generic example from the working example by Rings >
http://purebasic.fr/english/viewtopic.php?t=22678
Code: Select all
Global Dim Backup.b(5)
Procedure MyFunction(a.l,b.l,c.l,d.l)
< do something in my own function here>
ProcedureReturn
EndProcedure
Procedure Hook(Libname.s,FuncName.s,NewFunctionAddress)
dwAddr =GetProcAddress_(GetModuleHandle_(LibName), FuncName)
OriginalAdress=dwAddr
Result=ReadProcessMemory_(GetCurrentProcess_(), dwAddr, @Backup(0), 6, @readbytes)
Dim a.b(6)
a(0)=$e9
a(5)=$C3
dwCalc = NewFunctionAddress - dwAddr - 5
CopyMemory(@dwCalc,@a(1),4)
Result = WriteProcessMemory_(GetCurrentProcess_(), dwAddr, @a(0), 6, @written);
EndProcedure
Procedure UnHook(Libname.s,FuncName.s)
dwAddr = GetProcAddress_(GetModuleHandle_(LibName), FuncName)
Result= WriteProcessMemory_(GetCurrentProcess_(), dwAddr, @Backup(0), 6, @written);
EndProcedure
; Hook("<the dll here>, "<the function in the dll to hook>, "< call our own function instead >"
Hook("Some.dll", "Dll_Function", @MyFunction());
UnHook("Some.dll", "Dll_Function")
Or maybe more in line with your question regarding using prototypes, heres something I use for getting the Process ID (PID) of a running executable (which is in memory), you can see the use of getting the library and calling its functions and setting up the prototypes for those functions:
Code: Select all
Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Procedure GetPidByName(p_name$)
Protected hDLL.i, process_name$
Protected PEntry.PROCESSENTRY32, hTool32.i
Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot
Protected pProcess32First.PFNProcess32First
Protected pProcess32Next.PFNProcess32Next
Protected pid.i
hDLL = OpenLibrary(#PB_Any,"kernel32.dll")
If hDLL
pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot")
pProcess32First = GetFunction(hDLL,"Process32First")
pProcess32Next = GetFunction(hDLL,"Process32Next")
Else
ProcedureReturn 0
EndIf
PEntry\dwSize = SizeOf(PROCESSENTRY32)
hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0)
pProcess32First(hTool32, @PEntry)
process_name$ = Space(#MAX_PATH)
CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
If UCase(process_name$) = UCase(p_name$)
ProcedureReturn PEntry\th32ProcessID
EndIf
While pProcess32Next(hTool32, @PEntry) > 0
process_name$ = Space(#MAX_PATH)
CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
If UCase(process_name$) = UCase(p_name$)
ProcedureReturn PEntry\th32ProcessID
EndIf
Wend
CloseLibrary(hDLL)
ProcedureReturn 0
EndProcedure
Or maybe more generically:
Code: Select all
Lib_Mine = LoadLibrary_("My.dll")
If Lib_Mine
*h_Lib_Mine_Func1 = GetProcAddress_(Lib_Mine, "DLL_First_Function")
*h_Lib_Mine_Func2 = GetProcAddress_(Lib_Mine, "DLL_Second_Function")
*h_Lib_Mine_Func3 = GetProcAddress_(Lib_Mine, "DLL_Third_Function")
*h_Lib_Mine_Func4 = GetProcAddress_(Lib_Mine, "DLL_Fourth_Function")
FreeLibrary_(Lib_Mine)
EndIf
CallFunctionFast(*h_Lib_Mine_Func1,a, b)
CallFunctionFast(*h_Lib_Mine_Func2,a, b)
CallFunctionFast(*h_Lib_Mine_Func3,a, b)
CallFunctionFast(*h_Lib_Mine_Func4,a, b)
or....maybe like this:
Lib_Mine = LoadLibrary_("My.dll")
If Lib_Mine
*h_Lib_Mine_Func1 = GetProcAddress_(Lib_Mine, "DLL_First_Function")
*h_Lib_Mine_Func2 = GetProcAddress_(Lib_Mine, "DLL_Second_Function")
*h_Lib_Mine_Func3 = GetProcAddress_(Lib_Mine, "DLL_Third_Function")
*h_Lib_Mine_Func4 = GetProcAddress_(Lib_Mine, "DLL_Fourth_Function")
CallFunctionFast(*h_Lib_Mine_Func1,a, b)
CallFunctionFast(*h_Lib_Mine_Func2,a, b)
CallFunctionFast(*h_Lib_Mine_Func3,a, b)
CallFunctionFast(*h_Lib_Mine_Func4,a, b)
FreeLibrary_(Lib_Mine)
EndIf
And to show an example of use in a current project I'm using to show FPS differences between Graphics cards in the same environment in Windows Vista:
Code: Select all
; gpcomms.dll - proxy dll project from > http://www.mikoweb.eu/index.php?node=28
; injector part from hipy001 at > http://www.purebasic.fr/english/viewtopic.php?t=37607
; other parts in PureBasic form and credit goes to their original authors
Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Procedure GPSI_ShowFPS(bShowFPS.i)
Lib_gpcomms = LoadLibrary_("gpcomms.dll")
If Lib_gpcomms
*h_GPSI_ShowFPS = GetProcAddress_(Lib_gpcomms, "GPSI_ShowFPS")
ret.i = CallFunctionFast(*h_GPSI_ShowFPS, bShowFPS)
FreeLibrary_(Lib_gpcomms)
EndIf
ProcedureReturn ret
EndProcedure
Procedure.b CheckRunningExe(FileName.s)
Protected snap.i , Proc32.PROCESSENTRY32 , dll_kernel32.i
FileName = GetFilePart(FileName)
dll_kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")
If dll_kernel32
snap = CallFunction(dll_kernel32, "CreateToolhelp32Snapshot",$2, 0)
If snap
Proc32\dwSize = SizeOf(PROCESSENTRY32)
If CallFunction(dll_kernel32, "Process32First", snap, @Proc32)
While CallFunction(dll_kernel32, "Process32Next", snap, @Proc32)
If PeekS(@Proc32\szExeFile)=FileName
CloseHandle_(snap)
CloseLibrary(dll_kernel32)
ProcedureReturn #True
EndIf
Wend
EndIf
CloseHandle_(snap)
EndIf
CloseLibrary(dll_kernel32)
EndIf
ProcedureReturn #False
EndProcedure
Procedure Elevated_Cmd(app_dir.s, app_name.s)
AppVerb$ = "runas"
AppName$ = app_name
AppDir$ = app_dir
shExecInfo.SHELLEXECUTEINFO
shExecInfo\cbSize=SizeOf(SHELLEXECUTEINFO)
shExecInfo\fMask=#Null
shExecInfo\hwnd=#Null
shExecInfo\lpVerb=@AppVerb$
shExecInfo\lpFile=@AppName$
shExecInfo\lpDirectory=@AppDir$
shExecInfo\nShow=#SW_NORMAL
exe.i = ShellExecuteEx_(shExecInfo)
Delay(3000)
If CheckRunningExe(app_name) = #True
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure GetPidByName(p_name$)
Protected hDLL.i, process_name$
Protected PEntry.PROCESSENTRY32, hTool32.i
Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot
Protected pProcess32First.PFNProcess32First
Protected pProcess32Next.PFNProcess32Next
Protected pid.i
hDLL = OpenLibrary(#PB_Any,"kernel32.dll")
If hDLL
pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot")
pProcess32First = GetFunction(hDLL,"Process32First")
pProcess32Next = GetFunction(hDLL,"Process32Next")
Else
ProcedureReturn 0
EndIf
PEntry\dwSize = SizeOf(PROCESSENTRY32)
hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0)
pProcess32First(hTool32, @PEntry)
process_name$ = Space(#MAX_PATH)
CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
If UCase(process_name$) = UCase(p_name$)
ProcedureReturn PEntry\th32ProcessID
EndIf
While pProcess32Next(hTool32, @PEntry) > 0
process_name$ = Space(#MAX_PATH)
CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
If UCase(process_name$) = UCase(p_name$)
ProcedureReturn PEntry\th32ProcessID
EndIf
Wend
CloseLibrary(hDLL)
ProcedureReturn 0
EndProcedure
Procedure InjectLibA(dwProcessId.i, pszLibFile$)
hProcess.i
hThread.i
lzLibFileRemote.i
lSize.i
endSize.i
lsThreadRtn.i
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId)
If hProcess = 0 : Goto ErrHandle : EndIf
lSize = 1 + Len(pszLibFile$)
endSize = lSize
lzLibFileRemote = VirtualAllocEx_(hProcess, #Null, endSize, #MEM_COMMIT, #PAGE_READWRITE)
If lzLibFileRemote = 0 : Goto ErrHandle : EndIf
If (WriteProcessMemory_(hProcess, lzLibFileRemote, pszLibFile$, endSize, #Null) = 0) : Goto ErrHandle : EndIf
OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0)
If lsThreadRtn = 0 : Goto ErrHandle : EndIf
hThread = CreateRemoteThread_(hProcess, #Null, #Null, lsThreadRtn, lzLibFileRemote, #Null, #Null)
If (hThread = 0) : Goto ErrHandle : EndIf
WaitForSingleObject_(hThread, #INFINITE)
If lzLibFileRemote<>0
VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
MessageRequester("Inject Status", "Injection Suceeded", 0)
Else
VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
MessageRequester("Inject Status", "Injection Failed !!!", 0)
EndIf
End
ErrHandle:
CloseHandle_(hThread)
CloseHandle_(hProcess)
MessageRequester("Inject Status", "Injection Failed !!!", 0)
EndProcedure
path_game$ = "C:\Program Files\SomeApp-Game\My_App_Game\"
file_game$ = "MyApp.exe"
apprun = Elevated_Cmd(path_game$, file_game$)
Delay(10000)
dll_dir$ = GetCurrentDirectory() + "d3d9.dll"
val_pid.i = GetPidByName(file_game$)
Delay(10)
File_dll$ = dll_dir$
Delay(10)
InjectLibA(val_pid, dll_dir$)
Delay(10000)
Debug GPSI_ShowFPS(1)
Does this help at all or am I not understanding what your after? (I'm probably not understanding - I can be that way sometimes

)
Hope it helps.