Ejemplo n.º 1
0
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));
    }
Ejemplo n.º 2
0
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;
}