My goal is far from nefarious. After several polite attempts to try and get Lenovo to implement a proper keyboard backlight control, I've had no response. They do have a Windows Store app which adds that control, however, it's not tied to keyboard or mouse input (idle user time). I can implement that, with AutoHotKey, if I manage to call their methods.
Screenshots for reference: https://i.stack.imgur.com/pGBre.jpg
Using JetBrains I can see a quite readable code, written in .NET (I assume), my main interest is in Keyboard_Core.dll. There I can see the methods for getting and setting the keyboard backlight, but I don't understand how they work.
public unsafe uint SetKeyboardBackLightStatus(int nStatus)
{
CKeyboardLight* ckeyboardLightPtr1 = (CKeyboardLight*) <Module>.@new(4U);
CKeyboardLight* ckeyboardLightPtr2;
// ISSUE: fault handler
try
{
ckeyboardLightPtr2 = (IntPtr) ckeyboardLightPtr1 == IntPtr.Zero ? (CKeyboardLight*) 0 : <Module>.ThinkPad.CKeyboardLight.{ctor}(ckeyboardLightPtr1);
}
__fault
{
<Module>.delete((void*) ckeyboardLightPtr1);
}
<Module>.ThinkPad.CKeyboardLight.SetStatus(ckeyboardLightPtr2, (KBDLIGHT_STATUS) nStatus);
if ((IntPtr) ckeyboardLightPtr2 != IntPtr.Zero)
{
CKeyboardLight* ckeyboardLightPtr3 = ckeyboardLightPtr2;
int num = 1;
// ISSUE: cast to a function pointer type
// ISSUE: function pointer call
void* voidPtr = __calli((__FnPtr<void* (IntPtr, uint)>) *(int*) *(int*) ckeyboardLightPtr2)((uint) ckeyboardLightPtr3, (IntPtr) num);
}
return 0;
}
I don't understand where @new(4U) points to. In the decompiled declaration it says it's [StructLayout(LayoutKind.Sequential, Size = 4)]
- so I can probably work with that without any structure description. Is it later pointed to some real memory address?
I cannot figure that out, it seems that both ckeyboardLightPtr1
and ckeyboardLightPtr2
are new objects until the end of the function.
I don't know how to call a random address (function) with some prepared parameters (stack) - should I stick to AHK (then it would be a different question), try Python (another layer), PowerShell (never used it) or create a small C program?
Either way, it looks that I have to set 4 bytes somewhere in memory. Perhaps I'm chasing the wrong end and these functions just set a temporary/proxy object that is later handled by a monitor thread.
Ollydbg doesn't let me do anything with the DLL.