PEAddingMethods<Registers_x86>::ErrorCode PEAddingMethods<Registers_x86>::injectEpCode(QList<uint64_t> &epMethods) { typedef Registers_x86 Register; PEFile *pe = dynamic_cast<PEFile*>(file); if(!pe) return ErrorCode::BinaryFileNoPe; BinaryCode<Register> code; // Wywołanie każdej z metod foreach(uint64_t offset, epMethods) { code.append(CodeDefines<Register>::movValueToReg(offset, Register::EAX), true); code.append(CodeDefines<Register>::callReg(Register::EAX)); }
typename PEAddingMethods<Register>::ErrorCode PEAddingMethods<Register>::generateCode (Wrapper<Register> *w, uint64_t &codePtr, bool isTlsCallback) { ErrorCode ec; PEFile *pe = dynamic_cast<PEFile*>(DAddingMethods<Register>::file); if(!pe) return ErrorCode::BinaryFileNoPe; if(!w) return ErrorCode::NullWrapper; uint64_t action = 0; uint64_t thread = 0; // Generowanie kodu dla akcji. if(w->detect_handler) { ec = generateCode(w->detect_handler, action); if(ec != ErrorCode::Success) return ec; } // Generowanie kodu dla funkcji wątku. ThreadWrapper<Register> *tw = dynamic_cast<ThreadWrapper<Register>*>(w); if(tw && tw->thread_actions.empty()) return ErrorCode::NoThreadAction; if(tw && !tw->thread_actions.empty()) { ec = generateThreadCode(tw->thread_actions, thread, tw->sleep_time); if(ec != ErrorCode::Success) return ec; } // Generowanie kodu BinaryCode<Register> code; // Tworzenie ramki stosu code.append(CodeDefines<Register>::startFunc); std::list<Register> rts = w->used_regs.toStdList(); bool align = false; // Zachowywanie rejestrów for(auto it = rts.begin(); it != rts.end(); ++it) { if(CodeDefines<Register>::externalRegs.contains(*it)) { code.append(CodeDefines<Register>::saveRegister(*it)); align = !align; } } // Wyrównanie do 16 w przypadku x64 if(std::is_same<Register, Registers_x64>::value && align) code.append(CodeDefines<Register>::reserveStackSpace(CodeDefines<Register>::align16Size)); // Ładowanie parametrów if(!w->dynamic_params.empty()) { DJsonParser parser(DSettings::getSettings().getDescriptionsPath<Register>()); Wrapper<Register> *func_wrap = parser.loadInjectDescription<Register>(windowsApiLoadingFunction); if(!func_wrap) return ErrorCode::ErrorLoadingFunctions; uint64_t get_functions = 0; ec = generateCode(func_wrap, get_functions); delete func_wrap; if(ec != ErrorCode::Success) return ec; ec = generateParametersLoadingCode(code, get_functions, w->dynamic_params, thread); if(ec != ErrorCode::Success) return ec; } // Doklejanie właściwego kodu QByteArray binCode; ec = compileCode(w->code, binCode); if(ec != ErrorCode::Success) return ec; code.append(binCode); // Handler if(action) { Register cond = w->ret; int act_idx = CodeDefines<Register>::internalRegs.indexOf(cond); Register act = act_idx == -1 ? CodeDefines<Register>::internalRegs[0] : CodeDefines<Register>::internalRegs[(act_idx + 1) % CodeDefines<Register>::internalRegs.length()]; generateActionConditionCode(code, action, cond, act); } // Wyrównanie do 16 w przypadku x64 if(std::is_same<Register, Registers_x64>::value && align) code.append(CodeDefines<Register>::clearStackSpace(CodeDefines<Register>::align16Size)); // Przywracanie rejestrów for(auto it = rts.rbegin(); it != rts.rend(); ++it) { if(CodeDefines<Register>::externalRegs.contains(*it)) code.append(CodeDefines<Register>::restoreRegister(*it)); } // Niszczenie ramki stosu i ret code.append(CodeDefines<Register>::endFunc); if(isTlsCallback && !std::is_same<Register, Registers_x64>::value) code.append(CodeDefines<Register>::retN(3 * CodeDefines<Register>::stackCellSize)); else code.append(CodeDefines<Register>::ret); codePtr = pe->injectUniqueData(code, codePointers, relocations); return codePtr == 0 ? ErrorCode::PeOperationFailed : ErrorCode::Success; }