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

📄 assembl.c

📁 一款压缩壳PE123的DELPHI源码 学习写壳的很好的参考
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (j==0) arg=pd->arg1;
    else if (j==1) arg=pd->arg2;
    else arg=pd->arg3;
    if (arg==NNN) break;               // All operands processed
    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 CRX:                        // Control register CRx
      case DRX:                        // Debug register DRx
        hasrm=1;
        if (op->index<8) {
          tcode[i+1]|=(char)(op->index<<3); tmask[i+1]|=0x38; };
        break;
      case RCM:                        // Integer register in command byte
      case RST:                        // FPU register (ST(i)) in command byte
        if (op->index<8) {
          tcode[i]|=(char)op->index; tmask[i]|=0x07; };
        break;
      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 MDE:                        // Destination in string op's ([EDI])
      case C01:                        // Implicit constant 1 (for shifts)
        break;                         // Simply skip implicit operands
      case MSO:                        // Source in string op's ([ESI])
      case MXL:                        // XLAT operand ([EBX+AL])
        if (op->segment!=SEG_UNDEF && op->segment!=SEG_DS)
          segment=op->segment;
        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 RR4:                        // 4-byte memory/register (register only)
      case MR8:                        // 8-byte memory/MMX register in ModRM
      case RR8:                        // 8-byte MMX register only in ModRM
      case MRD:                        // 8-byte memory/3DNow! register in ModRM
      case RRD:                        // 8-byte memory/3DNow! (register only)
        hasrm=1;
        if (op->type!=MRG) {           // Register in ModRM byte
          tcode[i+1]|=0xC0; tmask[i+1]|=0xC0;
          if (op->index<8) {
            tcode[i+1]|=(char)op->index; tmask[i+1]|=0x07; };
          break;
        };                             // Note: NO BREAK, continue with address
      case MMA:                        // Memory address in ModRM byte for LEA
      case MML:                        // Memory in ModRM byte (for LES)
      case MMS:                        // Memory in ModRM byte (as SEG:OFFS)
      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)
        hasrm=1; displacement=op->offset; anydisp=op->anyoffset;
        if (op->base<0 && op->index<0) {
          dispsize=4;                  // Special case of immediate address
          if (op->segment!=SEG_UNDEF && op->segment!=SEG_DS)
            segment=op->segment;
          tcode[i+1]|=0x05;
          tmask[i+1]|=0xC7; }
        else if (op->index<0 && op->base!=REG_ESP) {
          tmask[i+1]|=0xC0;            // SIB byte unnecessary
          if (op->offset==0 && op->anyoffset==0 && op->base!=REG_EBP)
            ;                          // [EBP] always requires offset
          else if ((constsize & 1)!=0 &&
            ((op->offset>=-128 && op->offset<128) || op->anyoffset!=0)
          ) {
            tcode[i+1]|=0x40;          // Disp8
            dispsize=1; }
          else {
            tcode[i+1]|=0x80;          // Disp32
            dispsize=4; };
          if (op->base<8) {
            if (op->segment!=SEG_UNDEF && op->segment!=addr32[op->base].defseg)
              segment=op->segment;
            tcode[i+1]|=
              (char)op->base;          // Note that case [ESP] has base<0.
            tmask[i+1]|=0x07; }
          else segment=op->segment; }
        else {                         // SIB byte necessary
          hassib=1;
          if (op->base==REG_EBP &&     // EBP as base requires offset, optimize
            op->index>=0 && op->scale==1 && op->offset==0 && op->anyoffset==0) {
            op->base=op->index; op->index=REG_EBP; };
          if (op->index==REG_ESP &&    // ESP cannot be an index, reorder
            op->scale<=1) {
            op->index=op->base; op->base=REG_ESP; op->scale=1; };
          if (op->base<0 &&            // No base means 4-byte offset, optimize
            op->index>=0 && op->scale==2 &&
            op->offset>=-128 && op->offset<128 && op->anyoffset==0) {
            op->base=op->index; op->scale=1; };
          if (op->index==REG_ESP) {    // Reordering was unsuccessfull
            strcpy(errtext,"Invalid indexing mode");
            goto error; };
          if (op->base<0) {
            tcode[i+1]|=0x04;
            dispsize=4; }
          else if (op->offset==0 && op->anyoffset==0 && op->base!=REG_EBP)
            tcode[i+1]|=0x04;          // No displacement
          else if ((constsize & 1)!=0 &&
            ((op->offset>=-128 && op->offset<128) || op->anyoffset!=0)
          ) {
            tcode[i+1]|=0x44;          // Disp8
            dispsize=1; }
          else {
            tcode[i+1]|=0x84;          // Disp32
            dispsize=4; };
          tmask[i+1]|=0xC7;            // ModRM completed, proceed with SIB
          if (op->scale==2) tcode[i+2]|=0x40;
          else if (op->scale==4) tcode[i+2]|=0x80;
          else if (op->scale==8) tcode[i+2]|=0xC0;
          tmask[i+2]|=0xC0;
          if (op->index<8) {
            if (op->index<0) op->index=0x04;
            tcode[i+2]|=(char)(op->index<<3);
            tmask[i+2]|=0x38; };
          if (op->base<8) {
            if (op->base<0) op->base=0x05;
            if (op->segment!=SEG_UNDEF && op->segment!=addr32[op->base].defseg)
              segment=op->segment;
            tcode[i+2]|=(char)op->base;
            tmask[i+2]|=0x07; }
          else segment=op->segment; };
        break;
      case IMM:                        // Immediate data (8 or 16/32)
      case IMU:                        // Immediate unsigned data (8 or 16/32)
      case VXD:                        // VxD service (32-bit only)
        if (datasize==0 && pd->arg2==NNN && (pd->bits==SS || pd->bits==WS))
          datasize=4;
        if (datasize==0) {
          strcpy(errtext,"Please specify operand size");
          goto error; };
        immediate=op->offset; anyimm=op->anyoffset;
        if (pd->bits==SS || pd->bits==WS) {
          if (datasize>1 && (constsize & 2)!=0 &&
            ((immediate>=-128 && immediate<128) || op->anyoffset!=0)) {
            immsize=1; tcode[i]|=0x02; }
          else immsize=datasize;
          tmask[i]|=0x02; }
        else immsize=datasize;
        break;
      case IMX:                        // Immediate sign-extendable byte
      case IMS:                        // Immediate byte (for shifts)
      case IM1:                        // Immediate byte
        if (immsize==2)                // To accomodate ENTER instruction
          immediate=(immediate & 0xFFFF) | (op->offset<<16);
        else immediate=op->offset;
        anyimm|=op->anyoffset;
        immsize++; break;
      case IM2:                        // Immediate word (ENTER/RET)
        immediate=op->offset; anyimm=op->anyoffset;
        immsize=2; break;
      case IMA:                        // Immediate absolute near data address
        if (op->segment!=SEG_UNDEF && op->segment!=SEG_DS)
          segment=op->segment;
        displacement=op->offset; anydisp=op->anyoffset;
        dispsize=4; break;
      case JOB:                        // Immediate byte offset (for jumps)
        jmpoffset=op->offset; anyjmp=op->anyoffset;
        jmpsize=1; break;
      case JOW:                        // Immediate full offset (for jumps)
        jmpoffset=op->offset; anyjmp=op->anyoffset;
        jmpsize=4; break;
      case JMF:                        // Immediate absolute far jump/call addr
        displacement=op->offset; anydisp=op->anyoffset; dispsize=4;
        immediate=op->segment; anyimm=op->anyoffset; immsize=2;
        break;
      case SGM:                        // Segment register in ModRM byte
        hasrm=1;
        if (op->index<6) {
          tcode[i+1]|=(char)(op->index<<3); tmask[i+1]|=0x38; };
        break;
      case SCM:                        // Segment register in command byte
        if (op->index==SEG_FS || op->index==SEG_GS) {
          tcode[0]=0x0F; tmask[0]=0xFF;
          i=1;
          if (strcmp(name,"PUSH")==0)
            tcode[i]=(char)((op->index<<3) | 0x80);
          else
            tcode[i]=(char)((op->index<<3) | 0x81);
          tmask[i]=0xFF; }
        else if (op->index<6) {
          if (op->index==SEG_CS && strcmp(name,"POP")==0) {
            strcpy(errtext,"Unable to POP CS");
            goto error; };
          tcode[i]=(char)((tcode[i] & 0xC7) | (op->index<<3)); }
        else {
          tcode[i]&=0xC7;
          tmask[i]&=0xC7; };
        break;
      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 PS0:                        // Top of FPU stack (pseudooperand)
      case PS1:                        // ST(1) (pseudooperand)
      case PCX:                        // CX/ECX (pseudooperand)
      case PDI:                        // EDI (pseudooperand in MMX extentions)
        break;                         // Simply skip preudooperands
      default:                         // Undefined type of operand
        strcpy(errtext,"Internal Assembler error");
      goto error;
    };
  };
  // Gather parts of command together in the complete command.
  j=0;
  if (lock!=0) {                       // Lock prefix specified
    model->code[j]=0xF0;
    model->mask[j]=0xFF; j++; };
  if (datasize==2 && pd->bits!=FF) {   // Data size prefix necessary
    model->code[j]=0x66;
    model->mask[j]=0xFF; j++; };
  if (addrsize==2) {                   // Address size prefix necessary
    model->code[j]=0x67;
    model->mask[j]=0xFF; j++; };
  if (segment!=SEG_UNDEF) {            // Segment prefix necessary
    if (segment==SEG_ES) model->code[j]=0x26;
    else if (segment==SEG_CS) model->code[j]=0x2E;
    else if (segment==SEG_SS) model->code[j]=0x36;
    else if (segment==SEG_DS) model->code[j]=0x3E;
    else if (segment==SEG_FS) model->code[j]=0x64;
    else if (segment==SEG_GS) model->code[j]=0x65;
    else { strcpy(errtext,"Internal Assembler error"); goto error; };
    model->mask[j]=0xFF; j++; };
  if (dispsize>0) {
    memcpy(tcode+i+1+hasrm+hassib,&displacement,dispsize);
    if (anydisp==0) memset(tmask+i+1+hasrm+hassib,0xFF,dispsize); };
  if (immsize>0) {
    if (immsize==1) l=0xFFFFFF00L;
    else if (immsize==2) l=0xFFFF0000L;
    else l=0L;
    if ((immediate & l)!=0 && (immediate & l)!=l) {
      strcpy(errtext,"Constant does not fit into operand");
      goto error; };
    memcpy(tcode+i+1+hasrm+hassib+dispsize,&immediate,immsize);
    if (anyimm==0) memset(tmask+i+1+hasrm+hassib+dispsize,0xFF,immsize); };
  i=i+1+hasrm+hassib+dispsize+immsize;
  jmpoffset=jmpoffset-(i+j+jmpsize);
  model->jmpsize=jmpsize;
  model->jmpoffset=jmpoffset;
  model->jmppos=i+j;
  if (jmpsize!=0) {
    if (ip!=0) {
      jmpoffset=jmpoffset-ip;
      if (jmpsize==1 && anyjmp==0 && (jmpoffset<-128 || jmpoffset>=128)) {
        if (longjump==0 && (jmpmode & 0x03)==0) {
          longjump=1;
          goto retrylongjump; };
        sprintf(errtext,
          "Relative jump out of range, use %s LONG form",name);
        goto error; };
      memcpy(tcode+i,&jmpoffset,jmpsize);
    };
    if (anyjmp==0) memset(tmask+i,0xFF,jmpsize);
    i+=jmpsize; };
  memcpy(model->code+j,tcode,i);
  memcpy(model->mask+j,tmask,i);
  i+=j;
  model->length=i;
  return i;                            // Positive value: length of code
error:
  model->l

⌨️ 快捷键说明

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