?? disasm.c
字號:
if (mnemosize==4 && sizesens!=2) name[i++]='D';
else if (mnemosize!=4 && sizesens!=0) name[i++]='W'; }
else name[i++]=pd->name[j];
};
name[i]='\0'; }
else {
strcpy(name,pd->name);
for (i=0; name[i]!='\0'; i++) {
if (name[i]==',') { // Use main mnemonic
name[i]='\0'; break;
};
};
};
if (repprefix!=0 && tabarguments) {
for (i=0; name[i]!='\0' && name[i]!=' '; i++)
da->result[nresult++]=name[i];
if (name[i]==' ') {
da->result[nresult++]=' '; i++; };
while (nresult<8) da->result[nresult++]=' ';
for ( ; name[i]!='\0'; i++)
da->result[nresult++]=name[i];
; }
else
nresult+=sprintf(da->result+nresult,"%s",name);
if (lowercase) strlwr(da->result);
};
// Decode operands (explicit - encoded in command, implicit - present in
// mmemonic or assumed - used or modified by command). Assumed operands
// must stay after all explicit and implicit operands. Up to 3 operands
// are allowed.
for (operand=0; operand<3; operand++) {
if (da->error) break; // Error - no sense to continue
// If command contains both source and destination, one usually must not
// decode destination to comment because it will be overwritten on the
// next step. Global addcomment takes care of this. Decoding routines,
// however, may ignore this flag.
if (operand==0 && pd->arg2!=NNN && pd->arg2<PSEUDOOP)
addcomment=0;
else
addcomment=1;
// Get type of next argument.
if (operand==0) arg=pd->arg1;
else if (operand==1) arg=pd->arg2;
else arg=pd->arg3;
if (arg==NNN) break; // No more operands
// Arguments with arg>=PSEUDOOP are assumed operands and are not
// displayed in disassembled result, so they require no delimiter.
if ((mode>=DISASM_FILE) && arg<PSEUDOOP) {
if (operand==0) {
da->result[nresult++]=' ';
if (tabarguments) {
while (nresult<8) da->result[nresult++]=' ';
}; }
else {
da->result[nresult++]=',';
if (extraspace) da->result[nresult++]=' ';
};
};
// Decode, analyse and comment next operand of the command.
switch (arg) {
case REG: // Integer register in Reg field
if (size<2) da->error=DAE_CROSS;
else DecodeRG(cmd[1]>>3,datasize,REG);
hasrm=1; break;
case RCM: // Integer register in command byte
DecodeRG(cmd[0],datasize,RCM); break;
case RG4: // Integer 4-byte register in Reg field
if (size<2) da->error=DAE_CROSS;
else DecodeRG(cmd[1]>>3,4,RG4);
hasrm=1; break;
case RAC: // Accumulator (AL/AX/EAX, implicit)
DecodeRG(REG_EAX,datasize,RAC); break;
case RAX: // AX (2-byte, implicit)
DecodeRG(REG_EAX,2,RAX); break;
case RDX: // DX (16-bit implicit port address)
DecodeRG(REG_EDX,2,RDX); break;
case RCL: // Implicit CL register (for shifts)
DecodeRG(REG_ECX,1,RCL); break;
case RS0: // Top of FPU stack (ST(0))
DecodeST(0,0); break;
case RST: // FPU register (ST(i)) in command byte
DecodeST(cmd[0],0); break;
case RMX: // MMX register MMx
if (size<2) da->error=DAE_CROSS;
else DecodeMX(cmd[1]>>3);
hasrm=1; break;
case R3D: // 3DNow! register MMx
if (size<2) da->error=DAE_CROSS;
else DecodeNR(cmd[1]>>3);
hasrm=1; 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
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)
DecodeMR(arg); break;
case MMS: // Memory in ModRM byte (as SEG:OFFS)
DecodeMR(arg);
da->warnings|=DAW_FARADDR; break;
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 ((cmd[1] & 0xC0)!=0xC0) softerror=DAE_REGISTER;
DecodeMR(arg); break;
case MSO: // Source in string op's ([ESI])
DecodeSO(); break;
case MDE: // Destination in string op's ([EDI])
DecodeDE(); break;
case MXL: // XLAT operand ([EBX+AL])
DecodeXL(); break;
case IMM: // Immediate data (8 or 16/32)
case IMU: // Immediate unsigned data (8 or 16/32)
if ((pd->bits & SS)!=0 && (*cmd & 0x02)!=0)
DecodeIM(1,datasize,arg);
else
DecodeIM(datasize,0,arg);
break;
case VXD: // VxD service (32-bit only)
DecodeVX(); break;
case IMX: // Immediate sign-extendable byte
DecodeIM(1,datasize,arg); break;
case C01: // Implicit constant 1 (for shifts)
DecodeC1(); break;
case IMS: // Immediate byte (for shifts)
case IM1: // Immediate byte
DecodeIM(1,0,arg); break;
case IM2: // Immediate word (ENTER/RET)
DecodeIM(2,0,arg);
if ((da->immconst & 0x03)!=0) da->warnings|=DAW_STACK;
break;
case IMA: // Immediate absolute near data address
DecodeIA(); break;
case JOB: // Immediate byte offset (for jumps)
DecodeRJ(1,srcip+2); break;
case JOW: // Immediate full offset (for jumps)
DecodeRJ(datasize,srcip+datasize+1); break;
case JMF: // Immediate absolute far jump/call addr
DecodeJF();
da->warnings|=DAW_FARADDR; break;
case SGM: // Segment register in ModRM byte
if (size<2) da->error=DAE_CROSS;
DecodeSG(cmd[1]>>3); hasrm=1; break;
case SCM: // Segment register in command byte
DecodeSG(cmd[0]>>3);
if ((da->cmdtype & C_TYPEMASK)==C_POP) da->warnings|=DAW_SEGMENT;
break;
case CRX: // Control register CRx
if ((cmd[1] & 0xC0)!=0xC0) da->error=DAE_REGISTER;
DecodeCR(cmd[1]); break;
case DRX: // Debug register DRx
if ((cmd[1] & 0xC0)!=0xC0) da->error=DAE_REGISTER;
DecodeDR(cmd[1]); break;
case PRN: // Near return address (pseudooperand)
break;
case PRF: // Far return address (pseudooperand)
da->warnings|=DAW_FARADDR; break;
case PAC: // Accumulator (AL/AX/EAX, pseudooperand)
DecodeRG(REG_EAX,datasize,PAC); break;
case PAH: // AH (in LAHF/SAHF, pseudooperand)
case PFL: // Lower byte of flags (pseudooperand)
break;
case PS0: // Top of FPU stack (pseudooperand)
DecodeST(0,1); break;
case PS1: // ST(1) (pseudooperand)
DecodeST(1,1); break;
case PCX: // CX/ECX (pseudooperand)
DecodeRG(REG_ECX,cxsize,PCX); break;
case PDI: // EDI (pseudooperand in MMX extentions)
DecodeRG(REG_EDI,4,PDI); break;
default:
da->error=DAE_INTERN; // Unknown argument type
break;
};
};
// Check whether command may possibly contain fixups.
if (pfixup!=NULL && da->fixupsize>0)
da->fixupoffset=pfixup-src;
// Segment prefix and address size prefix are superfluous for command which
// does not access memory. If this the case, mark command as rare to help
// in analysis.
if (da->memtype==DEC_UNKNOWN &&
(segprefix!=SEG_UNDEF || (addrsize!=4 && pd->name[0]!='$'))
) {
da->warnings|=DAW_PREFIX;
da->cmdtype|=C_RARE; };
// 16-bit addressing is rare in 32-bit programs. If this is the case,
// mark command as rare to help in analysis.
if (addrsize!=4) da->cmdtype|=C_RARE;
};
// Suffix of 3DNow! command is accounted best by assuming it immediate byte
// constant.
if (is3dnow) {
if (immsize!=0) da->error=DAE_BADCMD;
else immsize=1; };
// Right or wrong, command decoded. Now dump it.
if (da->error!=0) { // Hard error in command detected
if (mode>=DISASM_FILE)
nresult=sprintf(da->result,"???");
if (da->error==DAE_BADCMD &&
(*cmd==0x0F || *cmd==0xFF) && size>0
) {
if (mode>=DISASM_FILE) ndump+=sprintf(da->dump+ndump,"%02X",*cmd);
cmd++; size--; };
if (size>0) {
if (mode>=DISASM_FILE) ndump+=sprintf(da->dump+ndump,"%02X",*cmd);
cmd++; size--;
}; }
else { // No hard error, dump command
if (mode>=DISASM_FILE) {
ndump+=sprintf(da->dump+ndump,"%02X",*cmd++);
if (hasrm) ndump+=sprintf(da->dump+ndump,"%02X",*cmd++);
if (hassib) ndump+=sprintf(da->dump+ndump,"%02X",*cmd++);
if (dispsize!=0) {
da->dump[ndump++]=' ';
for (i=0; i<dispsize; i++) {
ndump+=sprintf(da->dump+ndump,"%02X",*cmd++);
};
};
if (immsize!=0) {
da->dump[ndump++]=' ';
for (i=0; i<immsize; i++) {
ndump+=sprintf(da->dump+ndump,"%02X",*cmd++);
};
};
}
else
cmd+=1+hasrm+hassib+dispsize+immsize;
size-=1+hasrm+hassib+dispsize+immsize;
};
// Check that command is not a dangerous one.
if (mode>=DISASM_DATA) {
for (pdan=dangerous; pdan->mask!=0; pdan++) {
if (((code^pdan->code) & pdan->mask)!=0)
continue;
if (pdan->type==C_DANGERLOCK && lockprefix==0)
break; // Command harmless without LOCK prefix
if (iswindowsnt && pdan->type==C_DANGER95)
break; // Command harmless under Windows NT
// Dangerous command!
if (pdan->type==C_DANGER95) da->warnings|=DAW_DANGER95;
else da->warnings|=DAW_DANGEROUS;
break;
};
};
if (da->error==0 && softerror!=0)
da->error=softerror; // Error, but still display command
if (mode>=DISASM_FILE) {
if (da->error!=DAE_NOERR) switch (da->error) {
case DAE_CROSS:
strcpy(da->comment,"Command crosses end of memory block"); break;
case DAE_BADCMD:
strcpy(da->comment,"Unknown command"); break;
case DAE_BADSEG:
strcpy(da->comment,"Undefined segment register"); break;
case DAE_MEMORY:
strcpy(da->comment,"Illegal use of register"); break;
case DAE_REGISTER:
strcpy(da->comment,"Memory address not allowed"); break;
case DAE_INTERN:
strcpy(da->comment,"Internal OLLYDBG error"); break;
default:
strcpy(da->comment,"Unknown error");
break; }
else if ((da->warnings & DAW_PRIV)!=0 && privileged==0)
strcpy(da->comment,"Privileged command");
else if ((da->warnings & DAW_IO)!=0 && iocommand==0)
strcpy(da->comment,"I/O command");
else if ((da->warnings & DAW_FARADDR)!=0 && farcalls==0) {
if ((da->cmdtype & C_TYPEMASK)==C_JMP)
strcpy(da->comment,"Far jump");
else if ((da->cmdtype & C_TYPEMASK)==C_CAL)
strcpy(da->comment,"Far call");
else if ((da->cmdtype & C_TYPEMASK)==C_RET)
strcpy(da->comment,"Far return");
; }
else if ((da->warnings & DAW_SEGMENT)!=0 && farcalls==0)
strcpy(da->comment,"Modification of segment register");
else if ((da->warnings & DAW_SHIFT)!=0 && badshift==0)
strcpy(da->comment,"Shift constant out of range 1..31");
else if ((da->warnings & DAW_PREFIX)!=0 && extraprefix==0)
strcpy(da->comment,"Superfluous prefix");
else if ((da->warnings & DAW_LOCK)!=0 && lockedbus==0)
strcpy(da->comment,"LOCK prefix");
else if ((da->warnings & DAW_STACK)!=0 && stackalign==0)
strcpy(da->comment,"Unaligned stack operation");
;
};
return (srcsize-size); // Returns number of recognized bytes
};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -