首页
社区
课程
招聘
[原创]x86机器码识别程序
发表于: 2007-3-29 00:08 28572

[原创]x86机器码识别程序

2007-3-29 00:08
28572

【  标题  】 x86机器码识别程序
【  作者  】 linxer
【  环境  】 xp + vc6
【  声明  】 本人学疏才浅,失误之处敬请诸位大侠赐教!

题外话:以前曾做过虚拟机脱壳方面的研究,不过后来由于某些原因,没有再研究下去。以前也想继续搞下去,苦于没有时间。近日,在不可抗力作用下与女友分手......逼与无奈,准备重新研究这个东西,这次准备做一个功能更加强大的虚拟机,使之具有解一些加密壳能力。本人对壳的认识十分肤浅(会的一点都忘了),深知要完成这个任务会遇到很多技术问题,希望能得到各位高人的指点,故借本文在此show下自己qq:3568599,不出意外,本人也会在此共享一些研究成果;也以此文献给昔日女友,祝幸福!

其实,以下代码只是本人整理的,它来源于ollydbg反汇编器源码(http://www.pediy.com/sourcecode/disassemblers/disasm/disasm.zip可下),以下代码看起来比较乱,有意往下看的同志最好先揉下眼睛哈:)

#define u8 unsigned char
#define s8 char

#define u16 unsigned short int
#define s16 short int

#define u32 unsigned int
#define s32 int

//每条汇编指令详细信息
typedef struct tagDisasmCodeInfo
{
        u16                nPrefixes;        //前缀码
        u16                nSize;                //指令长度(含前缀码)
        u8 *                pOpcodeAdd;        //operand或modR/M字节前一个字节地址
        void *                pCmdDetail;        //指令详细描述
}DisasmCodeInfo, *PDisasmCodeInfo;

u8 * g_disasmbuf = NULL;  //待反汇编的pe文件缓冲区指针
u32  g_disasmLength = 0;  //待反汇编的pe文件长度

DisasmCodeInfo g_disamInfo; //保存当前正在反汇编的代码的详细信息
t_cmddata  *    g_pcmddata;  //保存当前被反汇编指令的opcode信息

u32 g_nException;                        //当前指针在反汇编中是否出现异常
u32 g_nDatasize;                        //operand数据大小
u32 g_nAddrsize;                        //operand地址大小
u32 g_nRepPrefix;                        //标识rep前缀
u32 g_nPrefixLen;                        //opcode前缀码长度

void init_disam_opcode(PDisasmCodeInfo p)
{
        g_nException = 0;        //清除异常标志
        g_nDatasize = 4;        //32位系统默认操作数大小
        g_nAddrsize = 4;        //32位系统默认地址大小
        g_nRepPrefix = 0;        //默认是0
        g_nPrefixLen = 0;

        memset((void *)p, 0, sizeof(DisasmCodeInfo));
}

//初始化反汇编器
void init_disam_machine(u8 * pPEBuf, u32 nPELen)
{
        g_disasmbuf = pPEBuf;
        g_disasmLength = nPELen;
}

//把反汇编器工作状态设置成默认
void default_disam_machine()
{
        g_disasmbuf = NULL;
        g_disasmLength = 0;

        memset((void *)&g_disamInfo, 0, sizeof(DisasmCodeInfo));
        g_pcmddata = NULL;
}

//前缀码识别函数
//如果前缀码不冲突返回0,否则返回-1
u32 prefix_recognise(u8 ** pSrc, u32 * pSize)
{
        u32 nIsPrefix;                //当前字节是否还是opcode的前缀码
        u32 nSegPrefix = 0;        //当前opcode含有段跨越前缀的个数
        u32 nRepeated = 0;        //是否前缀重复

        for(; *pSize > 0; )
        {
                nIsPrefix = 1;        //假定当前字节还是前缀码
               
                switch(**pSrc)
                {
                        /*本人愚见,以下文字请用批判眼光看待:由于现在win32系统内存采用flat模式,win把描述表中的段基地址都填为0,段的界限都为4GB,因此段寄存器的作用不是很大了,在OD中可以看到这些段寄存器的值,gs是0,cs是0x1b,fs是0x3b与SEH有关,其它的均是0x23,除fs外,其它的可以看成等同,gs未用,所以具体识别出什么段前缀码已经没有什么意义了,不过fs还是要另眼看待的*/
                case 0x64: //fs段跨越前缀
                        g_disamInfo.nPrefixes |= FSPrefix; //FSPrefi是fs前缀标志
                case 0x26: //es段跨越前缀
                case 0x2E: //cs段跨越前缀
                case 0x36: //ss段跨越前缀
                case 0x3E: //ds段跨越前缀
                case 0x65: //gs段跨越前缀
                        nSegPrefix++;
                        break;
                case 0x66:
                        if(g_nDatasize == 4)
                        {
                                g_nDatasize = 2;
                                g_disamInfo.nPrefixes |= DataPrefix; //DataPrefix是操作数大小前缀标志
                        }
                        else
                        {
                                nRepeated = 1;
                        }
                        break;
                case 0x67:
                        if(g_nAddrsize == 4)
                        {
                                g_nAddrsize = 2;
                                g_disamInfo.nPrefixes |= AddPrefix; //AddPrefix是地址大小前缀标志
                        }
                        else
                        {
                                nRepeated = 1;
                        }
                        break;
                case 0xF0: //lock前缀只对smp系统有用,这里忽略
                        break;
                case 0xF2:
                        if(g_nRepPrefix == 0)
                        {
                                g_nRepPrefix = 0xF2;
                                g_disamInfo.nPrefixes |= REPNEPrefix; //REPNEPrefix是repne前缀标志
                        }
                        else
                        {
                                nRepeated = 1;
                        }
                        break;
                case 0xF3:
                        if(g_nRepPrefix == 0)
                        {
                                g_nRepPrefix = 0xF3;
                                g_disamInfo.nPrefixes |= REPEPrefix; //REPEPrefix是rep前缀标志
                        }
                        else
                        {
                                nRepeated = 1;
                        }
                        break;
                default:
                        nIsPrefix = 0;
                        break;
                }
               
                if(nRepeated == 1 || nSegPrefix > 1)        //说明前缀重复冲突
                {
                        g_nException = 1; //异常
                        return -1;
                }
               
                if(nIsPrefix == 1)  
                {
                        g_nPrefixLen++;   //前缀长度计数加1
                }
                else
                {
                        //识别前缀码,直到非前缀码
                        break;
                }
               
                (*pSrc)++;
                (*pSize)--;
        }

        return 0;
}

u32 Get3dnowsuffix(u8 * cmd, u32 size)
{
        int c,sib;
        unsigned long offset;
        if(size < 3) return -1;               //因为3DNow指令长度至少是3,小于3则出错
        offset = 3;
        c = cmd[2] & 0xC7;                    //去掉ModR/M域的opcode
        // Register in ModM - general-purpose, MMX or 3DNow!
        if ((c & 0xC0)==0xC0)
                ;
        // 16-bit addressing mode, SIB byte is never used here.
        else if (g_nAddrsize == 2) {
                if (c==0x06)                       // Special case of immediate address
                        offset+=2;
                else if ((c & 0xC0)==0x40)         // 8-bit signed displacement
                        offset++;
                else if ((c & 0xC0)==0x80)         // 16-bit unsigned displacement
                        offset+=2;
                ; }
        // Immediate 32-bit address.
        else if (c==0x05)                    // Special case of immediate address
                offset+=4;
        // 32-bit address with SIB byte.
        else if ((c & 0x07)==0x04) {         // SIB addresation
                if (size<4) return -1;             // Suffix outside the memory block
                sib=cmd[3]; offset++;
                if (c==0x04 && (sib & 0x07)==0x05)
                        offset+=4;                       // Immediate address without base
                else if ((c & 0xC0)==0x40)         // 8-bit displacement
                        offset+=1;
                else if ((c & 0xC0)==0x80)         // 32-bit dislacement
                        offset+=4;
                ; }
        // 32-bit address without SIB byte
        else if ((c & 0xC0)==0x40)
                offset+=1;
        else if ((c & 0xC0)==0x80)
                offset+=4;
        if (offset>=size) return -1;         // Suffix outside the memory block
        return cmd[offset];       
}

//x86机器码识别函数
//src是汇编起始位置
//srcsize可以反汇编的长度
//返回值是本次反汇编字节数
u32 disasm_one_opcode(u8 *src, u32 srcsize)
{
        u32 nMemoryOnly = 1;                   //operand只能在内存中标识
        u32 nCommand;
        u32 nSIB;

        u32 nMin;
        u32 size = srcsize;
       
        u32 is3dnow = 0;               //是否反汇编了AMD 3DNow指令
       
        u32 operand;                   //索引操作数
       
        u32 hasrm = 0;                 //是否出现ModR/M
        u32 hassib = 0;                //是否出现SIB
        u32 dispsize = 0;              //displacement字段大小
        u32 immsize = 0;               //immedate字段大小
       
        u32 i, j, arg;
        u32 code;
        const t_cmddata *pd;
       
        //opcode前缀码扫描
        if(0 != prefix_recognise(&src, &size)) //出现冲突前缀码
        {
                return 1; // 跳过一个字节重新反汇编
        }
       
        //opcode最长为3个字节
        code = 0;
        nMin = min(size, 3);
        if(0 != g_nRepPrefix)        //如有rep前缀,也算作opcode
        {
                code = g_nRepPrefix;
                memcpy((char *)&code + 1, src, nMin);
        }
        else
        {
                memcpy((void *)&code, src, nMin);
        }
       
        //查找当前opcode对应的指令信息(这里不反汇编vxd指令)
        for(pd = cmddata; pd->mask != 0; pd++)
        {
                if(((code ^ pd->code) & pd->mask) == 0) break;
        }
       
       
        //如果查到的是AMD 3DNow指令,则还要继续查找,因为3DNow指令系列是通过ModR/M来区分的
        if((pd->type & C_TYPEMASK) == C_NOW)
        {
                is3dnow = 1;
                j = Get3dnowsuffix(src, size);
                if(j < 0)
                {
                        g_nException = 1;
                }
                else
                {
                        for( ; pd->mask != 0; pd++)
                        {
                                if(((code ^ pd->code) & pd->mask) != 0)                continue;
                                if(((u8 *)&(pd->code))[2] == j)                                break;
                        }
                }
        }

        g_pcmddata = (t_cmddata *)pd; //查找到的opcode详细信息
       
        //当前opcode非法
        if(pd->mask == 0)
        {
                //非法
                if(size < 2)
                {
                        g_nException = 1;
                }
                else
                {
                        g_nException = 1;
                }
        }
        else
        {
                //不非法情况       
                if(pd->len == 2)
                {
                        if(size == 0)
                        {
                                g_nException = 1;
                        }
                        else
                        {
                                g_nPrefixLen++; //对两个字节opcode,g_nPrefixLen其实不能加1的,
                                src++;
                                size--;
                        }
                }

                g_disamInfo.pOpcodeAdd = src;
                g_disamInfo.pCmdDetail = (void *)pd;
               
                if(size == 0)
                {
                        g_nException = 1;
                }
               
                if((pd->bits & WW) != 0 && (*src & WW) == 0)
                        g_nDatasize = 1;
                else if((pd->bits & W3) != 0 && (*src & W3) == 0)
                        g_nDatasize = 1;
                else if((pd->bits & FF) != 0)
                        g_nDatasize = 2;
               
                //识别operand
                for(operand = 0; operand < 3; operand++)
                {
                        nMemoryOnly = 1;
                       
                        if(g_nException != 0)        break;        //如果有错误
                       
                        //获取operand类型
                        if(operand == 0)        arg = (u8)pd->arg1;
                        else if(operand == 1)        arg = (u8)pd->arg2;
                        else                        arg = (u8)pd->arg3;
                       
                        if(arg == NNN)                break;        //没有operand了
                       
                        switch(arg)
                        {
                        case REG:                      // Integer register in Reg field
                        case RG4:                      // Integer 4-byte register in Reg field
                        case RMX:                      // MMX register MMx
                        case R3D:                      // 3DNow! register MMx
                        case SGM:                      // Segment register in ModRM byte
                                if(size < 2) g_nException = 1;
                                hasrm = 1;
                                break;
                        case RCM:                      // Integer register in command byte
                        case RAC:                      // Accumulator (AL/AX/EAX, implicit)
                        case RAX:                      // AX (2-byte, implicit)
                        case RDX:                      // DX (16-bit implicit port address)
                        case RCL:                      // Implicit CL register (for shifts)
                        case RS0:                      // Top of FPU stack (ST(0))
                        case RST:                      // FPU register (ST(i)) in command byte
                        case MSO:                      // Source in string op's ([ESI])
                        case MDE:                      // Destination in string op's ([EDI])
                        case MXL:                      // XLAT operand ([EBX+AL])
                        case PRN:                      // Near return address (pseudooperand)
                        case PRF:                      // Far return address (pseudooperand)
                        case PAC:                      // Accumulator (AL/AX/EAX, pseudooperand)
                        case PAH:                      // AH (in LAHF/SAHF, pseudooperand)
                        case PFL:                      // Lower byte of flags (pseudooperand)
                        case PCX:                      // CX/ECX (pseudooperand)
                        case PDI:                      // EDI (pseudooperand in MMX extentions)
                        case PS0:                      // Top of FPU stack (pseudooperand)
                        case PS1:                      // ST(1) (pseudooperand)
                        case SCM:                      // Segment register in command byte
                        case C01:                      // Implicit constant 1 (for shifts)
                                break;                       
                        case MRG:                      // Memory/register in ModRM byte
                        case MRJ:                      // Memory/reg in ModRM as JUMP target
                        case MR1:                      // 1-byte memory/register in ModRM byte
                        case MR2:                      // 2-byte memory/register in ModRM byte
                        case MR4:                      // 4-byte memory/register in ModRM byte
                        case MR8:                      // 8-byte memory/MMX register in ModRM
                        case MRD:                      // 8-byte memory/3DNow! register in ModRM
                                nMemoryOnly = 0;
                        case MMA:                      // Memory address in ModRM byte for LEA
                        case MML:                      // Memory in ModRM byte (for LES)
                        case MM6:                      // Memory in ModRm (6-byte descriptor)
                        case MMB:                      // Two adjacent memory locations (BOUND)
                        case MD2:                      // Memory in ModRM byte (16-bit integer)
                        case MB2:                      // Memory in ModRM byte (16-bit binary)
                        case MD4:                      // Memory in ModRM byte (32-bit integer)
                        case MD8:                      // Memory in ModRM byte (64-bit integer)
                        case MDA:                      // Memory in ModRM byte (80-bit BCD)
                        case MF4:                      // Memory in ModRM byte (32-bit float)
                        case MF8:                      // Memory in ModRM byte (64-bit float)
                        case MFA:                      // Memory in ModRM byte (80-bit float)
                        case MFE:                      // Memory in ModRM byte (FPU environment)
                        case MFS:                      // Memory in ModRM byte (FPU state)
                        case MFX:                      // Memory in ModRM byte (ext. FPU state)
                        case MMS:                      // Memory in ModRM byte (as SEG:OFFS)
                        case RR4:                      // 4-byte memory/register (register only)
                        case RR8:                      // 8-byte MMX register only in ModRM
                        case RRD:                      // 8-byte memory/3DNow! (register only)
                                if(arg == RR4 || arg == RR8 || arg == RRD)
                                {
                                        if((src[1] & 0xC0) != 0xC0) g_nException = 1;
                                }

                                if(size < 2)        g_nException = 1;
                                hasrm = 1;        //有modR/M
                                nCommand = src[1] & 0xC7;        //modR/M字段去掉opcode部分
                                if((nCommand & 0xC0) == 0xC0)        //operand是寄存器
                                {
                                        if(nMemoryOnly == 1)        g_nException = 1;
                                }
                                else if(g_nAddrsize == 2)        //16位寻址模式
                                {
                                        if(nCommand == 0x06)
                                        {
                                                dispsize = 2;
                                                if(size < 4)        g_nException = 1;        //4=1opcode+1modR/M+2disp
                                        }
                                        else
                                        {
                                                if((nCommand & 0xC0) == 0x40)        //mod=01
                                                {
                                                        if(size < 3)        g_nException = 1;
                                                        dispsize=1;
                                                }
                                                else if((nCommand & 0xC0) == 0x80)        //mod=10
                                                {
                                                        if(size < 4)        g_nException = 1;
                                                        dispsize = 2;
                                                }
                                        }
                                }
                                else if(nCommand == 0x05)        //32位寻址模式(无寄存器基址)
                                {
                                        dispsize = 4;
                                        if(size < 6)        g_nException = 1;        //6=1opcode+1modR/M+4disp
                                }
                                else if((nCommand & 0x07) == 0x04)        //32位寻址模式(有SIB字段)
                                {
                                        nSIB = src[2];
                                        hassib = 1;

                                        if(nCommand == 0x04 && (nSIB & 0x07) == 0x05)        //立即数寻址
                                        {
                                                dispsize = 4;
                                                if(size < 7)        g_nException = 1;
                                        }
                                        else        //非立即数寻址
                                        {
                                                if((nCommand & 0xC0) == 0x40)        //mod=01
                                                {
                                                        dispsize = 1;
                                                        if(size < 4)        g_nException = 1;
                                                }
                                                else if((nCommand & 0xC0) == 0x80)        //mod=10
                                                {
                                                        dispsize = 4;
                                                        if(size < 7)        g_nException = 1;
                                                }
                                        }
                                }
                                else        //32位寻址模式(无SIB字段)
                                {
                                        if((nCommand & 0xC0) == 0x40)        //mod=01
                                        {
                                                dispsize = 1;
                                                if(size < 3)        g_nException = 1;
                                        }
                                        else if((nCommand & 0xC0) == 0x80)        //mod=10
                                        {
                                                dispsize = 4;
                                                if(size < 6)        g_nException = 1;
                                        }
                                }
                                break;                       
                        case IMM:                      // Immediate data (8 or 16/32)
                        case IMU:                      // Immediate unsigned data (8 or 16/32)
                                if((pd->bits & SS) != 0 && (*src & 0x02) != 0)
                                {
                                        immsize += 1; //因为一个指令中可能会有两个立即数,故这里用累加,不是赋值
                                        if(size < 1 + hasrm + hassib + dispsize + immsize) g_nException = 1;//这个1是opcode
                                }
                                else
                                {
                                        immsize += g_nDatasize;
                                        if(size < 1 + hasrm + hassib + dispsize + immsize) g_nException = 1;
                                }
                                break;
                        case IMX:                      // Immediate sign-extendable byte
                        case IMS:                      // Immediate byte (for shifts)
                        case IM1:                      // Immediate byte
                                immsize += 1;
                                if(size < 1 + hasrm + hassib + dispsize + immsize) g_nException = 1;
                                break;
                        case IM2:                      // Immediate word (ENTER/RET)
                                immsize += 2;
                                if(size < 1 + hasrm + hassib + dispsize + immsize) g_nException = 1;
                                break;
                        case VXD:                      // VxD service (32-bit only)
                                immsize += 4;
                                if(size < 1 + hasrm + hassib + dispsize + immsize) g_nException = 1;
                                break;
                        case IMA:                      // Immediate absolute near data address
                                if(size < 1 + g_nAddrsize)        g_nException = 1;
                                dispsize = g_nAddrsize;
                                break;
                        case JOB:                      // Immediate byte offset (for jumps)
                                if(size < 1 + 1)        g_nException = 1;
                                dispsize = 1;
                                break;
                        case JOW:                      // Immediate full offset (for jumps)
                                if(size < g_nDatasize + 1)        g_nException = 1;
                                dispsize = g_nDatasize;
                                break;               
                        case JMF:                      // Immediate absolute far jump/call addr
                                if(size < 1 + g_nAddrsize + 2)        g_nException = 1;
                                dispsize = g_nAddrsize;
                                immsize = 2;               // Non-trivial but allowed interpretation
                                break;
                        case CRX:                      // Control register CRx
                        case DRX:                      // Debug register DRx
                                if((src[1] & 0xC0) != 0xC0)        g_nException = 1;
                                hasrm = 1;
                                break;
                        default:
                                g_nException = 1;
                                break;
                        }
                }
        }

        if(1 == is3dnow)
        {
                if(immsize!=0) g_nException = 1;
                else immsize=1;
        }

        if(g_nException != 0)        //出错
        {
                size--;
        }
        else
        {
                size -= 1 + hasrm + hassib + dispsize + immsize;
        }
       
        return (srcsize - size);               // Returns number of recognized bytes
}

大致用法如下:

init_disam_machine(pExePEBuf, imageSize);

init_disam_opcode(&g_disamInfo);
nInstructionLen = disasm_one_opcode(char *buf, u32 nBufLen);


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (28)
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
虚拟机脱壳的思想是好的,但如果壳在未解密完代码的时候访问系统API怎么解决?
2007-3-29 09:38
0
雪    币: 47147
活跃值: (20410)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
最初由 linxer 发布
题外话:以前曾做过虚拟机脱壳方面的研究,不过后来由于某些原因,没有再研究下去。以前也想继续搞下去,苦于没有时间。近日,在不可抗力作用下与女友分手......逼与无奈,准备重新研究这个东西,这次准备做一个功能更加强大的虚拟机,使之具有解一些加密壳能力。

........


同情一下,观注你的虚拟脱壳技术的进展
2007-3-29 09:45
0
雪    币: 615
活跃值: (1202)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
最初由 linxer 发布
近日,在不可抗力作用下与女友分手......逼与无奈,准备重新研究这个东西,这次准备做一个功能更加强大的虚拟机

........


人世间还有什么比幸福更重要,同情你。

linxer研究到这个程度已经很厉害了。
2007-3-29 09:52
0
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
5
最初由 dwing 发布
虚拟机脱壳的思想是好的,但如果壳在未解密完代码的时候访问系统API怎么解决?


这就需要仿真一些系统api了
2007-3-29 10:01
0
雪    币: 707
活跃值: (1301)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
6
对以你的失恋表示同感同情!
偶也是过来人! 你真是化悲伤为力量! 这是很好的表现!

祝你找到一个真心爱你的人!

爱很伤人,但要是转换为力量! 我想你比超人还强!

兄弟加油//世上不止她是女人!
2007-3-29 12:37
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
7
关注!
2007-3-29 21:10
0
雪    币: 1946
活跃值: (248)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
8
顶................
2007-4-1 03:56
0
雪    币: 383
活跃值: (41)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
9
问世间情为何物,直叫人生死相许!挨~!
2007-4-1 11:29
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
10
这份代码好象缺少了一张大表?

为了填充一个内部结构而使用一个巨大的SELECT CASE语句,好象用太多代码了。在处理大量指令的时候,速率不太好吧?

西裤哥在壳里逆出来的那段代码用的方法感觉不错。直接将指令的相关信息保存在表里的对应元素中,查表便立刻得到相关信息了。
2007-4-1 11:51
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
虽然仿真的方法很好,但系统API数量太庞大了,也不能只仿真常用的,有的病毒专门调用一些可能一辈子都用不着的API,比如GetTapeParameters,然后根据错误参数的返回值来解密代码,还有许多意想不到的API,比如COM/COM+,.NET体系.所以我想仿真API的方法有点不现实,.
还有一些壳使用复杂的运算,正常启动时间需要5秒,那么虚拟机至少就要50秒才能执行完.
还有壳使用多线程互相配合SMC.
其实我也不想给楼主泼冷水,只不过这些都已经是实事了.真正受虚拟机乖乖检查的程序一般都是无害的.
2007-4-1 12:03
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
12
真正受虚拟机乖乖检查的程序一般都是无害的

这句话太经典了
2007-4-1 12:50
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
13
我觉得在SSDT仿真,重定向I/O操作就可以了

主要问题还是脱壳完成的判定、慢速和EPO
2007-4-1 12:56
0
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
14
首先要承认,我对大多数壳的特性都不了解,这个东西我能不能搞成,说实话,我也没有底,现在只是抱着研究的态度;也知道这个东西要做的比较好,会异常复杂,也很有难度,呵呵,所以也希望能得到各位的帮助。
因为虚拟cpu上并不安装OS,所以有意义程序真正要在上面跑起来都是不可能的,很多壳搞不定也是正常的,不过好在有些壳,用的api不是很多,脱这些壳应该不会遇到太多问题吧
当然也可能对一些特殊的壳,进行特殊的处理,写一些特殊的模拟模块,不过这会牺牲程序的通用性
还有就是,我已经准备支持多线程,希望能脱一些基于多线程技术的壳,不过,我对这些壳不是很了解,还待详细分析它们的特性,也不知道会不会有成果
虽然前景很不明朗,不过,偶最近是准备搞这个东东了
2007-4-1 20:50
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
这写要慢慢的学习。。。。我只是一个才鸟
2007-4-2 14:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
同情加顶,呵呵
2007-9-16 02:17
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
17
原来在看Themida的VM时,曾经考虑过能否用虚拟机来
辅助变形代码的清理,没有想清楚,编程工夫也不够,linxer
觉得是否可行?
2007-9-16 10:01
0
雪    币: 1946
活跃值: (248)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
18
弱弱的说一句,不大可行。。
感觉用编译优化技术可能会好一点。。考算法功底了。。
2007-9-16 10:25
0
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
19
从昨天起,才开始接触Themida,对它不了解,我也是想用虚拟机来脱,还没有看到VM那块,不好回答,不过目前,我不太看好它

我以前弄这个,里面没有OS,全要自己仿真,很麻烦,开始弄的时候,自己对壳也不熟悉,现在发现有些OS特性的仿真对一些猛壳,失效,要重新改写

对themida还不了解,如果被辅助清理变形代码里,没有用到OS的一些特性,或者用的很简单的话,可以把要清理的代码放到里面运行,把它的动作行为找出来,至于怎么清理,什么时候清理结束这些,我还不懂
2007-9-16 11:35
0
雪    币: 226
活跃值: (15)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
我看好你哟
2007-9-16 11:45
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
支持支持,虽然枯涩难懂1
2007-9-16 15:55
0
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
22
俺是新手,正在学习
2007-9-20 11:26
0
雪    币: 1136
活跃值: (683)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
对虚拟机脱壳技术关注中。。。。。。。。。。。。。
天涯何处无芳草同情你一下linxer
2007-9-28 11:37
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
既然关注。就多去实践吧。
在linxer和OD的帮助下。完成了识别。
再次言重感谢。
过几日将奉上OD的文档。已经在翻译中了。
谢谢!
2007-9-28 14:45
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
我怎么觉得你是女人
2007-10-1 18:10
0
游客
登录 | 注册 方可回帖
返回
//