xp下对dinput8.dll 游戏键盘输入的模拟 非函数hook | 学步园

    很多游玩或许3d仿照软件为了胜过的支集表面设备运用directinput作为输出交谈电话联络。这么即使要仿照鼠标或用键盘式排字机排字来把持游玩或许3d软件举行不自觉动作作业健康状况如何才能做到呢?

我研究了用键盘式排字机排字地区。。鼠标等。
起因于模块:
运用软件:

这执意思考方式。。在DPin预调中有独一附近查询情况处置。。被电话联络的有或起作用是CKBDGGETDeVICESTANCE。 (为了有或起作用地址可以在剖析坐果中找到)

电话联络行为准则是使巩固的。:
HRESULT   UpdateInputState(void)  
{  
DWORD   i;  
if(lpKeyboard   !=   空)
{  
DIDEVICEOBJECTDATA   didod[DINPUT_BUFFERSIZE];   //   Receives   buffered   data  
DWORD   dwElements;  
HRESULT   hr;  
hr   =   DIERR_INPUTLOST;  
(人文资源) !=   DI_OK)  
{  
dwElements   =   DINPUT_BUFFERSIZE;  
hr   =   lpKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),didod,&dwElements,0);  在这里喊叫 CKbd_GetDeviceState
if   (人文资源) !=   DI_OK)  
{  

            hr   =   lpKeyboard->Acquire();  
即使落空(人文资源)
return   hr;  
}  
}  
即使落空(人文资源)
return   hr;  
}  
为(int) i=0;   i{  
//   把处置行为准则放在在这里
//   didod[i].dwOfs   指挥的键被按下或使通畅。
//   didod[i].dwData   记载此关键的的情况。,最少的音节是黄金时代的。 1   指挥的压力机,0   显示松动
//   普通用   didod[i].dwData&0x80   来测验  
}  
return   S_OK;  
}  
这么用键盘式排字机排字情况是健康状况如何购置物的呢?见上面的IDA剖析。
.text:6D18C5EA _CKbd_GetDeviceState@8 proc near        ; DATA XREF: .text:6D18C37Co
.text:6D18C5EA
.text:6D18C5EA arg_0           = dword ptr  8
.text:6D18C5EA arg_4           = dword ptr  0Ch
.text:6D18C5EA
.text:6D18C5EA                 mov     edi, edi
.text:6D18C5EC                 push    ebp
.text:6D18C5ED                 mov     ebp, esp
.text:6D18C5EF                 mov     eax, [ebp+arg_0]
.text:6D18C5F2                 mov     ecx, [eax+8]
.text:6D18C5F5                 test    byte ptr [ECX], 2
.text:6D18C5F8                 jz      short loc_6D18C60D
.text:6D18C5FA                 push    esi
.text:6D18C5FB                 mov     esi, [eax+4] ;由于随后剖析。ESI标点的内存是具有明显的键PLA的用键盘式排字机排字情况表。,00不注意压榨
.text:6D18C5FE                 push    edi
.text:6D18C5FF                 mov     edi, [ebp+arg_4]
.text:6D18C602                 push    40h  拷贝大小为0x100音节40h×4
.text:6D18C604                 pop     ecx
.text:6D18C605                 rep movsd  将用键盘式排字机排字情况完全一样的到表面收执减震器
.text:6D18C607                 pop     edi
.text:6D18C608                 xor     eax, eax
.text:6D18C60A                 pop     esi
.text:6D18C60B                 jmp     short loc_6D18C612
.text:6D18C60D ; —————————————————————————
.text:6D18C60D
.text:6D18C60D loc_6D18C60D:                           ; CODE XREF: CKbd_GetDeviceState(x,X) EJ
.text:6D18C60D                 mov     eax, 8007001Eh
.text:6D18C612
.text:6D18C612 loc_6D18C612:                           ; CODE XREF: CKbd_GetDeviceState(x,x)+21j
.text:6D18C612                 pop     ebp
.text:6D18C613                 retn    8
.text:6D18C613 _CKbd_GetDeviceState@8 endp
经过随后,可以觉悟贮存器减震器是全程变量贮存器器。 用键盘式排字机排字表对应的发报投资如次 我列出了经用的关键的。。

根本地址:6D1A448 为了地址可以经过随后ESI的使满足来随后。
6d1a4448h+2 = 1 到 6d1a4448h+bh = 0
6d1a4448h+ch = –
6d1a4448h+dh = =
6d1a4448h+1eh = a
6d1a4448h+30h = b
6d1a4448h+2eh = c
6d1a4448h+20h = d
6d1a4448h+12h = e
6d1a4448h+21h = f
6d1a4448h+22h = g
6d1a4448h+23h = h
6d1a4448h+17h = i
6d1a4448h+24h = j
6d1a4448h+25h = k
6d1a4448h+26h = l
6d1a4448h+32h = m
6d1a4448h+31h = n
6d1a4448h+18h = o
6d1a4448h+19h = p
6d1a4448h+10h = q
6d1a4448h+13h = r
6d1a4448h+1fh = s
6d1a4448h+14h = t
6d1a4448h+16h = u
6d1a4448h+2fh = v
6d1a4448h+11h = w
6d1a4448h+2dh = x
6d1a4448h+15h = y
6d1a4448h+2ch = z
6d1a4448h+1ch = enter
6d1a4448h+c8h = up
6d1a4448h+d0h = down
6d1a4448h+cbh = left
6d1a4448h+cdh = right  

这么健康状况如何随后OllyDbg正中鹄的调试呢?
咱们可以经过C32 ASM 修正CKbd_GetDeviceState 6D1880A7    8BFF            mov     edi, edi                         ;
该机具的第独一音节的有或起作用的行为准则是CC,即int。 3个断点
眼前,8BFF被修正为CCFF。 这么当手段到为了有或起作用的时分会提词发现物调试投资差错0x80000003由于提词进入调试
率先,将OllyDbg设置为体系的默许调试器。。
它将在OllyDbg稽留。
CC              int3                                     ; CKbd_GetDeviceState
FF55 8B         call    dword ptr [ebp-75]
EC              in      al, dx
8B45 08         mov     eax, dword ptr [ebp+8]
ctrl+e 修正CC到8B
单步F8到这句话。。
.text:6D18C5FB                 mov     esi, [eax+4]
再次点击F8。
ESI中有独一地址。

看一眼ESI指的是什么。。你会一下子看到其正中鹄的0个。。在这里是用键盘式排字机排字缓冲液。

现时咱们觉悟用键盘式排字机排字缓冲液的地址是规则的。。咱们可以仿照行为准则。。
率先要将行为准则拔出到要修正的男高音的中。。钩子也依从的近程线索。。有很多方式可以疏忽它。。
我在在这里运用用键盘式排字机排字钩子。
BYTE keyMap[0x100]={NULL};
BYTE *dinput8KeyMap=(BYTE*)0x24448; 用键盘式排字机排字映照区域地址偏移
在设定初值点计算缓冲液的对立投资。
HINSTANCE hDinput8 = 0;
hDinput8 = GetModuleHandle(“”);
if(!hDinput8)
{
__asm
{
mov eax,dinput8KeyMap
add eax,hDinput8
mov dinput8KeyMap,eax
}
}else
{
hDinput8 = LoadLibrary(“”);
__asm
{
mov eax,dinput8KeyMap
add eax,hDinput8
mov dinput8KeyMap,eax
}
FreeLibrary(hDinput8);
}
率先限界咱们的关键的表并写独一设定初值有或起作用。
void InitKeyMap()
{
ZeroMemory(keyMap,0x100);
keyMap[0x2] =”1”;
keyMap[0x3] =”2”;
keyMap[0x4] =”3”;
keyMap[0x5] =”4”;
keyMap[0x6] =”5”;
keyMap[0x7] =”6”;
keyMap[0x8] =”7”;
keyMap[0x9] =”8”;
keyMap[0xa] =”9”;
keyMap[0xb] =”0”;
keyMap[0xc] =”-”;
keyMap[0xd] =”=”;
keyMap[0x1e]  A
keyMap[0x30]  =”b”;
keyMap[0x2e]  =”c”;
keyMap[0x20]  =”d”;
keyMap[0x12]  =”e”;
keyMap[0x21]  =”f”;
keyMap[0x22]  =”g”;
keyMap[0x23]  =”h”;
keyMap[0x17]  =”i”;
keyMap[0x24]  =”j”;
keyMap[0x25]  =”k”;
keyMap[0x26]  =”l”;
keyMap[0x32]  =”m”;
keyMap[0x31]  =”n”;
keyMap[0x18]  =”o”;
keyMap[0x19]  =”p”;
keyMap[0x10]  =”q”;
keyMap[0x13]  =”r”;
keyMap[0x1f]  =”s”;
keyMap[0x14]  =”t”;
keyMap[0x16]  =”u”;
keyMap[0x2f]  =”v”;
keyMap[0x11]  =”w”;
keyMap[0x2d]  =”x”;
keyMap[0x15]  =”y”;
keyMap[0x2c]  =”z”;
keyMap[0x1c]  =VK_RETURN;
keyMap[0xc8]  =VK_UP;
keyMap[0xd0]  =VK_DOWN;
keyMap[0xcb]  =VK_LEFT;
keyMap[0xcd]  =VK_RIGHT;
}
构成独一用键盘式排字机排字将有或起作用设置为80。

void SetKeyDown(BYTE VK)
{
//大小写替换
即使(vk>=a) && vk<=''Z'')
{
vk|=0x20;
}
为(int) cnt=0;cnt<0x100;cnt++)
{
(KEYMAP[CNT])
{
if(keyMap[cnt]==VK)
{
dinput8KeyMap[cnt]=0x80;
break;
}
}
}
}
为了有或起作用是绝望的。。即使钥匙伸出,咱们清算0。
void SetKeyUp(BYTE VK)
{
ZeroMemory(dinput8KeyMap,0x100);
}
用键盘式排字机排字钩子i运用。这是如愿以偿的。
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{

 if(lParam==0xc0000001)
{
SetKeyDown((BYTE)wParam);
}
if(lParam==1)
{
SetKeyUp((BYTE)wParam);
}

 return CallNextHookEx(winKbd,nCode,wParam,lParam);
}
这般做了。它可以经过顺序不自觉动作把持。无论很重要
切开包围着的:
vs2005,xp sp2

发表评论

电子邮件地址不会被公开。 必填项已用*标注