⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm.cpp

📁 Ollydbg环境下的一款插件源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  FileName    :   VM.cpp
//  Version     :   0.10
//  Author      :   Luo Cong
//  Date        :   2004-10-28 22:30:12
//  Comment     :   first version started on 2004-10-23 19:01:11
//
///////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "OllyMachine.h"
#include "VM.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#ifndef RefreshOD
#define RefreshOD()     Broadcast(WM_USER_CHALL, 0, 0)
#endif

#ifndef SetRetVal
#define SetRetVal(lRetVal)  m_Cpu.reg[REG_00] = (lRetVal)
#endif

#ifndef ReturnToOD
#define ReturnToOD()    m_VMStatus = MCS_BACKTOOD
#endif

#define EREV32(x) ((((x) & 0xFF000000) >> 24) | \
                   (((x) & 0x00FF0000) >> 8)  | \
                   (((x) & 0x0000FF00) << 8)  | \
                   (((x) & 0x000000FF) << 24))
#define FIXENDIAN32(x) (x) = EREV32((ulong)x)
#define FIXENDIAN16(x) (x) = ((((ushort)(x)) >> 8) | ((ushort)((x) << 8)))
#define EREV24(x) ((((x) & 0x00FF0000) >> 16) |\
                   (((x) & 0x0000FF00))       |\
                   (((x) & 0x000000FF) << 16))
#define FIXENDIAN24(x) (x) = EREV24((ulong)x)

const char *g_szVMErr[] =
{
    "Fatal error: divided by ZERO!!!",      // VM_ERR_DIV_ZERO
    // VM_ERR_OUT_OF_REG_RANGE:
    "Register index out of range!\nMust be: REG00 < reg <= REG64",
    // VM_ERR_EMBEDDED_ASM_CODE_TOO_BIG
    "Embedded asm code size too big!\n\n"
    "Please separate your embedded asm code into several block.",
};

void CVM::Initialize()
{
    int i;

    // init code
    m_Code = NULL;
    m_lCodeSize = 0;

    // init data
    m_Data = NULL;
    m_lDataSize = 0;

    // init CPU
    m_Cpu.eip = 0;
    m_Cpu.eflags.value = 0;
    m_Cpu.esp = 0;
    m_Cpu.modrm = 0;
    for (i = 0; i < REGISTER_COUNTS; ++i)
        m_Cpu.reg[i] = 0;

    m_lBreakpointLabel = -1;
    m_lInt3BreakpointLabel = -1;
    m_lHWBreakpointLabel = -1;
    m_lMemBreakpointLabel = -1;
    m_lExceptionLabel = -1;
    m_lOldEip = -1;
    m_VMStatus = MCS_BAD;

    // init freebuffer
    m_FreeBuffer = (char *)malloc(FREEBUFFER_SIZE + 1);
    if (m_FreeBuffer)
        m_FreeBuffer[0] = '\0';

    // init stack pointer
    m_lStackPointer = STACK_SIZE;

    m_ucOrigCode[0] = '\0';
    m_ulOrigCodeLen = 0;

    m_listMallocMemAddr.RemoveAll();
    m_listVirtualAllocExAddr.RemoveAll();
}

void CVM::Reset()
{
    CVM::~CVM();
    Initialize();
}

const char *CVM::GetMnemonicName(
    /* [in] */  const int i
) const
{
    if (0 <= i && i <= MNEMONIC_COUNTS)
        return m_Mnemonics[i];
    else
        return NULL;
}

int CVM::GetMnemonicLen(
    /* [in] */  MNEMONICTYPE MneType
) const
{
    return m_nMnemonicLen[MneType];
}

const char *CVM::GetRegisterName(
    /* [in] */  const int i
) const
{
    if (0 <= i && i <= REGISTER_COUNTS)
        return m_Registers[i];
    else
        return NULL;
}

int CVM::GetRegisterIndex(
    /* [size_is][in] */ const UINT unRegNameSize,
    /* [in] */          const char *szRegName,
    /* [out] */         int *nRegIndex
)
{
    ASSERT(szRegName);
    ASSERT(nRegIndex);

    int i;

    if ((strlen(szRegName) + 1) != unRegNameSize)
        return 0;

    for (i = 0; i < REGISTER_COUNTS; ++i)
    {
        if (0 == strcomp(szRegName, m_Registers[i]))
        {
            *nRegIndex = i;
            return 1;
        }
    }

    return 0;
}

const unsigned char CVM::opcode(
    /* [in] */  const MNEMONICTYPE MneType
) const
{
    return *(unsigned char *)&MneType;
}

int CVM::SetCode(
    /* [in] */  const long lCodeSize,
    /* [in] */  const unsigned char *Code
)
{
    ASSERT(Code);

    int nRetResult = 0;

    m_Code = (unsigned char *)malloc(lCodeSize);
    OM_PROCESS_ERROR(m_Code);

    m_lCodeSize = lCodeSize;

    memcpy(m_Code, Code, lCodeSize);

    nRetResult = 1;
Exit0:
    return nRetResult;
}

int CVM::SetData(
    /* [in] */  const long lDataSize,
    /* [in] */  const char *Data
)
{
    ASSERT(Data);

    int nRetResult = 0;

    m_Data = (char *)malloc(lDataSize + FREEBUFFER_SIZE + 1);
    OM_PROCESS_ERROR(m_Data);

    m_lDataSize = lDataSize;

    memcpy(m_Data, Data, lDataSize);

    nRetResult = 1;
Exit0:
    return nRetResult;
}

inline int CVM::CheckDataAddrValid(
    /* [in] */  const long lDataOffset
)
{
    if ((0 > lDataOffset) || (lDataOffset >= m_lDataSize))
        return 0;
    return 1;
}

void CVM::JumpToBreakpointLabel()
{
    if (-1 != m_lBreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lBreakpointLabel;
    }
}

void CVM::JumpToInt3BreakpointLabel()
{
    if (-1 != m_lInt3BreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lInt3BreakpointLabel;
    }
    else if (-1 != m_lBreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lBreakpointLabel;
    }
}

void CVM::JumpToHWBreakpointLabel()
{
    if (-1 != m_lHWBreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lHWBreakpointLabel;
    }
    else if (-1 != m_lBreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lBreakpointLabel;
    }
}

void CVM::JumpToMemBreakpointLable()
{
    if (-1 != m_lMemBreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lMemBreakpointLabel;
    }
    else if (-1 != m_lBreakpointLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lBreakpointLabel;
    }
}

void CVM::JumpToExceptionLabel()
{
    if (-1 != m_lExceptionLabel)
    {
        m_lOldEip = m_Cpu.eip;
        m_Cpu.eip = m_lExceptionLabel;
    }
}

MCSTATUS CVM::GetStatus()
{
    return m_VMStatus;
}

void CVM::SetStatus(MCSTATUS status)
{
    m_VMStatus = status;
}

inline MCSTATUS CVM::CheckAddressRange(
    /* [in] */  long eip
)
{
    if (eip < 0 || eip > m_lCodeSize)
        return MCS_BAD;
    else
        return MCS_RUNNING;
}

int CVM::SetFreeBuffer(
    /* [len_is][in] */  const long lBufferLen
)
{
    if (lBufferLen > FREEBUFFER_SIZE)
        return 0;

    m_Cpu.reg[REG_FREEBUFFERREG] = m_lDataSize;
    m_Cpu.reg[REG_FREEBUFFERSIZEREG] = lBufferLen;

    if (0 != lBufferLen)
    {
        memcpy(&m_Data[m_lDataSize], m_FreeBuffer, lBufferLen);
        m_lDataSize += lBufferLen;
    }
    m_Data[m_lDataSize] = '\0';

    return 1;
}

inline int CVM::Push(
    /* [in] */  const long lValue
)
{
    if (0 == m_lStackPointer)
        return 0;

    --m_lStackPointer;

    m_Cpu.esp -= 4;

    m_Stack[m_lStackPointer] = lValue;

    return 1;
}

inline int CVM::Pop(
    /* [out] */ long *lpValue
)
{
    ASSERT(lpValue);

    if (STACK_SIZE == m_lStackPointer)
        return 0;

    *lpValue = m_Stack[m_lStackPointer];

    m_Cpu.esp += 4;

    ++m_lStackPointer;

    return 1;
}

int CVM::IsODReg(
    /* [in] */  const REGISTERTYPE *rt
)
{
    ASSERT(rt);

    switch (*rt)
    {
    case OD_REG_EAX:
    case OD_REG_ECX:
    case OD_REG_EDX:
    case OD_REG_EBX:
    case OD_REG_ESP:
    case OD_REG_EBP:
    case OD_REG_ESI:
    case OD_REG_EDI:
    case OD_REG_EIP:
    case OD_REG_EFLAGS_CF:
    case OD_REG_EFLAGS_PF:
    case OD_REG_EFLAGS_AF:
    case OD_REG_EFLAGS_ZF:
    case OD_REG_EFLAGS_SF:
    case OD_REG_EFLAGS_DF:
    case OD_REG_EFLAGS_OF:
        return 1;
    default:
        return 0;
    }
}

int CVM::DoLDS(
    /* [in] */  const long eip
)
{
    int nRetCode;

    REGISTERTYPE rt_dest;
    long lDataOffset;

    lDataOffset = *(long *)&m_Code[eip + 5];

    rt_dest = (REGISTERTYPE)*(long *)&m_Code[eip + 1];

    nRetCode = IsODReg(&rt_dest);
    // do not allow use OD registers here!
    if (nRetCode)
        return 0;

    m_Cpu.reg[rt_dest] = lDataOffset;

    return 1;
}

int CVM::DoPop(
    /* [in] */  const long eip
)
{
    int nRetResult = 0;
    int nRetCode;

    REGISTERTYPE rt;

    rt = (REGISTERTYPE)*(long *)&m_Code[eip + 1];

    nRetCode = Pop(&m_Cpu.reg[rt]);
    OM_PROCESS_ERROR(nRetCode);

    nRetCode = SetODReg(&rt, m_Cpu.reg[rt]);
    OM_PROCESS_ERROR(nRetCode);

    nRetResult = 1;
Exit0:
    return nRetResult;
}

int CVM::DoPush(
    /* [in] */  const long eip
)
{
    int nRetResult = 0;
    int nRetCode;

    REGISTERTYPE rt_dest;

    m_Cpu.modrm = *(unsigned char *)&m_Code[eip + 1];

    switch (m_Cpu.modrm)
    {
    case MR_MEM:
        nRetCode = Push(*(long *)&m_Code[eip + 2]);
        OM_PROCESS_ERROR(nRetCode);
        break;

    case MR_REG:
        nRetCode = GetODReg();
        OM_PROCESS_ERROR(nRetCode);
        rt_dest = (REGISTERTYPE)*(long *)&m_Code[eip + 2];
        nRetCode = Push(m_Cpu.reg[rt_dest]);
        OM_PROCESS_ERROR(nRetCode);
        break;

    default:
        goto Exit0;
    }

    nRetResult = 1;
Exit0:
    return nRetResult;
}

int CVM::IR(
    /* [in] */  const long eip,
    /* [in] */  const MNEMONICTYPE MneType
)
{
    int nRetResult = 0;
    int nRetCode;

    REGISTERTYPE rt_dest;
    long lVal_dest;

    nRetCode = GetODReg();
    OM_PROCESS_ERROR(nRetCode);

    rt_dest = (REGISTERTYPE)*(long *)&m_Code[eip + 1];
    lVal_dest = m_Cpu.reg[rt_dest];

    switch (MneType)
    {
    case MC_INC:
        ++lVal_dest;
        break;
    case MC_DEC:
        --lVal_dest;
        m_Cpu.eflags.zf = (0 == lVal_dest);
        break;
    case MC_NOT:
        lVal_dest = !lVal_dest;
        break;
    default:
        goto Exit0;
    }

    m_Cpu.reg[rt_dest] = lVal_dest;

    nRetCode = SetODReg(&rt_dest, lVal_dest);
    OM_PROCESS_ERROR(nRetCode);

    nRetResult = 1;
Exit0:
    return nRetResult;
}

int CVM::GetODReg()
{
    t_thread* pt = Findthread(Getcputhreadid());
    if (NULL == pt)
        return 0;

    m_Cpu.reg[OD_REG_EAX] = pt->reg.r[0];
    m_Cpu.reg[OD_REG_ECX] = pt->reg.r[1];
    m_Cpu.reg[OD_REG_EDX] = pt->reg.r[2];
    m_Cpu.reg[OD_REG_EBX] = pt->reg.r[3];
    m_Cpu.reg[OD_REG_ESP] = pt->reg.r[4];
    m_Cpu.reg[OD_REG_EBP] = pt->reg.r[5];
    m_Cpu.reg[OD_REG_ESI] = pt->reg.r[6];
    m_Cpu.reg[OD_REG_EDI] = pt->reg.r[7];
    m_Cpu.reg[OD_REG_EIP] = pt->reg.ip;
    m_Cpu.reg[OD_REG_EFLAGS_CF] = !!(pt->reg.flags & 0x0001);
    m_Cpu.reg[OD_REG_EFLAGS_PF] = !!(pt->reg.flags & 0x0004);
    m_Cpu.reg[OD_REG_EFLAGS_AF] = !!(pt->reg.flags & 0x0010);
    m_Cpu.reg[OD_REG_EFLAGS_ZF] = !!(pt->reg.flags & 0x0040);
    m_Cpu.reg[OD_REG_EFLAGS_SF] = !!(pt->reg.flags & 0x0080);
    m_Cpu.reg[OD_REG_EFLAGS_DF] = !!(pt->reg.flags & 0x0400);
    m_Cpu.reg[OD_REG_EFLAGS_OF] = !!(pt->reg.flags & 0x0800);

    return 1;
}

int CVM::SetReg(
    /* [in] */  const REGISTERTYPE *rt_dest,
    /* [in] */  const REGISTERTYPE *rt_src,
    /* [in] */  long  lVal_dest,
    /* [in] */  long  lVal_src,
    /* [in] */  const MNEMONICTYPE MneType
)
{
    ASSERT(rt_dest);

    int nRetResult = 0;
    int nRetCode;

    switch (MneType)
    {
    case MC_MOV:
        if (rt_src)
        {
            m_Cpu.reg[*rt_dest] = m_Cpu.reg[*rt_src];
            lVal_dest = lVal_src;
        }
        else
        {
            m_Cpu.reg[*rt_dest] = lVal_src;
            lVal_dest = lVal_src;
        }
        goto Exit1;

    case MC_ADD:
        m_Cpu.eflags.cf = lVal_dest < lVal_src;
        lVal_dest += lVal_src;
        break;

    case MC_SUB:
        m_Cpu.eflags.cf = lVal_dest < lVal_src;
        m_Cpu.eflags.zf = (0 == (lVal_dest - lVal_src));
        lVal_dest -= lVal_src;
        break;

    case MC_MUL:
        lVal_dest *= lVal_src;
        break;

    case MC_DIV:
        if (0 == lVal_src)
        {
            ShowErrMsg(g_szVMErr[VM_ERR_DIV_ZERO]);
            return 0;
        }
        lVal_dest /= lVal_src;
        break;

    case MC_XCHG:
        // a = a ^ b
        lVal_dest = lVal_dest ^ lVal_src;
        // b = b ^ a
        lVal_src  = lVal_src  ^ lVal_dest;
        // a = a ^ b
        lVal_dest = lVal_dest ^ lVal_src;
        m_Cpu.reg[*rt_src] = lVal_src;
        break;

    case MC_AND:
        m_Cpu.eflags.cf = 0;
        m_Cpu.eflags.zf = (0 == (lVal_dest - lVal_src));
        lVal_dest &= lVal_src;
        break;

    case MC_OR:
        m_Cpu.eflags.cf = 0;
        m_Cpu.eflags.zf = (0 == (lVal_dest - lVal_src));
        lVal_dest |= lVal_src;
        break;

    case MC_XOR:
        m_Cpu.eflags.cf = 0;
        m_Cpu.eflags.zf = (0 == (lVal_dest - lVal_src));
        lVal_dest ^= lVal_src;
        break;

    case MC_SHL:
        lVal_dest <<= lVal_src;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -