Looking on the D3D11 DLLs, I see that internally all the variants implemented by the same objects.
But if you create DXGIFactory using CreateDXGIFactory (11.0 variant) the object keeps a flag telling it that it indeed 11.0 variant. I'm not clear what this flag does.
Also, in this case, the object prevent you from doing QueryInterface and upgrading to the 11.1 variant.
Tuesday, August 2, 2016
Tuesday, July 12, 2016
Thoughts on reversing C++ code
The local globals:
A method in C++ can change a variable that belongs to the object. As it is not a parameter, and not a local variable, then it is kind of global.
But it doesn't have a set location in memory, just an offset from 'this'. so you can't track it unlike a true global.
Calculated calls:
Every virtual call is calculated call. so it is difficult to know in static analysis where this calls goes to.
Virtual call table:
The VTable is saved to the executable as just a list of function pointers.
Listing xref to this list, it will point to the object constructor. And from it all the location that this object was constructed. (but not sub classes, as they have their own VTable)
Highly coupled:
Well, making a change in an object that is inside an inheritance tree is challenging.
Making a change to a method that is shared to other classes is most likely not a good idea.
You can change the class VTable itself, redirecting calls. but unless you want redirect it to null_sub, there is not much that you can do.
I need to think of a way to find which functions are used exclusively by the attacked class.
A method in C++ can change a variable that belongs to the object. As it is not a parameter, and not a local variable, then it is kind of global.
But it doesn't have a set location in memory, just an offset from 'this'. so you can't track it unlike a true global.
Calculated calls:
Every virtual call is calculated call. so it is difficult to know in static analysis where this calls goes to.
Virtual call table:
The VTable is saved to the executable as just a list of function pointers.
Listing xref to this list, it will point to the object constructor. And from it all the location that this object was constructed. (but not sub classes, as they have their own VTable)
Highly coupled:
Well, making a change in an object that is inside an inheritance tree is challenging.
Making a change to a method that is shared to other classes is most likely not a good idea.
You can change the class VTable itself, redirecting calls. but unless you want redirect it to null_sub, there is not much that you can do.
I need to think of a way to find which functions are used exclusively by the attacked class.
Wednesday, June 29, 2016
Unity's Invalid DWORD (32-bit) value problem
Apparently, the Unity developers decided that it is good idea to store floating point values in the registry.
The registry does not support floating point, but you know what it does support? Integers. so let's use that!
So they did something like:
double f;
RegSetValueExA ( KeyHandle, ValName, 0, REG_DWORD, &f, sizeof(f) )
It is just that... double is 64-bit type. DWORD is 32-bit type.
The registry does not support floating point, but you know what it does support? Integers. so let's use that!
So they did something like:
double f;
RegSetValueExA ( KeyHandle, ValName, 0, REG_DWORD, &f, sizeof(f) )
It is just that... double is 64-bit type. DWORD is 32-bit type.
Well, Windows doesn't care. For it, the type is just a label on the value, for readability. Internally, all the registry values are binary blobs.
And that's why I had to implement 64-bit DWORDs.
Tuesday, June 14, 2016
XInput's hidden functions
Inside X_Input, there are a couple of undocumented functions. You can load them not by name, but by ordinal.
I tried to find as much as I can about them:
DWORD __stdcall __ordinal(100) XInputGetStateEx(DWORD dwUserIndex, XINPUT_STATE* pState)
The same as XInputGetState, adding the "Guide" button.
#define XINPUT_GAMEPAD_GUIDE 0x0400
DWORD __stdcall __ordinal(101) XInputWaitForGuideButton(DWORD dwUserIndex, DWORD dwFlags, PVOID pUnKnown)
If dwFlags == 0 - blocking until Guide button is pressed. Otherwise, it is async.
I am not clear on how to get the async option to report.
DWORD __stdcall __ordinal(102) XInputCancelGuideButtonWait(DWORD dwUserIndex)
If XInputWaitForGuideButton was activated in async mode, this will stop it.
DWORD __stdcall __ordinal(103) XInputPowerOffController(DWORD dwUserIndex)
I think that his one is clear.
struct _XINPUT_BASE_BUS_INFORMATION
{
WORD a1;
WORD a2;
DWORD a3;
DWORD Flags; // probably
BYTE a4;
BYTE a5;
BYTE a6;
BYTE reserved;
}
DWORD __stdcall __ordinal(104) XInputGetBaseBusInformation(DWORD dwUserIndex, XINPUT_BASE_BUS_INFORMATION *pInfo)
Not working on all gamepads. It can refuse and return ERROR_DEVICE_NOT_CONNECTED, even if connected.
struct XINPUT_CAPABILITIES_EX
{
XINPUT_CAPABILITIES Capabilities;
WORD a1;
WORD a2;
WORD a3;
DWORD a4;
};
DWORD __stdcall __ordinal(108) XInputGetCapabilitiesEx(DWORD a1, DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES_EX *pCapabilities)
a1 should probably be 1.
I tried to find as much as I can about them:
DWORD __stdcall __ordinal(100) XInputGetStateEx(DWORD dwUserIndex, XINPUT_STATE* pState)
The same as XInputGetState, adding the "Guide" button.
#define XINPUT_GAMEPAD_GUIDE 0x0400
DWORD __stdcall __ordinal(101) XInputWaitForGuideButton(DWORD dwUserIndex, DWORD dwFlags, PVOID pUnKnown)
If dwFlags == 0 - blocking until Guide button is pressed. Otherwise, it is async.
I am not clear on how to get the async option to report.
DWORD __stdcall __ordinal(102) XInputCancelGuideButtonWait(DWORD dwUserIndex)
If XInputWaitForGuideButton was activated in async mode, this will stop it.
DWORD __stdcall __ordinal(103) XInputPowerOffController(DWORD dwUserIndex)
I think that his one is clear.
struct _XINPUT_BASE_BUS_INFORMATION
{
WORD a1;
WORD a2;
DWORD a3;
DWORD Flags; // probably
BYTE a4;
BYTE a5;
BYTE a6;
BYTE reserved;
}
DWORD __stdcall __ordinal(104) XInputGetBaseBusInformation(DWORD dwUserIndex, XINPUT_BASE_BUS_INFORMATION *pInfo)
Not working on all gamepads. It can refuse and return ERROR_DEVICE_NOT_CONNECTED, even if connected.
struct XINPUT_CAPABILITIES_EX
{
XINPUT_CAPABILITIES Capabilities;
WORD a1;
WORD a2;
WORD a3;
DWORD a4;
};
DWORD __stdcall __ordinal(108) XInputGetCapabilitiesEx(DWORD a1, DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES_EX *pCapabilities)
a1 should probably be 1.
Sunday, June 5, 2016
Monkey business in IMMDeviceEnumerator
winmmbase.dll's function winmmGetMidiInterfaces create a IMMDeviceEnumerator object, and the uses QueryInterface using this UUID:
"3e52272f-3c89-45f8-be26-cb3b91ab42a0"
I couldn't find why and what is this uuid is about.
"3e52272f-3c89-45f8-be26-cb3b91ab42a0"
I couldn't find why and what is this uuid is about.
Wednesday, June 1, 2016
COM objects can be elusive
When proxying a COM object, queryinterface it can be frustrating.
A program can ask for other interface, and then return to the original interface.
If you are not covering all the interfaces that the object support, a program can bypass the proxy this way.
Also, A lot of unexpected interfaces can be created using CoCreateInstance, bypassing their official "create" function.
Also, A lot of unexpected interfaces can be created using CoCreateInstance, bypassing their official "create" function.
Thursday, May 19, 2016
ChangeDisplaySettings
Dear game developers,
The next game that will call ChangeDisplaySettings / ChangeDisplaySettingsEx, will have its bits burned one by one.
This is not 1990 anymore.
Thanks.
The next game that will call ChangeDisplaySettings / ChangeDisplaySettingsEx, will have its bits burned one by one.
This is not 1990 anymore.
Thanks.
Subscribe to:
Posts (Atom)