-
-
[原创]asprotect 2.3 vm 还原
-
2013-3-29 22:01
10648
-
由于asp的vm其实还是基于x86,所以,一套反汇编引擎就可以将其还原了。
以下自己的代码很少,几乎都是拷贝的
typedef struct _ASP_VMCODE{
uint8_t Fcode;
uint8_t nop1[2];
uint8_t mod;
uint8_t nop2[5];
uint8_t sib;
uint8_t nop3[5];
uint8_t bReloc;
uint8_t nop4[6];
uint32_t indexValue;
uint8_t nop5[2];
uint32_t dis;
uint8_t nop6[5];
uint32_t imm;
uint8_t nop7[2];
uint8_t code;
uint8_t nop8[2];
uint8_t code_;
uint8_t nop9[5];
}ASP_VMCODE;
typedef struct {
uint32_t Unknown;
uint32_t pFirstItem;
uint32_t ItemNum;
uint8_t FuncIndex[0x0A];
uint8_t FuncIndex2[0x0A];
uint32_t Funcs[0x0A];
uint32_t ItemSize;
uint32_t BaseAddr;
uint32_t RandomXX; // +50
uint32_t procID;
uint32_t Size;
ASP_VMCODE code[0];
} ASP_VMINFO;
uint32_t AsprotectVm::Parse(ASP_VMCODE* pVmcode, uint8_t* pResult) {
uint8_t mod, sib, opcode;
uint32_t instruction;
uint8_t* p = pResult;
m_code = pVmcode;
int opsizeprefix = 0, addressprefix = 0;
opcode = GetFirstPcode();
*p++ = opcode;
if (table_1[opcode] == C_PREFIX){
if (opcode == C_66)
opsizeprefix = 1;
if (opcode == C_67)
addressprefix = 1;
p++;
opcode = GetSecPcode();
*p++ = opcode;
}
mod = GetMod();
//check for test, stupid and fucking test
instruction = table_1[opcode];
if ((opcode == 0xF6) || (opcode == 0xF7)){
opcode=GetSecPcode();
if ((opcode & 0x38) != 0) //test or neg/not...
instruction = C_MODRM;
}
if (opsizeprefix)
//where was 8 still is 8 //where was 32 now is 16
if (instruction & C_DATA32){
instruction &= ~(C_DATA32);
instruction |= C_DATA16;
}
//if not relative change
if (addressprefix && !(instruction & C_REL) ){
instruction &= ~(C_DATA32);
instruction &= ~(C_DATA8);
instruction |= C_DATA16;
}
//clear relative flag
if (instruction & C_REL)
instruction &= ~(C_REL);
//fill instruction with flags from table_2 and decode it in right way
if (instruction == C_2BYTE){
opcode = GetSecPcode();
*p++ = opcode;
instruction = table_2[opcode];
//if (instruction == C_DATA32)
// size += 5;
//goto check_modrm;
}
//check_modrm:
if (instruction & C_MODRM){
*p++ = mod;
unsigned char modrm;
modrm = mod;
if ((modrm >> 6) == 0 && (modrm & 0x07) == 0x05) //modrm is folowed by 32disp
instruction |= C_DISP32;
if ((modrm >> 6) != 3 && (modrm & 0x07) == 0x04){ //sib
sib = GetSib();
*p++ = sib;
if ( (modrm >> 6) == 1 && (modrm & 0x07) == 0x04) //8bit disp after SIB(added to index)
instruction |= C_DISP8;
else if ( (modrm >> 6) == 2 && (modrm & 0x07) == 0x04) //32bit displacement after sib(added to index)
instruction |= C_DISP32;
else if ( (modrm >> 6) == 0 && (sib & 0x07) == 0x05)
instruction |= C_DISP32;
} //SIB processing
////////////////TEST CODE//////////////////
if (modrm >= 0x40 && modrm <= 0x7f && (modrm & 0x07) != 0x04)
instruction |= C_DISP8; //i cann't sure
if (modrm >= 0x80 && modrm <= 0xbf && (modrm & 0x07) != 0x04)
instruction |= C_DISP32;
///////////////TEST CODE///////////////////
}
if (instruction & C_DATA32){
*(uint32_t*)p = GetImm();
p += 4;
}
else if (instruction & C_DATA8) {
*p++ = (uint8_t)GetImm();
}
else if (instruction & C_DATA16) {
*(uint16_t*)p = (uint16_t)GetImm();
p += 2;
}
if (instruction & C_DISP32){
*(uint32_t*)p = GetDis();
p += 4;
}
else if (instruction & C_DISP8) {
*p++ = (uint8_t)GetDis();
}
else if (instruction & C_DISP16) {
*(uint16_t*)p = (uint16_t)GetDis();
p += 2;
}
if (instruction == C_UNKNOWN)
return 0;
return p- pResult;
}
uint8_t AsprotectVm::GetFirstPcode()
{
return m_code->code+ m_pInfo->RandomXX;
}
uint8_t AsprotectVm::GetSecPcode()
{
return m_code->code_+ m_pInfo->RandomXX;
}
uint8_t AsprotectVm::GetMod()
{
return m_code->mod;
}
uint8_t AsprotectVm::GetSib()
{
return m_code->sib;
}
uint32_t AsprotectVm::GetImm()
{
uint32_t value = m_code->imm;
if (value) {
value += + m_code->code;
value += m_pInfo->RandomXX;
if (m_code->bReloc) {
value += m_pInfo->BaseAddr;
}
}
return value;
}
uint32_t AsprotectVm::GetDis()
{
return m_code->dis;
}
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界