TEST(Hijack, Find) { const std::string windowName = "Hijack Window Test"; win::native::Window target(windowName); for (size_t ii = 0; ii < 10; ++ii) { core::sleep(10); target.update(); } std::shared_ptr<win::Window> found = hijack(windowName); found->setSize(math::Vector2U(500, 500)); for (size_t ii = 0; ii < 10; ++ii) { core::sleep(10); target.update(); } EXPECT_EQ(math::Vector2U(500, 500), found->getSize()); EXPECT_EQ(target.getName(), found->getName()); EXPECT_EQ(target.getPosition(), found->getPosition()); EXPECT_EQ(target.getSize(), found->getSize()); EXPECT_EQ(target.getID(), found->getID()); EXPECT_EQ(target.getNative(), found->getNative()); }
static void hijack_with_jmp(reloc_seq_t *seq, hijacksection_t *hijacksection, pefile_t *pefile) { char *old_buf; char *new_buf; DWORD newMemoryAddress = 0; DWORD dwOperand = 0; assert(seq != NULL); assert(hijacksection != NULL); if (seq->relocated) return; old_buf = va_to_ptr(pefile, seq->start); if (old_buf == NULL) { old_buf = hijacksection_va_to_ptr(hijacksection, seq->start); if (old_buf == NULL) return; } new_buf = hijack_reserve(hijacksection, seq->length + 5, &newMemoryAddress); //memcpy(new_buf, old_buf, seq->length); hijack(old_buf, seq->start, new_buf, newMemoryAddress, seq); new_buf[seq->length] = 0xe9; dwOperand = (seq->start + seq->length) - (newMemoryAddress + seq->length + 5); memcpy(&new_buf[seq->length + 1], &dwOperand, sizeof dwOperand); old_buf[0] = 0xe9; dwOperand = newMemoryAddress - (seq->start + 5); memcpy(&old_buf[1], &dwOperand, sizeof dwOperand); //printf("Reloc: %d bytes from 0x%08X to 0x%08X\n", seq->length, seq->start, newMemoryAddress); //debug_print_insn_list(seq->instructions); //printf("\n"); }
static void hijack_xor_seq(reloc_seq_t *seq, hijacksection_t *hijacksection, pefile_t *pefile) { char *old_buf; char *new_buf; DWORD newMemoryAddress = 0; DWORD dwOperand = 0; DWORD xorInsnSize = 0; assert(seq != NULL); assert(hijacksection != NULL); assert(pefile != NULL); if (seq->relocated) return; if (seq->instructions->insn->Instruction.type != insn_xor || !operands_match(seq->instructions->insn)) { return; } xorInsnSize = seq->instructions->insn->InstructionSize; seq->instructions = seq->instructions->next; seq->length -= xorInsnSize; seq->start += xorInsnSize; // See if we have enough room to plant the 6 byte "JZ rel32" instruction if (seq->length < 6) return; old_buf = va_to_ptr(pefile, seq->start); if (old_buf == NULL) { old_buf = hijacksection_va_to_ptr(hijacksection, seq->start); if (old_buf == NULL) return; } new_buf = hijack_reserve(hijacksection, seq->length + 6, &newMemoryAddress); new_buf[0] = 0xEB; // 8-bit relative JMP prefix newMemoryAddress++; // lets bypass the fake 0xEB we put in for future reference. hijack(old_buf, seq->start, &new_buf[1], newMemoryAddress, seq); // finish off the new hijack area with a jmp back to the original. new_buf[seq->length + 1] = 0xE9; // 32-bit JMP prefix dwOperand = (seq->start + seq->length) - (newMemoryAddress + seq->length + 5); memcpy(&new_buf[(seq->length) + 2], &dwOperand, sizeof dwOperand); // Put in a jz prefix to the new "real" code chunk old_buf[0] = 0x0F; old_buf[1] = 0x84; dwOperand = newMemoryAddress - (seq->start + 6); memcpy(&old_buf[2], &dwOperand, sizeof dwOperand); // if we have enough room left, put in a fake jmp or call to before the "real" code // This will throw off disassembly, especially if we put a valid instruction prefix there. if (seq->length >= xorInsnSize + 6 + 5) { // call <offset> is 5 bytes old_buf[6] = 0xE8; // 32-bit relative CALL prefix dwOperand = (newMemoryAddress - 1) - (seq->start + 6 + 5); memcpy(&old_buf[7], &dwOperand, sizeof dwOperand); } //printf("XOR Hijack: %d bytes from 0x%08X to 0x%08X\n", seq->length, seq->start, newMemoryAddress+1); //debug_print_insn_list(seq->instructions); //printf("\n"); seq->relocated = TRUE; // make a new relocatable sequence out of what has been moved so that another algorithm // may play with it further... (evil laughter) // ...This could turn out to be a dumb idea... // if (seq->length > xorInsnSize) { // reloc_seq_t *new_seq; // DWORD dwSeqOffset = 0; // reloc_insn_list_t *insn; // new_seq = ecalloc(1, sizeof *new_seq); // new_seq->instructions = seq->instructions; // new_seq->length = seq->length; // new_seq->start = newMemoryAddress + 1; // Add 1 to bypass the fake prefix we added. // // // just in case it might bite us later on, lets adjust all the addresses for the instructions // for (insn = new_seq->instructions; insn != NULL; insn = insn->next) { // insn->insn->MemoryAddress = newMemoryAddress + dwSeqOffset + 1; // dwSeqOffset += insn->insn->InstructionSize; // } // // new_seq->next = seq->next; // seq->next = new_seq; //} }