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

📄 assembl.c

📁 一款压缩壳PE123的DELPHI源码 学习写壳的很好的参考
💻 C
📖 第 1 页 / 共 5 页
字号:


#define STRICT

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include <dir.h>
#include <math.h>
#include <float.h>
#pragma hdrstop

#include "disasm.h"

////////////////////////////////////////////////////////////////////////////////
///////////////////////////// ASSEMBLER FUNCTIONS //////////////////////////////

// Scanner modes.
#define SA_NAME        0x0001          // Don't try to decode labels
#define SA_IMPORT      0x0002          // Allow import pseudolabel

// Types of input tokens reported by scanner.
#define SCAN_EOL       0               // End of line
#define SCAN_REG8      1               // 8-bit register
#define SCAN_REG16     2               // 16-bit register
#define SCAN_REG32     3               // 32-bit register
#define SCAN_SEG       4               // Segment register
#define SCAN_FPU       5               // FPU register
#define SCAN_MMX       6               // MMX register
#define SCAN_CR        7               // Control register
#define SCAN_DR        8               // Debug register
#define SCAN_OPSIZE    9               // Operand size modifier
#define SCAN_JMPSIZE   10              // Jump size modifier
#define SCAN_LOCAL     11              // Address on stack in form LOCAL.decimal
#define SCAN_ARG       12              // Address on stack in form ARG.decimal
#define SCAN_PTR       20              // PTR in MASM addressing statements
#define SCAN_REP       21              // REP prefix
#define SCAN_REPE      22              // REPE prefix
#define SCAN_REPNE     23              // REPNE prefix
#define SCAN_LOCK      24              // LOCK prefix
#define SCAN_NAME      25              // Command or label
#define SCAN_ICONST    26              // Hexadecimal constant
#define SCAN_DCONST    27              // Decimal constant
#define SCAN_OFS       28              // Undefined constant
#define SCAN_FCONST    29              // Floating-point constant
#define SCAN_EIP       30              // Register EIP
#define SCAN_SIGNED    31              // Keyword "SIGNED" (in expressions)
#define SCAN_UNSIGNED  32              // Keyword "UNSIGNED" (in expressions)
#define SCAN_CHAR      33              // Keyword "CHAR" (in expressions)
#define SCAN_FLOAT     34              // Keyword "FLOAT" (in expressions)
#define SCAN_DOUBLE    35              // Keyword "DOUBLE" (in expressions)
#define SCAN_FLOAT10   36              // Keyword "FLOAT10" (in expressions)
#define SCAN_STRING    37              // Keyword "STRING" (in expressions)
#define SCAN_UNICODE   38              // Keyword "UNICODE" (in expressions)
#define SCAN_MSG       39              // Pseudovariable MSG (in expressions)

#define SCAN_SYMB      64              // Any other character
#define SCAN_IMPORT    65              // Import pseudolabel
#define SCAN_ERR       255             // Definitely bad item

// Definition used by Assembler to report command matching errors.
#define MA_JMP         0x0001          // Invalid jump size modifier
#define MA_NOP         0x0002          // Wrong number of operands
#define MA_TYP         0x0004          // Bad operand type
#define MA_NOS         0x0008          // Explicit operand size expected
#define MA_SIZ         0x0010          // Bad operand size
#define MA_DIF         0x0020          // Different operand sizes
#define MA_SEG         0x0040          // Invalid segment register
#define MA_RNG         0x0080          // Constant out of expected range

typedef struct t_asmoperand {
  int            type;                 // Operand type, see beginning of file
  int            size;                 // Operand size or 0 if yet unknown
  int            index;                // Index or other register
  int            scale;                // Scale
  int            base;                 // Base register if present
  long           offset;               // Immediate value or offset
  int            anyoffset;            // Offset is present but undefined
  int            segment;              // Segment in address if present
  int            jmpmode;              // Specified jump size
} t_asmoperand;

static char      *asmcmd;              // Pointer to 0-terminated source line
static int       scan;                 // Type of last scanned element
static int       prio;                 // Priority of operation (0: highest)
static char      sdata[TEXTLEN];       // Last scanned name (depends on type)
static long      idata;                // Last scanned value
static long      double fdata;         // Floating-point number
static char      *asmerror;            // Explanation of last error, or NULL

// Simple and slightly recursive scanner shared by Assemble(). The scanner is
// straightforward and ineffective, but high speed is not a must here. As
// input, it uses global pointer to source line asmcmd. On exit, it fills in
// global variables scan, prio, sdata, idata and/or fdata. If some error is
// detected, asmerror points to error message, otherwise asmerror remains
// unchanged.
static void Scanasm(int mode) {
  int i,j,base,maxdigit;
  long decimal,hex;
  long double floating,divisor;
  char s[TEXTLEN],*pcmd;
  sdata[0]='\0';
  idata=0;
  if (asmcmd==NULL) {
    asmerror="NULL input line"; scan=SCAN_ERR; return; };
  while (*asmcmd==' ' || *asmcmd=='\t')
    asmcmd++;                          // Skip leading spaces
  if (*asmcmd=='\0' || *asmcmd==';') {
    scan=SCAN_EOL; return; };          // Empty line
  if (isalpha(*asmcmd) || *asmcmd=='_' || *asmcmd=='@') {
    sdata[0]=*asmcmd++; i=1;           // Some keyword or identifier
    while ((isalnum(*asmcmd) || *asmcmd=='_' || *asmcmd=='@') &&
      i<sizeof(sdata))
      sdata[i++]=*asmcmd++;
    if (i>=sizeof(sdata)) {
      asmerror="Too long identifier"; scan=SCAN_ERR; return; };
    sdata[i]='\0';
    while (*asmcmd==' ' || *asmcmd=='\t')
      asmcmd++;                        // Skip trailing spaces
    strcpy(s,sdata); strupr(s);
    for (j=0; j<=8; j++) {             // j==8 means "any register"
      if (strcmp(s,regname[0][j])!=0) continue;
      idata=j; scan=SCAN_REG8;         // 8-bit register
      return; };
    for (j=0; j<=8; j++) {
      if (strcmp(s,regname[1][j])!=0) continue;
      idata=j; scan=SCAN_REG16;        // 16-bit register
      return; };
    for (j=0; j<=8; j++) {
      if (strcmp(s,regname[2][j])!=0) continue;
      idata=j; scan=SCAN_REG32;        // 32-bit register
      return; };
    for (j=0; j<6; j++) {
      if (strcmp(s,segname[j])!=0) continue;
      idata=j; scan=SCAN_SEG;          // Segment register
      while (*asmcmd==' ' || *asmcmd=='\t')
        asmcmd++;                      // Skip trailing spaces
      return; };
    if (strcmp(s,"ST")==0) {
      pcmd=asmcmd; Scanasm(SA_NAME);   // FPU register
      if (scan!=SCAN_SYMB || idata!='(') {
        asmcmd=pcmd;                   // Undo last scan
        idata=0; scan=SCAN_FPU; return; };
      Scanasm(SA_NAME); j=idata;
      if ((scan!=SCAN_ICONST && scan!=SCAN_DCONST) || idata<0 || idata>7) {
        asmerror="FPU registers have indexes 0 to 7";
        scan=SCAN_ERR; return; };
      Scanasm(SA_NAME);
      if (scan!=SCAN_SYMB || idata!=')') {
        asmerror="Closing parenthesis expected";
        scan=SCAN_ERR; return; };
      idata=j; scan=SCAN_FPU; return; };
    for (j=0; j<=8; j++) {
      if (strcmp(s,fpuname[j])!=0) continue;
      idata=j; scan=SCAN_FPU;          // FPU register (alternative coding)
      return; };
    for (j=0; j<=8; j++) {
      if (strcmp(s,mmxname[j])!=0) continue;
      idata=j; scan=SCAN_MMX;          // MMX register
      return; };
    for (j=0; j<=8; j++) {
      if (strcmp(s,crname[j])!=0) continue;
      idata=j; scan=SCAN_CR;           // Control register
      return; };
    for (j=0; j<=8; j++) {
      if (strcmp(s,drname[j])!=0) continue;
      idata=j; scan=SCAN_DR;           // Debug register
      return; };
    for (j=0; j<sizeof(sizename)/sizeof(sizename[0]); j++) {
      if (strcmp(s,sizename[j])!=0) continue;
      pcmd=asmcmd; Scanasm(SA_NAME);
      if (scan!=SCAN_PTR)              // Fetch non-functional "PTR"
        asmcmd=pcmd;
      idata=j; scan=SCAN_OPSIZE;       // Operand (data) size in bytes
      return; };
    if (strcmp(s,"EIP")==0) {          // Register EIP
      scan=SCAN_EIP; idata=0; return; };
    if (strcmp(s,"SHORT")==0) {        // Relative jump has 1-byte offset
      scan=SCAN_JMPSIZE; idata=1; return; };
    if (strcmp(s,"LONG")==0) {         // Relative jump has 4-byte offset
      scan=SCAN_JMPSIZE; idata=2; return; };
    if (strcmp(s,"NEAR")==0) {         // Jump within same code segment
      scan=SCAN_JMPSIZE; idata=4; return; };
    if (strcmp(s,"FAR")==0) {          // Jump to different code segment
      scan=SCAN_JMPSIZE; idata=8; return; };
    if (strcmp(s,"LOCAL")==0 && *asmcmd=='.') {
      asmcmd++;
      while (*asmcmd==' ' || *asmcmd=='\t')
        asmcmd++;                      // Skip trailing spaces
      if (!isdigit(*asmcmd)) {
        asmerror="Integer number expected";
        scan=SCAN_ERR; return; };
      while (isdigit(*asmcmd))         // LOCAL index is decimal number!
        idata=idata*10+(*asmcmd++)-'0';
      scan=SCAN_LOCAL; return; };
    if (strcmp(s,"ARG")==0 && *asmcmd=='.') {
      asmcmd++;
      while (*asmcmd==' ' || *asmcmd=='\t')
        asmcmd++;                      // Skip trailing spaces
      if (!isdigit(*asmcmd)) {
        asmerror="Integer number expected";
        scan=SCAN_ERR; return; };
      while (isdigit(*asmcmd))         // ARG index is decimal number!
        idata=idata*10+(*asmcmd++)-'0';
      scan=SCAN_ARG; return; };
    if (strcmp(s,"REP")==0) {
      scan=SCAN_REP; return; };        // REP prefix
    if (strcmp(s,"REPE")==0 || strcmp(s,"REPZ")==0) {
      scan=SCAN_REPE; return; };       // REPE prefix
    if (strcmp(s,"REPNE")==0 || strcmp(s,"REPNZ")==0) {
      scan=SCAN_REPNE; return; };      // REPNE prefix
    if (strcmp(s,"LOCK")==0) {
      scan=SCAN_LOCK; return; };       // LOCK prefix
    if (strcmp(s,"PTR")==0) {
      scan=SCAN_PTR; return; };        // PTR in MASM addressing statements
    if (strcmp(s,"CONST")==0 || strcmp(s,"OFFSET")==0) {
      scan=SCAN_OFS; return; };        // Present but undefined offset/constant
    if (strcmp(s,"SIGNED")==0) {
      scan=SCAN_SIGNED; return; };     // Keyword "SIGNED" (in expressions)
    if (strcmp(s,"UNSIGNED")==0) {
      scan=SCAN_UNSIGNED; return; };   // Keyword "UNSIGNED" (in expressions)
    if (strcmp(s,"CHAR")==0) {
      scan=SCAN_CHAR; return; };       // Keyword "CHAR" (in expressions)
    if (strcmp(s,"FLOAT")==0) {
      scan=SCAN_FLOAT; return; };      // Keyword "FLOAT" (in expressions)
    if (strcmp(s,"DOUBLE")==0) {
      scan=SCAN_DOUBLE; return; };     // Keyword "DOUBLE" (in expressions)
    if (strcmp(s,"FLOAT10")==0) {
      scan=SCAN_FLOAT10; return; };    // Keyword "FLOAT10" (in expressions)
    if (strcmp(s,"STRING")==0) {
      scan=SCAN_STRING; return; };     // Keyword "STRING" (in expressions)
    if (strcmp(s,"UNICODE")==0) {
      scan=SCAN_UNICODE; return; };    // Keyword "UNICODE" (in expressions)
    if (strcmp(s,"MSG")==0) {
      scan=SCAN_MSG; return; };        // Pseudovariable MSG (in expressions)
    if (mode & SA_NAME) {
      idata=i; scan=SCAN_NAME;         // Don't try to decode symbolic label
      return; }
    asmerror="Unknown identifier";
    scan=SCAN_ERR; return; }
  else if (isdigit(*asmcmd)) {         // Constant
    base=0; maxdigit=0; decimal=hex=0L; floating=0.0;
    if (asmcmd[0]=='0' && toupper(asmcmd[1])=='X') {
      base=16; asmcmd+=2; };           // Force hexadecimal number
    while (1) {
      if (isdigit(*asmcmd)) {
        decimal=decimal*10+(*asmcmd)-'0';
        floating=floating*10.0+(*asmcmd)-'0';
        hex=hex*16+(*asmcmd)-'0';
        if (maxdigit==0) maxdigit=9;
        asmcmd++; }
      else if (isxdigit(*asmcmd)) {
        hex=hex*16+toupper(*asmcmd++)-'A'+10;
        maxdigit=15; }
      else break; };
    if (maxdigit==0) {
      asmerror="Hexadecimal digits after 0x... expected";
      scan=SCAN_ERR; return; };
    if (toupper(*asmcmd)=='H') {       // Force hexadecimal number
      if (base==16) {
        asmerror="Please don't mix 0xXXXX and XXXXh forms";
        scan=SCAN_ERR; return; };
      asmcmd++;
      idata=hex; scan=SCAN_ICONST;
      while (*asmcmd==' ' || *asmcmd=='\t') asmcmd++;
      return; };
    if (*asmcmd=='.') {                // Force decimal number
      if (base==16 || maxdigit>9) {
        asmerror="Not a decimal number"; scan=SCAN_ERR; return; };
      asmcmd++;
      if (isdigit(*asmcmd) || toupper(*asmcmd)=='E') {
        divisor=1.0;
        while (isdigit(*asmcmd)) {     // Floating-point number
          divisor/=10.0;
          floating+=divisor*(*asmcmd-'0');
          asmcmd++; };
        if (toupper(*asmcmd)=='E') {

⌨️ 快捷键说明

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