| 355 | } |
| 356 | |
| 357 | void CProcessInlineHookTable::CheckX86HookType3(cs_insn* insn, size_t j, size_t count) { |
| 358 | cs_detail* d1, * d2; |
| 359 | |
| 360 | d1 = insn[j].detail; |
| 361 | if (d1 == nullptr) |
| 362 | return; |
| 363 | if (j + 1 >= count) { |
| 364 | return; |
| 365 | } |
| 366 | d2 = insn[j + 1].detail; |
| 367 | if (d2 == nullptr) |
| 368 | return; |
| 369 | |
| 370 | if (d1->x86.operands[0].type != CS_OP_REG) |
| 371 | return; |
| 372 | |
| 373 | if (d1->x86.operands[0].access != CS_AC_WRITE) |
| 374 | return; |
| 375 | |
| 376 | if (d1->x86.operands[0].size != 4) |
| 377 | return; |
| 378 | |
| 379 | if (d1->x86.operands[1].type != CS_OP_IMM) |
| 380 | return; |
| 381 | |
| 382 | if (d1->x86.operands[1].size != 4) |
| 383 | return; |
| 384 | |
| 385 | if (d2->x86.operands[0].type != CS_OP_REG) |
| 386 | return; |
| 387 | |
| 388 | if (d2->x86.operands[0].access != CS_AC_READ) |
| 389 | return; |
| 390 | |
| 391 | if (d2->x86.operands[0].size != 4) |
| 392 | return; |
| 393 | |
| 394 | if (strcmp(insn[j + 1].mnemonic, "jmp")) |
| 395 | return; |
| 396 | |
| 397 | if (d1->x86.operands[0].reg != d2->x86.operands[0].reg) |
| 398 | return; |
| 399 | |
| 400 | ULONG targetAddress = d1->x86.operands[1].imm; |
| 401 | // �ų���Ч���ڴ��ַ |
| 402 | SIZE_T size; |
| 403 | ULONG dummy; |
| 404 | bool success = ::ReadProcessMemory(m_hProcess, (LPVOID)targetAddress, &dummy, 4, &size); |
| 405 | if (!success) |
| 406 | return; |
| 407 | |
| 408 | InlineHookInfo info; |
| 409 | info.TargetAddress = targetAddress; |
| 410 | info.TargetModule = L"Unknown"; |
| 411 | auto m = GetModuleByAddress(targetAddress); |
| 412 | if (m != nullptr) { |
| 413 | info.TargetModule = m->Path; |
| 414 | } |