int TestDetourCopyInstruction(PBYTE pbSrcInstruction, PCHAR pszFunction) { PBYTE pbSrc = pbSrcInstruction; ULONG nIns = 0; if (pszFunction) { printf("%s:\n", pszFunction); } for (; nIns < 4096; nIns++) { BYTE rbDst[128]; PVOID pbDstPool = (PVOID)(rbDst + sizeof(rbDst)); LONG lExtra = 0; PVOID pbTarget = NULL; ULONG cbStep = (ULONG)((PBYTE)DetourCopyInstruction(rbDst, &pbDstPool, pbSrc, &pbTarget, &lExtra) - pbSrc); printf(" %p:", pbSrc); DumpMemoryFragment(rbDst, cbStep, 10); printf(" "); DumpMemoryFragment(rbDst, cbStep, 10); if (pbTarget) { if (pbTarget == DETOUR_INSTRUCTION_TARGET_DYNAMIC) { printf(" Dynamic\n"); } else { printf(" %p%c\n", pbTarget, (pbTarget >= s_pbBegin && pbTarget < s_pbLimit) ? ' ' : '!'); } } else { printf("\n"); } if (pbTarget && pbTarget != DETOUR_INSTRUCTION_TARGET_DYNAMIC) { if (pbTarget > pbSrc && pbTarget >= s_pbBegin && pbTarget < s_pbLimit ) { (void) new BasicBlockLink((PBYTE)pbTarget, NULL); } } if (IsTerminate(pbSrc)) { break; } pbSrc += cbStep; } return nIns; }
void TestDetourCopyInstruction(PBYTE pbSrcInstruction, PCHAR pszFunction) { PBYTE pbSrc = pbSrcInstruction; if (pszFunction) { printf("%s:\n", pszFunction); } for (ULONG nIns = 0; nIns < 4096; nIns++) { BYTE rbDst[128]; LONG lExtra = 0; PBYTE pbTarget = NULL; ULONG cbStep = DetourCopyInstructionEx(rbDst, pbSrc, &pbTarget, &lExtra) - pbSrc; printf(" %8lx:", pbSrc); DumpMemoryFragment(rbDst, cbStep, 10); printf(" "); DumpMemoryFragment(rbDst, cbStep, 10); if (pbTarget) { if (pbTarget == DETOUR_INSTRUCTION_TARGET_DYNAMIC) { printf(" Dynamic\n"); } else { printf(" %8lx\n", pbTarget); } } else { printf("\n"); } if (pbTarget && pbTarget != DETOUR_INSTRUCTION_TARGET_DYNAMIC) { if (pbTarget > pbSrc) { (void) new BasicBlockLink(pbTarget, NULL); } } if (IsTerminate(pbSrc)) { break; } pbSrc += cbStep; } }
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR lpszCmdLine, int nCmdShow) { (void)hprev; (void)hinst; (void)lpszCmdLine; (void)nCmdShow; #ifdef DETOURS_IA64 #error Feature not supported in this release. #endif // DETOURS_IA64 #if defined(DETOURS_X64) || defined(DETOURS_X86) // First we check the pre-canned TestCodes from disasm.asm // PBYTE pbBegin = (PBYTE)DetourCodeFromPointer(TestCodes, NULL); printf("%p:\n", pbBegin); for (PBYTE pbTest = pbBegin;;) { if (pbTest[0] != 0xcc) { // int 3 printf("%08x ", pbTest - pbBegin); DumpMemoryFragment(pbTest, 8, 8); printf("\n"); printf("failed on last.\n"); return 1; } pbTest++; if (pbTest[0] == 0x70 || pbTest[0] == 0x71) { printf("[%p]:\n", pbTest); } BYTE rbDst[128]; PVOID pbDstPool = (PVOID)(rbDst + sizeof(rbDst)); LONG lExtra = 0; PVOID pbTarget = NULL; PBYTE pbNext = (PBYTE)DetourCopyInstruction(rbDst, &pbDstPool, pbTest, &pbTarget, &lExtra); LONG cbTest = (LONG)(pbNext - pbTest); printf("%08x ", pbTest - pbBegin); DumpMemoryFragment(pbTest, cbTest, 12); printf("[%16p] ", pbTarget); DumpMemoryFragment(rbDst, cbTest + lExtra, 11); printf("\n"); if (pbTest[cbTest] != 0xcc) { printf("failed!\n"); return 1; } pbTest += cbTest; if (pbTest[0] == 0xcc && pbTest[1] == 0xcc) { break; } } #if 0 // Then we check all of the code we can find in user32.dll // HINSTANCE hInst = LoadLibrary("user32.dll"); printf("Loaded: user32.dll: %p\n", hInst); s_pbBegin = (PBYTE)hInst; s_pbLimit = s_pbBegin + DetourGetModuleSize(hInst); PBYTE pbEntry = DetourGetEntryPoint(hInst); (VOID) new BasicBlockLink(pbEntry, "user32.dll"); DetourEnumerateExports(hInst, NULL, ExportCallback); ULONG nIns = 0; for (BasicBlockLink *pLink = BasicBlockLink::GetListHead(); pLink; pLink = pLink->Next()) { nIns += TestDetourCopyInstruction(pLink->m_pbEntry, pLink->m_pszName); if (nIns > 100000) { break; } } printf("Disassembled %d instructions.\n", nIns); #endif #endif // DETOURS_X86 || DETOURS_X64 #ifdef DETOURS_ARM #error Feature not supported in this release. #endif // DETOURS_ARM return 0; }