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

📄 assembl.cpp

📁 实现了屏幕截取
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				{
					if (sign=='-')
					{
						asmerror="Unable to subtract register"; scan=SCAN_ERR;
						return;
					};
					if (xlataddr!=0) 
					{
						asmerror="Too many registers"; 
						scan=SCAN_ERR; 
						return;
					};
					xlataddr=1;
					Scanasm(0);
				}
				else if (scan==SCAN_REG16)
				{
					asmerror="Sorry, 16-bit addressing is not supported";
					scan=SCAN_ERR;
					return;
				}
				else if (scan==SCAN_REG32)
				{
					if (sign=='-') 
					{
						asmerror="Unable to subtract register";
						scan=SCAN_ERR; return;
					};
					reg=idata; Scanasm(0);
					if (scan==SCAN_SYMB && idata=='*')
					{
						Scanasm(0);                  // Try index*scale
						if (scan==SCAN_ERR)
							return;
						if (scan==SCAN_OFS) 
						{
							asmerror="Undefined scale is not allowed"; 
							scan=SCAN_ERR; 
							return; 
						};
						if (scan!=SCAN_ICONST && scan!=SCAN_DCONST) 
						{
							asmerror="Syntax error";
							scan=SCAN_ERR; 
							return; 
						};
						if (idata==6 || idata==7 || idata>9)
						{
							asmerror="Invalid scale";
							scan=SCAN_ERR;
							return;
						};
						r[reg]+=idata;
						Scanasm(0); 
					}
					else 
						r[reg]++; 
				}               // Simple register
				else if (scan==SCAN_LOCAL) 
				{
					r[REG_EBP]++;
					op->offset-=idata*4;
					Scanasm(0);
				}
				else if (scan==SCAN_ARG)
				{
					r[REG_EBP]++;
					op->offset+=(idata+1)*4;
					Scanasm(0);
				}
				else if (scan==SCAN_ICONST || scan==SCAN_DCONST)
				{
					offset=idata; 
					Scanasm(0);
					if (scan==SCAN_SYMB && idata=='*')
					{
						Scanasm(0);                  // Try scale*index
						if (scan==SCAN_ERR)
							return;
						if (sign=='-')
						{
							asmerror="Unable to subtract register"; 
							scan=SCAN_ERR;
							return;
						};
						if (scan==SCAN_REG16) 
						{
							asmerror="Sorry, 16-bit addressing is not supported";
							scan=SCAN_ERR;
							return;
						};
						if (scan!=SCAN_REG32)
						{
							asmerror="Syntax error";
							scan=SCAN_ERR; 
							return;
						};
						if (offset==6 || offset==7 || offset>9)
						{
							asmerror="Invalid scale";
							scan=SCAN_ERR;
							return; 
						};
						r[idata]+=offset;
						Scanasm(0); 
					}
					else 
					{
						if (sign=='-') 
							op->offset-=offset;
						else 
							op->offset+=offset;
					};
				}
				else if (scan==SCAN_OFS) 
				{
					Scanasm(0);
					if (scan==SCAN_SYMB && idata=='*')
					{
						asmerror="Undefined scale is not allowed"; scan=SCAN_ERR; return; }
					else 
					{
						op->anyoffset=1;
					}; 
				}
				else 
					break;                      // None of expected address elements
				if (scan==SCAN_SYMB && idata==']')
					break;
				sign='?';
		};
		if (scan==SCAN_ERR) 
			return;
		if (scan!=SCAN_SYMB || idata!=']') 
		{
			asmerror="Syntax error";
			scan=SCAN_ERR;
			return;
		};
		// Process XLAT address separately.
		if (xlataddr!=0) 
		{                 // XLAT address in form [EBX+AX]
			for (i=0; i<=8; i++) 
			{           // Check which registers used
				if (i==REG_EBX)
					continue;
				if (r[i]!=0) break; 
			};
			if (i<=8 || r[REG_EBX]!=1 || op->offset!=0 || op->anyoffset!=0) 
			{
				asmerror="Invalid address";
				scan=SCAN_ERR;
				return;
			};
			op->type=MXL;
		}
		// Determine scale, index and base.
		else 
		{
			j=0;                             // Number of used registers
			for (i=0; i<=8; i++)
			{
				if (r[i]==0)
					continue;                    // Unused register
				if (r[i]==3 || r[i]==5 || r[i]==9)
				{
					if (op->index>=0 || op->base>=0)
					{
						if (j==0) 
							asmerror="Invalid scale";
						else 
							asmerror="Too many registers";
						scan=SCAN_ERR;
						return;
					};
					op->index=op->base=i;
					op->scale=r[i]-1;
				}
				else if (r[i]==2 || r[i]==4 || r[i]==8)
				{
					if (op->index>=0) 
					{
						if (j<=1) 
							asmerror="Only one register may be scaled";
						else 
							asmerror="Too many registers";
						scan=SCAN_ERR;
						return; 
					};
					op->index=i;
					op->scale=r[i];
				}
				else if (r[i]==1)
				{
					if (op->base<0)
						op->base=i;
					else if (op->index<0)
					{
						op->index=i;
						op->scale=1;
					}
					else
					{
						asmerror="Too many registers";
						scan=SCAN_ERR;
						return;
					};
				}
				else 
				{
					asmerror="Invalid scale";
					scan=SCAN_ERR;
					return;
				};
				j++;
			};
			op->type=MRG;
		}; 
	}
	else 
	{
		asmerror="Unrecognized operand";
		scan=SCAN_ERR; 
		return; };
		// In general, address modifier is allowed only with address expression which
		// is a constant, a far address or a memory expression. More precise check
		// will be done later in Assemble().
		if (op->jmpmode!=0 && op->type!=IMM && op->type!=JMF && op->type!=MRG)
		{
			asmerror="Jump address modifier is not allowed";
			scan=SCAN_ERR; 
			return;
		};
		Scanasm(0);                          // Fetch next token from input line
};

// Function assembles text into 32-bit 80x86 machine code. It supports imprecise
// operands (for example, R32 stays for any general-purpose 32-bit register).
// This allows to search for incomplete commands. Command is precise when all
// significant bytes in model.mask are 0xFF. Some commands have more than one
// decoding. By calling Assemble() with attempt=0,1... and constsize=0,1,2,3 one
// gets also alternative variants (bit 0x1 of constsize is responsible for size
// of address constant and bit 0x2 - for immediate data). However, only one
// address form is generated ([EAX*2], but not [EAX+EAX]; [EBX+EAX] but not
// [EAX+EBX]; [EAX] will not use SIB byte; no DS: prefix and so on). Returns
// number of bytes in assembled code or non-positive number in case of detected
// error. This number is the negation of the offset in the input text where the
// error encountered. Unfortunately, BC 4.52 is unable to compile the switch
// (arg) in this code when any common subexpression optimization is on. The
// next #pragma statement disables all optimizations.

//#pragma option -Od                     // No optimizations, or BC 4.52 crashes

int Assemble(char *cmd,ulong ip,t_asmmodel *model,int attempt,int constsize,char *errtext) 
{
	int i,j,k,namelen,nameok,arg,match,datasize,addrsize,bytesize,minop,maxop;
	int rep,lock,segment,jmpsize,jmpmode,longjump;
	int hasrm,hassib,dispsize,immsize;
	int anydisp,anyimm,anyjmp;
	long l,displacement,immediate,jmpoffset = 0;
	char name[32],*nameend;
	char tcode[MAXCMDSIZE],tmask[MAXCMDSIZE];
	t_asmoperand aop[3],*op;             // Up to 3 operands allowed
	const t_cmddata *pd;
	if (model!=NULL) 
		model->length=0;
	if (cmd==NULL || model==NULL || errtext==NULL) 
	{
		if (errtext!=NULL) 
			strcpy(errtext,"Internal OLLYDBG error");
		return 0; 
	};                       // Error in parameters
	asmcmd=cmd;
	rep=lock=0; errtext[0]='\0';
	Scanasm(SA_NAME);
	if (scan==SCAN_EOL)                  // End of line, nothing to assemble
		return 0;
	while (1) 
	{                          // Fetch all REPxx and LOCK prefixes
		if (scan==SCAN_REP || scan==SCAN_REPE || scan==SCAN_REPNE) 
		{
			if (rep!=0)
			{
				strcpy(errtext,"Duplicated REP prefix"); 
				goto error; 
			};
			rep=scan;
		}
		else if (scan==SCAN_LOCK)
		{
			if (lock!=0) 
			{
				strcpy(errtext,"Duplicated LOCK prefix");
				goto error;
			};
			lock=scan;
		}
		else
			break;                        // No more prefixes
		Scanasm(SA_NAME); 
	};
	if (scan!=SCAN_NAME || idata>16) 
	{
		strcpy(errtext,"Command mnemonic expected");
		goto error;
	};
	nameend=asmcmd;
	strupr(sdata);
	// Prepare full mnemonic (including repeat prefix, if any).
	if (rep==SCAN_REP) 
		sprintf(name,"REP %s",sdata);
	else if (rep==SCAN_REPE)
		sprintf(name,"REPE %s",sdata);
	else if (rep==SCAN_REPNE)
		sprintf(name,"REPNE %s",sdata);
	else 
		strcpy(name,sdata);
	Scanasm(0);
	// Parse command operands (up to 3). Note: jump address is always the first
	// (and only) operand in actual command set.
	for (i=0; i<3; i++) 
	{
		aop[i].type=NNN;                   // No operand
		aop[i].size=0;                     // Undefined size
		aop[i].index=-1;                   // No index
		aop[i].scale=0;                    // No scale
		aop[i].base=-1;                    // No base
		aop[i].offset=0;                   // No offset
		aop[i].anyoffset=0;                // No offset
		aop[i].segment=SEG_UNDEF;          // No segment
		aop[i].jmpmode=0;
	};               // No jump size modifier
	Parseasmoperand(aop+0);
	jmpmode=aop[0].jmpmode;
	if (jmpmode!=0) jmpmode|=0x80;
	if (scan==SCAN_SYMB && idata==',') 
	{
		Scanasm(0);
		Parseasmoperand(aop+1);
		if (scan==SCAN_SYMB && idata==',') 
		{
			Scanasm(0);
			Parseasmoperand(aop+2);
		};
	};
	if (scan==SCAN_ERR)
	{
		strcpy(errtext,asmerror); goto error;
	};
	if (scan!=SCAN_EOL) 
	{
		strcpy(errtext,"Extra input after operand");
		goto error;
	};
	// If jump size is not specified, function tries to use short jump. If
	// attempt fails, it retries with long form.
	longjump=0;                          // Try short jump on the first pass
retrylongjump:
	nameok=0;
	// Some commands allow different number of operands. Variables minop and
	// maxop accumulate their minimal and maximal counts. The numbers are not
	// used in assembly process but allow for better error diagnostics.
	minop=3; maxop=0;
	// Main assembly loop: try to find the command which matches all operands,
	// but do not process operands yet.
	namelen=(int)strlen(name);
	for (pd=cmddata; pd->mask!=0; pd++)
	{
		if (pd->name[0]=='&')
		{            // Mnemonic depends on operand size
			j=1;
			datasize=2;
			addrsize=4;
			while (1) 
			{                      // Try all mnemonics (separated by ':')
				for (i=0; pd->name[j]!='\0' && pd->name[j]!=':'; j++)
				{
					if (pd->name[j]=='*') 
					{
						if (name[i]=='W')
						{
							datasize=2;
							i++;
						}
						else if (name[i]=='D')
						{ 
							datasize=4;
							i++;
						}
						else if (sizesens==0) 
							datasize=2;
						else
							datasize=4;
					}
					else if (pd->name[j]==name[i])
						i++;
					else 
						break;
				};
				if (name[i]=='\0' && (pd->name[j]=='\0' || pd->name[j]==':'))
					break;                       // Bingo!
				while (pd->name[j]!='\0' && pd->name[j]!=':')
					j++;
				if (pd->name[j]==':')
				{
					j++; datasize=4;
				}           // Retry with 32-bit mnenonic
				else 
				{
					i=0; 
					break;                  // Comparison failed
				};
			};
			if (i==0) 
				continue; 
		}
		else if (pd->name[0]=='$')	// Mnemonic depends on address size
		{
			j=1;
			datasize=0;
			addrsize=2;
			while (1)
			{                      // Try all mnemonics (separated by ':')
				for (i=0; pd->name[j]!='\0' && pd->name[j]!=':'; j++)
				{
					if (pd->name[j]=='*')
					{
						if (name[i]=='W')
						{
							addrsize=2;
							i++;
						}
						else if (name[i]=='D') 
						{ addrsize=4; i++;
						}
						else if (sizesens==0) 
							addrsize=2;
						else 
							addrsize=4; 

⌨️ 快捷键说明

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