As stated in the documentation for the IDirectDraw7::SetCooperativeLevel method, it states
You must use LoadLibrary to explicitly link to Ddraw.dll and then use GetProcAddress to access the SetCooperativeLevel method.
in the remarks. However when I attempt to do so (code below), it fails to work. Am I doing something wrong?
typedef HRESULT (*pSetCooperativeLevelFunc)(HWND, DWORD);
HMODULE ddrawLib = LoadLibrary(L"ddraw.dll");
pSetCooperativeLevelFunc SCL = (pSetCooperativeLevelFunc) GetProcAddress(
ddrawLib,
"SetCooperativeLevel"
);
if (SCL == NULL) {
// this happens
int error = GetLastError(); // 127 (ERROR_PROC_NOT_FOUND)
printf("Error getting SetCooperativeLevel function address: %i", error);
}
There is no exported SetCooperativeLevel function in ddraw.dll. Use DUMPBIN utility and check it yourself. You can get DirectDrawCreate/DirectDrawCreateEx and similar functions using GetProcAddress, but you can't extract individual methods of COM object.
Article is quite ridiculous and doesn't make sense. Perhaps it was supposed to tell you to get DirectDrawCreate from ddraw.dll or something like that, but there's little reason to do that.
Link with ddraw.lib, call DirectDrawCreate and access methods provided by IDirectDraw7 interface.
P.S. If you aren't familiar with dumpbin, I'd suggest to learn at least basic usage of this utility.
I think that's a documentation bug. It's been a long time since I used DirectDraw7, but I don't recall having to load it dynamically. It was just a method of the IDirectDraw7 interface and called like any other method.
Since DX9, ddraw.lib was completely removed from the SDK, so you need to call LoadLibrary/GetProcAddress to call DirectDrawCreate or DirectDrawEnumerate. Unfortunately MSDN got it wrong, and added the GetProcAddress remark to EVERY DirectDraw function, even the COM interfaces' methods.
Related
So recently I wanted to add an imgui interface to an example window using DirectX, so I watched on a video I had to hook the EndScene function using DirectX9sdk to be able to add my custom imgui interface.
However I have some questions:
Where can I find any documentation for the DirectX9 functions and types,( if there is any, because I do not understand why we specifically have to hook the EndScene function) or where could I find any article explaining more in depth how directX works?
I've seen two version so far of EndScene hooks one with a patternScanning function which scans a signature in the shaderapi dll and another which creates a DirectXDevice and then accesses the vtable from there; are there any sources online, or is it something we have to do ourselves?
Here is the version I have:
while (!DirectXDevice) // loops until it finds the device
DirectXDevice = **(DWORD**)(FindPattern("shaderapidx9.dll", "A1 ?? ?? ?? ?? 50 8B 08 FF 51 0C") + 0x1);
void** pVTable = *reinterpret_cast<void***>(DirectXDevice); // getting the vtable array
oEndScene = (f_EndScene)DetourFunction((PBYTE)pVTable[42], (PBYTE)Hooked_EndScene)//getting the 42th virtual function and detouring it to our own
I don't really understand what __stdcall does here, I do know it is used to call WINAPI functions but what for here?
HRESULT __stdcall Hooked_EndScene(IDirect3DDevice9* pDevice){//some code}
Note: thats the function I hook to the original endscene.
Thank you really much, I'm sorry if there are alot of questions but I really can't wrap my head around this.
How do you know which functions you need to hook?
To put it bluntly, you have to be an experienced DirectX graphics programmer to find that out. Don't expect being able to hook into a framework that you don't understand. It just so happens that EndScene will always be called after all the other draw calls on the render target.
There are tons of D3D9 programming resources available, online and in paper form. Most of them are not free. I'm afraid this is not the answer you were hoping for.
What is the deal with pattern scanning, or creating a temporary D3D9 device?
Microsoft did not put any explicit effort into making EndScene hookable. It just happens to be hookable because every normal function is hookable. You need a way to find the function in memory, because the function will not always be at the same address.
One approach is to scan for known instructions that appear inside the function. Someone needs to be the first person to find out that pattern that you can scan for. You are far from the first person to hook EndScene, so many have reverse-engineered the function before and shared searchable patterns.
NOTE: The pattern does not necessarily need to be directly inside the target function. It might also lead you to something else first, in your case, the ID3D9Device instance. The important thing is that you can find your way to the EndScene function somehow.
Another approach is to get a pointer to the function. If it was a regular C function, that would be easy. It's hard here because OOP tends to make these things hard - you have to fight your way through various interfaces to get the correct vtable.
Both methods have advantages and disadvantages -- creating a D3D9 device is safer, but also more intrusive, because the target process might not expect someone to just randomly create new devices.
Why does the hook function need __stdcall?
Since you replace the original function with your hooked version, the calling convention of the hooked function must be the same as the calling convention of the original function. The caller of EndScene expects (and was compiled with) a __stdcall convention, so the new function must also behave the same way, otherwise the stack will be corrupted. Your act of replacing the function does not change the way the caller calls it.
I would like to use FsRtlIsDbcsInExpression (https://msdn.microsoft.com/en-us/library/windows/hardware/ff546803(v=vs.85).aspx) to do wild card checking exactly the same as Windows does it natively without have to re-implement it in my program. When I use:
auto module = GetModuleHandle(TEXT("NtosKrnl.exe"));
module turns up null. From what I can find on the internet, since this is a kernel mode function, KernelGetModuleBase is required. However, this function doesn't seem to resolve automatically and there are no msdn docs on it, so I am doubtful that is the solution. Does anyone have pointers for how to use function?
GetModuleHandle for ntoskrnl is going to fail because it's not loaded into your memory space. You can only call such functions from kernel.
You might want to try for the function PathMatch spec (https://msdn.microsoft.com/en-us/library/windows/desktop/bb773727%28v=vs.85%29.aspx). It appears to do the same job.
I have a DLL given named Lib.ddl. In the dll i have a function named add that takes an integer as a parameter.
Using the windows API and by using the following class.
class WindoswAPI
{
public:
WindowsAPI();//constructor
//helper functions
~WindowsAPI();
private:
}
How do I load this library in the constructor of the class. Extract the function via helper functions, and unload the function in the destructor?
I have looked on the internet for solutions and help but i cant find any.
You should first look at LoadLibraryEx() in order to load the dll in your process, then you can use GetProcAddress() to obtain a pointer to a function by name. Note the HMODULE parameter requested from the second function is returned by the first. You have to carefully know the function signature to invoke it without causing GPFs, so don't be surprised if you have to do some debug before having it working.
First easy thing to check anyway are the return values of both functions: the first one should return something different from zero ( it actually returns the virtual address where the dll is loaded ), if it returns NULL, use GetLastError to have some hints.
The same for GetProcAddress, if it return zero something didn't work, and usually is the incorrect spelling of the function name. As I said before having back an address from GetProcAddress does not guarantee you have finished: you must know perfectly how to call the function. If you need help in discovering which name are exposed from the dll, you will find useful DUMPBIN.EXE, you should have it already available from the Visual Studio Tools command prompt.
When your code finish with the dll, you can try to unload it by using FreeLibrary().
Look at POCO C++ Libraries, it contains very nice crossplatfrom DLL-Loader to avoid hand-written workarounds and boilerplate.
Today I had to define the WIN32_MEAN_AND_LEAN preprocessor macro in a native C++ project because I decided to use boost::asio in it, and without that macro, I get build errors.
Thing is, the error I get now is OleInitialize: identifier not found. According to the MSDN, this function is used to initialize a COM library. My project is not a COM library now, but my partners say it used to be.
In this case, would it be safe to remove the call? The project uses a mix of Win32 serial port functions and boost::asio (gradually, I'll leave just boost::asio). My concern is that OleInitialize might be necessary for some Win32 calls.
This is all it is done with it:
HRESULT hOle = OleInitialize( 0 );
if( !SUCCEEDED( hOle ) )
throw "Could not initialize OLE";
The worst that will happen is COM methods may start failing, if you're still calling some. OleInitialize() calls CoInitialize() internally. Only those functions need this. The base Win32 functions (CreateWindow, CreateFile, etc) do not require this initialization.
If you don't call any COM methods (any of the CoXXX() functions) and you don't call any Ole methods (OleXXX() functions), then you should be fine if you remove it.
You should do a quick search of your code base for COM / OLE functions and make sure you're really not using those technologies anymore. Then you can make a build where you don't do this and test it to see if it still works (you have a suite of test cases, right?).
Have a look at the Docs for other things that may break that you should check on.
From IDispatch::GetTypeInfoCount
The return value obtained from the
returned HRESULT is one of the
following: [S_OK -> Success],
[E_NOTIMPL -> Failure]
And the sample at the bottom returns E_INVALIDARG and NOERROR.
As far as I see E_INVALIDARG is not S_OK, nor is it NOERROR, so what do you do? Do you check for invalid pointers or you don't?
It seems that COM is pretty much foundation for everything, and I can't find one good source of information about correct behavior of simple IDispatch. How do you approach such inconsistencies in your production code?
With COM, you should never check for specific return values unless you actually need to have special handling for those values. Instead, you should use the FAILED or SUCCEEDED macros when you just need to know if a call failed or succeeded. i.e.
HRESULT hr = ...;
if (FAILED(hr)) {
...
COM calls can often return a much wider range of error codes than is specified in the documentation. The called function is not the only source of errors. Depending on the call is actually made (in-process, out-of-process, DCOM) the COM system itself can return a whole host of errors.
NOERROR is defined to the very same value as S_OK. Checking for a null pointer before dereferencing is good style in any method but in this sample it should return E_POINTER.
Values NOERROR/S_OK and E_NOTIMPL are the most typical you should expect from that method unless you abuse the method, that list can of course omit codes like E_POINTER.
Anyway don't target for specific codes, use SUCCEEDED/FAILED macros.