📄 vm.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// 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 + -