我在這裏沒有想法。我有一段代碼改編自http://thetechnofreak.com/technofreak/keylogger-visual-c/將鍵碼轉換爲Unicode字符。除非您嘗試從64位Windows運行32位版本,否則在任何情況下都可以正常工作。出於某種原因,pKbd-> pVkToWcharTable保持返回NULL。我已經嘗試__ptr64以及爲kbd dll路徑明確指定SysWOW64和System32。我在互聯網上發現了幾個指向這個確切或非常類似的問題的項目,但我似乎無法獲得任何解決方案(請參閱:KbdLayerDescriptor returns NULL at 64bit architecture)以下是我在Windows XP上使用mingw-32編譯的測試代碼( gcc -std = c99 Wow64Test.c),然後在Windows 7 64位上執行。在Windows XP上,我得到一個有效的指針,但是在Windows 7上,我得到了NULL。KbdLayerDescriptor pvkToWcharTable在Win64上返回NULL
***更新:所以看起來像我遇到的問題是由於mingw沒有正確實現__ptr64,因爲sizeof操作給出了4個字節,而不是由visual studio給出的8個字節。所以真正的解決方案是找出一種方法來使KBD_LONG_POINTER的大小變爲動態或至少64位,但我不確定這是否可能。有任何想法嗎?
#include <windows.h>
#include <stdio.h>
#define KBD_LONG_POINTER __ptr64
//#define KBD_LONG_POINTER
typedef struct {
BYTE Vk;
BYTE ModBits;
} VK_TO_BIT, *KBD_LONG_POINTER PVK_TO_BIT;
typedef struct {
PVK_TO_BIT pVkToBit;
WORD wMaxModBits;
BYTE ModNumber[];
} MODIFIERS, *KBD_LONG_POINTER PMODIFIERS;
typedef struct _VK_TO_WCHARS1 {
BYTE VirtualKey;
BYTE Attributes;
WCHAR wch[1];
} VK_TO_WCHARS1, *KBD_LONG_POINTER PVK_TO_WCHARS1;
typedef struct _VK_TO_WCHAR_TABLE {
PVK_TO_WCHARS1 pVkToWchars;
BYTE nModifications;
BYTE cbSize;
} VK_TO_WCHAR_TABLE, *KBD_LONG_POINTER PVK_TO_WCHAR_TABLE;
typedef struct {
DWORD dwBoth;
WCHAR wchComposed;
USHORT uFlags;
} DEADKEY, *KBD_LONG_POINTER PDEADKEY;
typedef struct {
BYTE vsc;
WCHAR *KBD_LONG_POINTER pwsz;
} VSC_LPWSTR, *KBD_LONG_POINTER PVSC_LPWSTR;
typedef struct _VSC_VK {
BYTE Vsc;
USHORT Vk;
} VSC_VK, *KBD_LONG_POINTER PVSC_VK;
typedef struct _LIGATURE1 {
BYTE VirtualKey;
WORD ModificationNumber;
WCHAR wch[1];
} LIGATURE1, *KBD_LONG_POINTER PLIGATURE1;
typedef struct tagKbdLayer {
PMODIFIERS pCharModifiers;
PVK_TO_WCHAR_TABLE pVkToWcharTable;
PDEADKEY pDeadKey;
PVSC_LPWSTR pKeyNames;
PVSC_LPWSTR pKeyNamesExt;
WCHAR *KBD_LONG_POINTER *KBD_LONG_POINTER pKeyNamesDead;
USHORT *KBD_LONG_POINTER pusVSCtoVK;
BYTE bMaxVSCtoVK;
PVSC_VK pVSCtoVK_E0;
PVSC_VK pVSCtoVK_E1;
DWORD fLocaleFlags;
BYTE nLgMax;
BYTE cbLgEntry;
PLIGATURE1 pLigature;
DWORD dwType;
DWORD dwSubType;
} KBDTABLES, *KBD_LONG_POINTER PKBDTABLES;
typedef PKBDTABLES(CALLBACK *KbdLayerDescriptor) (VOID);
int main() {
PKBDTABLES pKbd;
HINSTANCE kbdLibrary = NULL;
//"C:\\WINDOWS\\SysWOW64\\KBDUS.DLL"
//"C:\\WINDOWS\\System32\\KBDUS.DLL"
kbdLibrary = LoadLibrary("C:\\WINDOWS\\SysWOW64\\KBDUS.DLL");
KbdLayerDescriptor pKbdLayerDescriptor = (KbdLayerDescriptor) GetProcAddress(kbdLibrary, "KbdLayerDescriptor");
if(pKbdLayerDescriptor != NULL) {
pKbd = pKbdLayerDescriptor();
printf("Is Null? %d 0x%X\n", sizeof(pKbd->pVkToWcharTable), pKbd->pVkToWcharTable);
}
FreeLibrary(kbdLibrary);
kbdLibrary = NULL;
}
首先,感謝您花時間解釋所有這些!我最終採取了類似但更具動態性,並且隨後更復雜的途徑來完成相同的結果。基本上,我基於簡單的Wow64檢查計算了運行時指針填充。源代碼在公共領域完全可用:https://github.com/kwhat/libuiohook/blob/master/src/windows/input_helper.c – 2014-04-18 19:45:35