diff --git a/Decompiler.pas b/Decompiler.pas index 8fe61da..af6e6bb 100644 --- a/Decompiler.pas +++ b/Decompiler.pas @@ -593,7 +593,7 @@ constructor TDecompileEnv.Create(AStartAdr:Integer; ASize:Integer; recN:InfoRec) if aInfo.TypeDef = '' then Exit; end; if (ARec.kind = ikFunc) and (ARec._type = '') Then Exit; - Result:=False; + Result:=True; end; Function TDecompiler.Init (fromAdr:Integer):Boolean; @@ -1782,7 +1782,9 @@ constructor TDecompileEnv.Create(AStartAdr:Integer; ASize:Integer; recN:InfoRec) if DeFlags[DisaInfo.Immediate - Env.StartAdr] = 1 then Begin //SetFlag(cfPass, _fromPos); - Inc(curPos, instrLen); + //check Exit + if IsExit(DisaInfo.Immediate) then Env.AddToBody('Exit;'); + Inc(curPos, instrLen); Inc(curAdr, instrLen); break; End; @@ -1855,13 +1857,22 @@ constructor TDecompileEnv.Create(AStartAdr:Integer; ASize:Integer; recN:InfoRec) Env.CmpStack.Add(cmpItem); //skip jcc instrLen := frmDisasm.Disassemble(Code + curPos, curAdr, Nil, Nil); - Inc(curPos, instrLen); + Inc(curPos, instrLen); Inc(curAdr, instrLen); continue; //??? End; if cmpRes = CMP_BRANCH then Begin instrLen := frmDisasm.Disassemble(Code + curPos, curAdr, @disInfo, Nil); + //Exit + if IsExit(disInfo.Immediate) then + begin + line := 'if (' + CompInfo.L + ' ' + GetDirectCondition(CompInfo.O) + ' ' + CompInfo.R + ') then Exit;'; + Env.AddToBody(line); + Inc(curPos, instrLen); + Inc(curAdr, instrLen); + continue; + end; //jcc up if disInfo.Immediate < curAdr then Begin @@ -5524,7 +5535,7 @@ constructor TDecompileEnv.Create(AStartAdr:Integer; ASize:Integer; recN:InfoRec) CompInfo.R := itemSrc.Value; Exit; End - else if (Op = OP_ADD) or (Op = OP_SUB) or (Op = OP_XOR) then + else if Op in [OP_ADD, OP_SUB, OP_XOR] then Begin InitItem(@item); item.Precedence := PRECEDENCE_ADD; @@ -5536,7 +5547,7 @@ constructor TDecompileEnv.Create(AStartAdr:Integer; ASize:Integer; recN:InfoRec) Env.AddToBody(line); Exit; End - else if (Op = OP_MUL) or (Op = OP_IMUL) or (Op = OP_AND) then + else if Op in [OP_MUL, OP_IMUL, OP_AND] then Begin InitItem(@item); item.Precedence := PRECEDENCE_MULT; @@ -5661,6 +5672,13 @@ constructor TDecompileEnv.Create(AStartAdr:Integer; ASize:Integer; recN:InfoRec) Env.AddToBody(line); Exit; End + else if Op = OP_OR then + begin + Env.Stack[itemDst.IntValue].Value := _name; + line := _name + ' := ' + _name + ' Or ' + imm + ';'; + Env.AddToBody(line); + Exit; + end else if Op = OP_XOR then Begin Env.Stack[itemDst.IntValue].Value := _name; @@ -6578,7 +6596,7 @@ function TDecompiler.DecompileTry(fromAdr:Integer; flags:TDecomCset; loopInfo:TL _adr,n,r:Integer; item, item1, item2, item3, item4:TItem; recN:InfoRec; - line, _value, value1, value2, _typeName:AnsiString; + line, _value, value1, value2, _typeName,_op:AnsiString; _int64Val:Int64; Begin Result:=False; @@ -7203,19 +7221,86 @@ function TDecompiler.DecompileTry(fromAdr:Integer; flags:TDecomCset; loopInfo:TL Env.AddToBody(line); Exit; end - else if SameText(name, '@VarAdd') then + else if SameText(name, '@VarAdd') or + SameText(name, '@VarSub') or + SameText(name, '@VarMul') or + SameText(name, '@VarDiv') or + SameText(name, '@VarMod') or + SameText(name, '@VarAnd') or + SameText(name, '@VarOr') or + SameText(name, '@VarXor') or + SameText(name, '@VarShl') or + SameText(name, '@VarShr') or + SameText(name, '@VarRDiv') then begin - //eax=eax+edx + _op := Copy(name,5, Length(name)); GetRegItem(16, item1); GetRegItem(18, item2); if IF_STACK_PTR in item1.Flags then + begin Env.Stack[item1.IntValue]._Type := 'Variant'; + item1 := Env.Stack[item1.IntValue]; + end; if IF_STACK_PTR in item2.Flags then + begin Env.Stack[item2.IntValue]._Type := 'Variant'; - line := item1.Value + ' := ' + item1.Value + ' + ' + item2.Value + ';'; + item2 := Env.Stack[item2.IntValue]; + end; + line := item1.Name + ' := ' + item1.Name + ' ' + _op + ' ' + item2.Name + ';'; Env.AddToBody(line); Exit; end + else if SameText(name, '@VarNeg') or SameText(name, '@VarNot') then + begin + _op := Copy(name,5, Length(name)); + GetRegItem(16, item1); + if IF_STACK_PTR in item1.Flags then + begin + Env.Stack[item1.IntValue]._Type := 'Variant'; + item1 := Env.Stack[item1.IntValue]; + end; + line := item1.Name + ' := ' + _op + ' ' + item1.Name + ';'; + Env.AddToBody(line); + Exit; + end + else if SameText(Copy(name,1, 7), '@VarCmp') then + begin + GetCmpInfo(procAdr + instrLen); + if (name[8] = 'E') and (name[9] = 'Q') then + CompInfo.O := 'E' //JZ + else if (name[8] = 'N') and (name[9] = 'E') then + CompInfo.O := 'F' //JNZ + else if name[8] = 'L' then + begin + if name[9] = 'E' then + CompInfo.O := 'O' //JLE + else if name[9] = 'T' then + CompInfo.O := 'M'; //JL + end + else if name[8] = 'G' then + begin + if name[9] = 'E' then + CompInfo.O := 'N' //JGE + else if name[9] = 'T' then + CompInfo.O := 'P'; //JG + end; + GetRegItem(16, item1); //eax - Left argument + if IF_STACK_PTR in item1.Flags then + begin + Env.Stack[item1.IntValue]._Type := 'Variant'; + item1 := Env.Stack[item1.IntValue]; + CompInfo.L := item1.Name; + end; + GetRegItem(18, item2); //edx - Right argument + if IF_STACK_PTR in item2.Flags then + begin + Env.Stack[item2.IntValue]._Type := 'Variant'; + item2 := Env.Stack[item2.IntValue]; + CompInfo.R := item2.Name; + end; + Result:=true; + Exit; + end //Cast to Variant else if SameText(name, '@VarFromBool') or SameText(name, '@VarFromInt') or @@ -7229,22 +7314,22 @@ function TDecompiler.DecompileTry(fromAdr:Integer; flags:TDecomCset; loopInfo:TL if IF_STACK_PTR in item1.Flags then begin Env.Stack[item1.IntValue]._Type := 'Variant'; - line := Env.GetLvarName(item1.IntValue); + item1 := Env.Stack[item1.IntValue]; end; GetRegItem(18, item2); - line := line + ' := Variant(' + item2.Value + ');'; + line := item1.Name + ' := Variant(' + item2.Name + ');'; Env.AddToBody(line); Exit; End - else if SameText(name, '@VarFromTDateTime') then + else if SameText(name, '@VarFromTDateTime') or SameText(name, '@VarFromCurr') then Begin GetRegItem(16, item1); if IF_STACK_PTR in item1.Flags then begin Env.Stack[item1.IntValue]._Type := 'Variant'; - line := Env.GetLvarName(item1.IntValue); + item1 := Env.Stack[item1.IntValue]; end; - line:=line + ' := Variant(' + FPop.Value + ')'; //FGet(0) + line:=item1.Name + ' := Variant(' + FPop.Value + ')'; //FGet(0) Env.AddToBody(line); FPop; Exit; @@ -9695,6 +9780,7 @@ procedure TDecompiler.GetFloatItemFromStack(Esp:Integer; Dst:PITEM; FloatType:TF try Env.AddToBody('begin'); _curAdr := de.Decompile(_bodyBegAdr, [], loopInfo); + if (_jmpAdr<>0) and IsExit(_jmpAdr) then Env.AddToBody('Exit;'); Env.AddToBody('end'); Except on E:exception do @@ -9705,7 +9791,7 @@ procedure TDecompiler.GetFloatItemFromStack(Esp:Integer; Dst:PITEM; FloatType:TF end; Env.RestoreContext(_bodyBegAdr); //if (_jmpAdr || de.WasRet) de.Free; - if _jmpAdr<>0 then + if (_jmpAdr<>0)and not IsExit(_jmpAdr) then Begin Env.AddToBody('else'); _begAdr := _curAdr; diff --git a/Def_disasm.pas b/Def_disasm.pas index 23ff4fc..b0ea930 100644 --- a/Def_disasm.pas +++ b/Def_disasm.pas @@ -7,21 +7,6 @@ interface Const ASMMAXCOPLEN = 12; - //Instruction type - itUnknown = 0; //Unknown instruction - itTransfer = 1; //Data transfer instruction - itArifm = 2; //Ariphmetical instruction - itLogic = 3; //Logical instruction - itControl = 4; //Control flow instruction - itString = 5; //String instruction - itFloat = 6; //Coprocessor instruction - - otUND = 0; - otIMM = 1; - otREG = 2; - otMEM = 3; - otFST = 4; - OP_RESET = $80; OP_A2 = $40; //2 or 3 operands @@ -91,6 +76,8 @@ interface ); Type + TOperType = (otUND, otIMM, otREG, otMEM, otFST); + TDisInfo = record Mnem:String[32]; Op1:String[64]; @@ -116,7 +103,7 @@ TDisInfo = record RepPrefix:Integer; SegPrefix:Integer; OpNum:Byte; - OpType:Array [0..2] of Byte; + OpType:Array [0..2] of TOperType; End; PDisInfo = ^TDisInfo; diff --git a/Disasm.pas b/Disasm.pas index ceb1e26..ef9b779 100644 --- a/Disasm.pas +++ b/Disasm.pas @@ -233,11 +233,10 @@ MDisasm=class Function GetPostByteMod:Byte; function GetPostByteReg: Byte; function GetPostByteRm: Byte; - function GetOpType(const Op:AnsiString): Integer; + function GetOpType(const Op:AnsiString): TOperType; procedure FormatInstr(DisInfo:PDISINFO; disLine:PAnsiString); procedure FormatArg(argno:Integer; cmd, arg:Integer; DisInfo:PDISINFO; disLine:PAnsiString); function OutputGeneralRegister(var dst:AnsiString; reg, size:Integer): Integer; - procedure OutputHex(var dst:AnsiString; val:Integer); Function GetAddress:Integer; procedure OutputSegPrefix(var dst:AnsiString; DisInfo:PDISINFO); Function EvaluateOperandSize:Integer; @@ -263,7 +262,7 @@ MDisasm=class Implementation -Uses SysUtils,Main,Misc; +Uses SysUtils,Main,Misc,Math; Destructor MDisasm.Destroy; Begin @@ -322,13 +321,13 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; Else Result:=OP_UNK; end; -Function MDisasm.GetOpType(const Op:AnsiString):Integer; +Function MDisasm.GetOpType(const Op:AnsiString):TOperType; Begin if Op='' then Result:=otUND else begin if Pos('[',Op)<>0 then Result:=otMEM - else if Op[1] in ['0'..'9'] then Result:=otIMM + else if Op[1] in ['0'..'9','$','+','-'] then Result:=otIMM Else if (Op[1] = 's') and (Op[2] = 't') then Result:=otFST Else Result:=otREG; end; @@ -362,7 +361,6 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; Function MDisasm.Disassemble(from:PAnsiChar; address:Int64; DisInfo:PDISINFO; disLine:PAnsiString):Integer; var InstrLen:Integer; - //Instr:String[101]; Begin CrtSection.Enter; InstrLen:=DIS.CbDisassemble(0,DIS,100,from,address); @@ -385,11 +383,6 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; end; FormatInstr(DisInfo, disLine); if (DisInfo.IndxReg <> -1) and (DisInfo.Scale=0) then DisInfo.Scale := 1; - { - //Compare results of Microsoft disassembler - CchFormatInstr(0,0,DIS,100,@Instr[1]); - if DisInfo.DisLine=Instr then p := Nil; - } if (DisInfo.Mnem[1] = 'f') or (DisInfo.Mnem = 'wait') then DisInfo.Float := true else if DisInfo.Mnem[1] = 'j' then begin @@ -461,15 +454,6 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; DisInfo.Mnem:=OpName; Inc(Bytes,Length(OpName)); ArgInfo:=PAnsiChar(@DIS.m_popcd.pops.modrmt)+SizeOf(_OPS)+1; - { - asm - mov ecx, [DIS] - mov edx, [ecx+4Ch] - mov eax, [edx+4] - add eax, 9 - mov [ArgInfo], eax - end; - } for i := 0 to 2 do begin if (ArgInfo=Nil) or (ArgInfo^=#0) then break; @@ -485,19 +469,6 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; Cmd:=Byte(ArgInfo^); Arg:=PWord(ArgInfo+1)^; Inc(ArgInfo,4); - { - asm - mov ecx, [ArgInfo] - xor edx, edx - xor eax, eax - mov dx, [ecx+1] - mov [Arg], edx - mov al, [ecx] - mov [Cmd], eax - add ecx, 4 - mov [ArgInfo], ecx - end; - } FormatArg(i, Cmd, Arg, DisInfo, disLine); Inc(DisInfo.OpNum); End; @@ -509,35 +480,22 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; begin dst:=dst + Reg8Tab[reg]; Result:=0; - Exit; end Else if size = 2 then begin dst:=dst + Reg16Tab[reg]; Result:=8; - Exit; end; if (size <> 4) And not GetOperandSize then begin dst:=dst + Reg16Tab[reg]; Result:=8; - Exit; - End; - dst:=dst + Reg32Tab[reg]; - Result:=16; -end; - -Procedure MDisasm.OutputHex(var dst:AnsiString; val:Integer); -Var - buf:AnsiString; -Begin - //if val in [0..9] then dst:=dst + IntToStr(val) - //else + End + else begin - buf:=IntToHex(val,0); - if not (buf[1] in ['0'..'9']) Then dst:=dst+'0'+Buf - else dst:=dst + Buf; - End; + dst:=dst + Reg32Tab[reg]; + Result:=16; + end; end; Function MDisasm.GetAddress:Integer; @@ -557,44 +515,6 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; if DIS.m_dist = distX8616 then x:=(x and $FFFF) or (Integer(DIS.m_addr) and $FFFF0000); Result:=x; end; - { - asm - mov ecx, [DIS] - mov eax, [ecx+64h] - movsx eax, byte ptr [eax+ecx+3Ch] - mov edi, [ecx+38h] - mov ebx, [ecx+28h] - cdq - xor esi, esi - add edi, eax - mov al, [ecx+51h] - push ebp - mov ebp, [ecx+2Ch] - adc esi, edx - add edi, ebx - adc esi, ebp - pop ebp - test al, al - jnz @GA1 - and edi, $FFFF - and esi, 0 - @GA1: - mov eax, [ecx+8] - test eax, eax - jnz @GA2 - and ebx, $FFFF0000 - and edi, $FFFF - or ebx, edi - xor esi, esi - xor ecx, ecx - mov edi, ebx - or esi, ecx - @GA2: - mov eax, edi - mov edx, esi - mov dword ptr [result], eax - end; - } trmtaJmpNear, trmtaJmpCcNear, trmtaCallNear16, @@ -607,51 +527,6 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; if DIS.m_dist = distX8616 then x:=(x and $FFFF) or (Integer(DIS.m_addr) and $FFFF0000); Result:=x; end; - { - asm - mov al, [ecx+51h] - test al, al - jz @GA3 - mov edx, [ecx+64h] - mov eax, [edx+ecx+3Ch] - jmp @GA4 - @GA3: - mov eax, [ecx+64h] - movsx eax, word ptr [eax+ecx+3Ch] - @GA4: - mov edi, [ecx+38h] - mov ebx, [ecx+28h] - cdq - xor esi, esi - add edi, eax - mov al, [ecx+51h] - push ebp - mov ebp, [ecx+2Ch] - adc esi, edx - add edi, ebx - adc esi, ebp - pop ebp - test al, al - jnz @GA5 - and edi, $FFFF - and esi, 0 - @GA5: - mov eax, [ecx+8] - test eax, eax - jnz @GA6 - and ebx, $FFFF0000 - and edi, $FFFF - or ebx, edi - xor esi, esi - xor ecx, ecx - mov edi, ebx - or esi, ecx - @GA6: - mov eax, edi - mov edx, esi - mov dword ptr [result], eax - end; - } trmtaJmpFar, trmtaCallFar: Result:=PInteger(@DIS.m_rgbInstr[DIS.m_ibImmed])^; end; @@ -843,27 +718,11 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; End; end else ofs1 := true; - if ofs then - begin - DisInfo.Offset := offset32; - if ib then - begin - if offset32 < 0 then dst:=dst + '-' - else dst:=dst + '+'; - End; - OutputHex(dst, offset32); - dst:=dst + ']'; - Exit; - end; - if ofs1 then + if ofs or ofs1 then begin DisInfo.Offset := offset32; - if ib then - begin - if offset32 < 0 then dst:=dst + '-' - else dst:=dst + '+'; - End; - OutputHex(dst, offset32); + + dst:=dst+OutputHex(offset32,True); End; dst:=dst + ']'; end; @@ -934,16 +793,14 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; if regcomb<>'' then dst:=dst + '+'; dval:=PWord(@DIS.m_rgbInstr[DIS.m_ibModrm+1])^; DisInfo.Offset := dval; - dst:=dst + IntToHex(dval,4); - Exit; - end; - if sign<>#0 then + dst:=dst + OutputHex(dval,False,4); + end + else if sign<>#0 then begin DisInfo.Offset := offset16; - dst:=dst + sign; - OutputHex(dst, offset16); - dst:=dst + ']'; + dst:=dst + OutputHex(offset16,True,0); end; + dst:=dst+']'; end; Procedure MDisasm.FormatArg(argno:Integer; cmd, arg:Integer; DisInfo:PDISINFO; disLine:PAnsiString); @@ -959,14 +816,14 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; if GetOperandSize then // 32-bit begin dval:=PWord(@DIS.m_rgbInstr[Dis.m_ibImmed+4])^; - Op:=IntToHex(dval,4)+':'; + Op:='$'+IntToHex(dval,4)+':'; dval:=PInteger(@DIS.m_rgbInstr[Dis.m_ibImmed])^; Op:=Op+IntToHex(dval,8); end else // 16-bit begin dval:=PWord(@DIS.m_rgbInstr[DIS.m_ibImmed+2])^; - Op:=IntToHex(dval,4)+':'; + Op:='$'+IntToHex(dval,4)+':'; dval:=PWord(@DIS.m_rgbInstr[DIS.m_ibImmed])^; Op:=Op+IntToHex(dval,4); end; @@ -999,36 +856,37 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; else dval:=PByte(@DIS.m_rgbInstr[DIS.m_ibImmed])^; // unsigned DisInfo.Immediate := dval; //DisInfo.ImmPresent := true; - OutputHex(Op, dval); + Op:=OutputHex(dval,Boolean(IfThen(GetCop = $83,1)),2); end; 8: //Immediate byte begin dval:=PByte(@DIS.m_rgbInstr[DIS.m_ibImmed+2])^; DisInfo.Immediate := dval; //DisInfo.ImmPresent := true; - OutputHex(Op, dval); + Op:=OutputHex(dval,False,2); end; 9: //Immediate dword begin if GetOperandSize then dval:=PInteger(@DIS.m_rgbInstr[DIS.m_ibImmed])^ // 32-bit - else dval:=PWord(@DIS.m_rgbInstr[DIS.m_ibImmed])^; // 16-bit + else dval:=PSmallInt(@DIS.m_rgbInstr[DIS.m_ibImmed])^; // 16-bit DisInfo.Immediate := dval; //DisInfo.ImmPresent := true; - OutputHex(Op, dval); + Op:=OutputHex(dval,Boolean(IfThen(GetOp(DisInfo.Mnem) + in [OP_CMP,OP_ADD,OP_ADC,OP_SUB,OP_SBB,OP_MUL,OP_IMUL,OP_DIV,OP_IDIV],1))); end; 10: //Immediate word (ret) begin dval:=PWord(@DIS.m_rgbInstr[DIS.m_ibImmed])^; DisInfo.Immediate := dval; //DisInfo.ImmPresent := true; - OutputHex(Op, dval); + Op:=OutputHex(dval,False); end; 11,12: //Address (jmp, jcond, call) begin adr := GetAddress; DisInfo.Immediate := adr; //DisInfo.ImmPresent := true; - Op:=IntToHex(adr,8); + Op:=OutputHex(adr,False,8); end; 13,15,27: //Memory if GetAddressSize then @@ -1054,7 +912,7 @@ function MDisasm.GetOp(mnem:AnsiString): Byte; OutputSegPrefix(Op, DisInfo); if GetAddressSize then dval:=PInteger(@DIS.m_rgbInstr[DIS.m_ibImmed])^ // 32-bit else dval:=PWord(@DIS.m_rgbInstr[DIS.m_ibImmed])^; // 16-bit - Op:=Op+'['+IntToHex(dval,8)+']'; + Op:='['+OutputHex(dval,False)+']'; DisInfo.Offset := dval; //! end; 19: //8-bit register diff --git a/EditFunctionDlg.dfm b/EditFunctionDlg.dfm index d4a1a18..f84f6ad 100644 --- a/EditFunctionDlg.dfm +++ b/EditFunctionDlg.dfm @@ -115,7 +115,7 @@ object FEditFunctionDlg: TFEditFunctionDlg end object lArgsBytes: TLabel Left = 78 - Top = 429 + Top = 421 Width = 5 Height = 13 Font.Charset = DEFAULT_CHARSET @@ -151,6 +151,7 @@ object FEditFunctionDlg: TFEditFunctionDlg Font.Style = [] ParentFont = False TabOrder = 0 + WantReturns = False end object rgCallKind: TRadioGroup Left = 11 diff --git a/EditFunctionDlg.pas b/EditFunctionDlg.pas index 22725c6..a9d7761 100644 --- a/EditFunctionDlg.pas +++ b/EditFunctionDlg.pas @@ -60,7 +60,7 @@ TFEditFunctionDlg=class(TForm) { Private declarations } TypModified:Boolean; VarModified:Boolean; - ArgEdited:Integer; + //ArgEdited:Integer; VarEdited:Integer; VmtCandidatesNum:Integer; StackSize:Integer; @@ -230,7 +230,7 @@ procedure TFEditFunctionDlg.bApplyTypeClick(Sender : TObject); Var newEndAdr:Integer; recN:InfoRec; - line,decl,name,retType:AnsiString; + decl,_name,retType:AnsiString; n,p:Integer; begin if cbMethod.Checked and (cbVmtCandidates.Text = '') then @@ -272,45 +272,35 @@ procedure TFEditFunctionDlg.bApplyTypeClick(Sender : TObject); if cbEmbedded.Checked then Include(recN.procInfo.flags, PF_EMBED) else Exclude(recN.procInfo.flags, PF_EMBED); - decl:=''; - (* - if (recN.kind = ikConstructor) or (recN.kind = ikDestructor) then - decl:=decl + 'Self:' + cbVmtCandidates.Text + ';_Dv__:Boolean;' - else if (recN.info.procInfo.flags and PF_ALLMETHODS)<>0 then - decl:=decl + 'Self:' + cbVmtCandidates.Text + ';'; - *) - for n:=0 To mType.Lines.Count-1 do - begin - line:=Trim(mType.Lines[n]); - if line = '' Then continue; - decl:=decl + line; - End; - decl:=Trim(decl); - p:=Length(decl); - if decl[p] = ';' then decl[p]:=' '; - name:=''; - for n:=1 to p do - if decl[n] in [' ','(',';',':'] then - begin - name:=Copy(decl,1, n-1); - p:=n+1; // used later for "retType" - break; - End; + decl:=AnsiReplaceStr(mType.Text,#13#10,' '); + p:=Pos('(',decl); + If p<>0 then _name:=Trim(Copy(decl,1,p-1)) + Else + Begin + p:=Pos(':',decl); + If p<>0 then _name:=Trim(Copy(decl,1,p-1)) + else + Begin + p:=Pos(';',decl); + if p<>0 then _name:=Trim(Copy(decl,1,p-1)) + else _name:=Trim(decl); + end; + end; if recN.kind = ikConstructor then - recN.SetName(cbVmtCandidates.Text + '.Create') + recN.Name:=cbVmtCandidates.Text + '.Create' else if recN.kind = ikDestructor then - recN.SetName(cbVmtCandidates.Text + '.Destroy') - else if SameText(name, GetDefaultProcName(Adr)) then + recN.Name:=cbVmtCandidates.Text + '.Destroy' + {else if SameText(_name, GetDefaultProcName(Adr)) then begin if cbMethod.Checked and (recN.procInfo.flags * PF_ALLMETHODS <> []) then - recN.SetName(cbVmtCandidates.Text + '.' + name) + recN.SetName(cbVmtCandidates.Text + '.' + _name) else recN.SetName(''); - end + end} else begin if cbMethod.Checked and (recN.procInfo.flags * PF_ALLMETHODS <> []) then - recN.SetName(cbVmtCandidates.Text + '.' + ExtractProcName(name)) - else recN.SetName(name); + recN.Name:=cbVmtCandidates.Text + '.' + ExtractProcName(_name) + else recN.Name:=_name; End; recN.procInfo.DeleteArgs; n:=0; @@ -320,15 +310,36 @@ procedure TFEditFunctionDlg.bApplyTypeClick(Sender : TObject); recN.procInfo.AddArg($21, 1, 4, '_Dv__', 'Boolean'); n:=2; end - else if recN.procInfo.flags * PF_ALLMETHODS <> [] then + else if cbMethod.Checked {recN.procInfo.flags * PF_ALLMETHODS <> []} then begin recN.procInfo.AddArg($21, 0, 4, 'Self', cbVmtCandidates.Text); n:=1; end; - retType:=recN.procInfo.AddArgsFromDeclaration(Copy(decl,p,Length(decl)), n, rgCallKind.ItemIndex); - if recN.kind = ikFunc then recN._type:=retType; + p:=Pos('(',decl); + If p<>0 then retType:=recN.procInfo.AddArgsFromDeclaration(decl, n, rgCallKind.ItemIndex) + Else + Begin + p:=Pos(':',decl); + if p<>0 Then + begin + n:=PosEx(';',decl,p); + if n=0 then n:=Length(decl)+1; + retType:=Copy(decl,p+1,n-p-1); + End + Else retType:=''; + end; + if recN.kind = ikFunc then + Begin + if retType<>'' then recN._type:=retType + Else + Begin + ShowMessage('Missing result type for function'); + Exit; + end; + End; recN.procInfo.stackSize:=StackSize; FillType; + FillArgs; cbMethod.Enabled:=false; mType.Enabled:=false; @@ -478,8 +489,7 @@ procedure TFEditFunctionDlg.bAddClick(Sender : TObject); Procedure TFEditFunctionDlg.FillType; Var - callKind:Byte; - argsBytes:Integer; + argsBytes:Integer; flags:TProcFlagSet; recN:InfoRec; line:AnsiString; @@ -493,8 +503,7 @@ procedure TFEditFunctionDlg.bAddClick(Sender : TObject); ikFunc: rgFunctionKind.ItemIndex := 3; end; flags := recN.procInfo.flags; - callKind := recN.procInfo.call_kind; - rgCallKind.ItemIndex := callKind; + rgCallKind.ItemIndex := recN.procInfo.call_kind; cbEmbedded.Checked := PF_EMBED in flags; if cbMethod.Checked then line := recN.MakeMultilinePrototype(Adr, argsBytes, cbVmtCandidates.Text) @@ -523,8 +532,8 @@ procedure TFEditFunctionDlg.bAddClick(Sender : TObject); if argsBytes > recN.procInfo.retBytes then Include(recN.procInfo.flags, PF_ARGSIZEG); if argsBytes < recN.procInfo.retBytes then Include(recN.procInfo.flags, PF_ARGSIZEL); - lRetBytes.Caption := 'RetBytes: ' + IntToStr(recN.procInfo.retBytes); - lArgsBytes.Caption := 'ArgBytes: ' + IntToStr(argsBytes); + lRetBytes.Caption := {'RetBytes: ' +} IntToStr(recN.procInfo.retBytes); + lArgsBytes.Caption := {'ArgBytes: ' +} IntToStr(argsBytes); end; Procedure TFEditFunctionDlg.FillArgs; diff --git a/Heuristic.pas b/Heuristic.pas index 7b9d5d6..a4524cd 100644 --- a/Heuristic.pas +++ b/Heuristic.pas @@ -61,6 +61,11 @@ implementation frmDisasm.Disassemble(Pos2Adr(p), @disInfo, Nil); if disInfo.Branch then begin + if IsExit(disInfo.Immediate) then + begin + Result:= 0; + Exit; + end; if disInfo.Conditional then begin if disInfo.Immediate > Integer(CodeBase) + p then @@ -72,7 +77,6 @@ implementation End Else begin - //if (IsExit(_disInfo.Immediate)) return 0; if disInfo.Immediate > Integer(CodeBase) + p then begin jmpAdr := disInfo.Immediate; diff --git a/Idr.dof b/Idr.dof index bf24b5c..12149f3 100644 --- a/Idr.dof +++ b/Idr.dof @@ -115,7 +115,7 @@ AutoIncBuild=0 MajorVer=1 MinorVer=1 Release=0 -Build=1265 +Build=1327 Debug=0 PreRelease=0 Special=0 @@ -126,7 +126,7 @@ CodePage=1251 [Version Info Keys] CompanyName= FileDescription= -FileVersion=1.1.0.1265 +FileVersion=1.1.0.1327 InternalName= LegalCopyright= LegalTrademarks= diff --git a/Idr.res b/Idr.res index d76d8ec..bba37b1 100644 Binary files a/Idr.res and b/Idr.res differ diff --git a/Infos.pas b/Infos.pas index 74daa18..1bb5bd0 100644 --- a/Infos.pas +++ b/Infos.pas @@ -79,11 +79,7 @@ InfoRec = class Implementation -Uses SysUtils,StrUtils,Misc,Main,Def_disasm,Scanf,CodeSiteLogging; - -Var - //as some statistics for memory leaks detection (remove it when fixed) - stat_InfosOverride:Cardinal; +Uses SysUtils,StrUtils,Misc,Main,Def_disasm,Scanf,Dialogs; Function FieldsCmpFunction(item1,item2:Pointer):Integer; Begin @@ -315,111 +311,103 @@ InfoRec = class Function InfoProcInfo.AddArgsFromDeclaration (Decl:AnsiString; from, callKind:Integer):AnsiString; var - fColon:Boolean; p, pp, cp:Integer; - sc:Char; - ss, num,arg:Integer; + ss, arg:Integer; + sl,sl2:TStringList; + i,j:Integer; aInfo:ArgInfo; - _Name,_Type:AnsiString; + _Name,_Type,t,m:AnsiString; Begin Result:=''; - aInfo.in_Reg:=False; p := Pos('(',Decl); if p<>0 then Begin - Inc(p); - pp := p; - num := 0; - fColon := false; - while true do - Begin - case Decl[pp] of - ')': break; - ';': fColon := false; - ':': if not fColon then - Begin - Decl[pp] := ' '; - Inc(num); - fColon := true; - End; - end; - Inc(pp); - End; - if num<>0 then + Inc(p); + pp := PosEx(')',Decl,p); // Preserve it, used later to get the result type + If pp<>0 Then Begin ss := bpBase; arg := from; - while true do - Begin - _Name := ''; - _Type := ''; - sc := ';'; - pp := PosEx(sc,Decl,p); - if pp=0 then - Begin - sc := ')'; - pp := PosEx(sc,Decl,p); - End; - // pp^ := #0; - //Tag - aInfo.Tag := $21; - while Decl[p] = ' ' do Inc(p); - _Name:=Copy(Decl,p,FirstWord(Decl,p,pp)); - if _Name='var' then - Begin - aInfo.Tag := $22; - Inc(p, Length(_Name)); - while Decl[p] = ' ' do Inc(p); - //Name - _Name:=Copy(Decl,p,FirstWord(Decl,p,pp)); - End - else if _Name= 'val' then + sl:=Nil; + sl2:=Nil; + Try + sl:=TStringList.Create; + ExtractStrings([';'],[],@Copy(Decl,p,pp-p)[1],sl); + sl2:=TStringList.Create; + for i:=0 to sl.Count-1 do Begin - Inc(p, Length(_Name)); - while Decl[p] = ' ' do Inc(p); - //Name - _Name:=Copy(Decl,p,FirstWord(Decl,p,pp)); - End; - Inc(p, Length(_Name)); - while Decl[p] = ' ' do Inc(p); - //Type - _Type:=Copy(Decl, p,pp-p); - //Inc(p, strlen(_Type)); - //while p^ = ' ' do Inc(p); - aInfo.Size := 4; - cp := Pos(':',_Type); - if cp<>0 then - Begin - sscanf(PAnsiChar(_type)+cp+1,'%d',[@aInfo.Size]); - _Type[cp]:=' '; - //sscanf(cp + 1, '%d', &argInfo.Size); - //cp^ := #0; - End; - if callKind = 0 then //fastcall - Begin - if (arg < 3) and (aInfo.Size = 4) then aInfo.Ndx := arg - else + // check each group of arguments + t:=sl[i]; + cp:=Pos(':',t); + if cp=0 then + Begin + ShowMessage('Missing argument type '+IntToStr(i+1)); + Exit; + end; + p:=PosEx('=',t,cp); + if p=0 then p:=Length(t); + _Type:=Trim(Copy(t,cp+1,p-cp)); + sl2.Clear; + ExtractStrings([','],[],@Copy(t,1,cp-1)[1],sl2); + if sl2.Count=0 Then Begin - aInfo.Ndx := ss; - Inc(ss, aInfo.Size); + ShowMessage('Missing argument name '+IntToStr(i+1)); + Exit; + end; + for j:=0 to sl2.Count-1 do + begin + // check each argument in the group + t:=Trim(sl2[j]); + p:=Pos(' ',t); + if p<>0 Then + Begin + m:=Copy(t,1,p-1); + if SameText(m,'var')Or SameText(m,'out') then + Begin + aInfo.Tag:=$22; + _Name:=Trim(Copy(t,p+1,Length(t))); + end + else + Begin + ShowMessage('Unknown argument modifier '+IntToStr(i+1)); + Exit; + end; + end + Else + Begin + aInfo.Tag:=$21; + _Name:=t; + End; + aInfo.Size := 4; + {cp := Pos(':',_Type); + if cp<>0 then + Begin + sscanf(PAnsiChar(_type)+cp+1,'%d',[@aInfo.Size]); + _Type[cp]:=' '; + //sscanf(cp + 1, '%d', &argInfo.Size); + //cp^ := #0; + End;} + // fastcall + if (callKind = 0) and (arg < 3) and (aInfo.Size = 4) then aInfo.Ndx := arg + else + Begin + aInfo.Ndx := ss; + Inc(ss, aInfo.Size); + End; + if _Name= '?' then aInfo.Name := '' + else aInfo.Name := Trim(_Name); + if _Type = '?' then aInfo.TypeDef := '' + else aInfo.TypeDef := TrimTypeName(_Type); + AddArg(@aInfo); + Inc(arg); End; - End - else - Begin - aInfo.Ndx := ss; - Inc(ss, aInfo.Size); - End; - if _Name= '?' then aInfo.Name := '' - else aInfo.Name := Trim(_Name); - if _Type = '?' then aInfo.TypeDef := '' - else aInfo.TypeDef := TrimTypeName(_Type); - AddArg(@aInfo); - Decl[pp] := ' '; - p := pp + 1; - if sc = ')' then break; - Inc(arg); - End; - End; + end; + Finally + sl.Free; + sl2.Free; + end; + p:=pp; + end; End else p := 1; p := PosEx(':',Decl,p); @@ -559,7 +547,7 @@ InfoRec = class if Assigned(InfoList[APos]) then begin //as: if we here - memory leak then! - Inc(stat_InfosOverride); + //Inc(stat_InfosOverride); end; InfoList[APos] := Self; end; @@ -1278,7 +1266,7 @@ procedure InfoRec.Load(ins:TStream; buf:Pointer); Function InfoRec.MakeMultilinePrototype (Adr:Integer; Var ArgsBytes:Integer; MethodType:AnsiString):AnsiString; var - callKind:Byte; + //callKind:Byte; n, num, argsNum, firstArg:Integer; aInfo:PArgInfo; Begin @@ -1325,7 +1313,7 @@ procedure InfoRec.Load(ins:TStream; buf:Pointer); firstArg := 1; End; if num > 0 then result:=result + '('+#13; - callKind := procInfo.call_kind; + //callKind := procInfo.call_kind; for n := firstArg to argsNum-1 do Begin if n <> firstArg then result:=result + ';'+#13; diff --git a/Main.dfm b/Main.dfm index d801b48..95ff350 100644 --- a/Main.dfm +++ b/Main.dfm @@ -50,7 +50,7 @@ object FMain: TFMain Top = 0 Width = 903 Height = 585 - ActivePage = tsNames + ActivePage = tsCodeView Align = alClient TabOrder = 1 OnChange = pcWorkAreaChange @@ -534,7 +534,7 @@ object FMain: TFMain Top = 0 Width = 215 Height = 585 - ActivePage = tsRTTIs + ActivePage = tsUnits Align = alLeft Constraints.MinWidth = 200 TabOrder = 0 diff --git a/Main.pas b/Main.pas index 29b610e..0220742 100644 --- a/Main.pas +++ b/Main.pas @@ -582,7 +582,7 @@ implementation StringInfo, Explorer, FindDlg, EditFieldsDlg,Def_res,IniFiles,TypeInfos, InputDlg,Def_thread, EditFunctionDlg,IDCGen,AboutDlg,ShellAPI,Contnrs, KBViewer, Legend,Decompiler, Hex2Double,Clipbrd, Plugins,ActiveProcesses, - Scanf,TypInfo{,CodeSiteLogging}; + Scanf,TypInfo,Math{,CodeSiteLogging}; Var //Dest:TCodeSiteDestination; @@ -998,7 +998,7 @@ procedure TFMain.miExitClick(Sender : TObject); recN.kind := ikDestructor; End; _pos := Pos('@',recN.Name); - if _pos > 1 then PAnsiChar(recN.Name)[_pos] := '.'; + if _pos > 1 then PAnsiChar(recN.Name)[_pos-1] := '.'; End; End else recN.Name:=recI.module + '.' + recI.name; @@ -5492,9 +5492,8 @@ procedure TFMain.FormShow(Sender : TObject); End; if op = OP_MOV then lastMovAdr := DisInfo.Offset; //short relative abs jmp or cond jmp - if (b1 = $EB) or - ((b1 >= $70) and (b1 <= $7F)) or - ((b1 = 15) and (b2 >= $80) and (b2 <= $8F)) then + if (b1 = $EB) or (b1 in [$70..$7F]) or + ((b1 = 15) and (b2 in [$80..$8F])) then Begin Adr := DisInfo.Immediate; if IsValidCodeAdr(Adr) then @@ -5509,10 +5508,10 @@ procedure TFMain.FormShow(Sender : TObject); flags := flags or 8; if (Adr >= fromAdr) and (Adr > lastAdr) then lastAdr := Adr; End; - wid := AddAsmLine(curAdr, line, flags); + wid := AddAsmLine(curAdr, line, flags); Inc(row); if wid > maxwid then maxwid := wid; - Inc(curPos, instrLen); + Inc(curPos, instrLen); Inc(curAdr, instrLen); continue; End @@ -5528,7 +5527,7 @@ procedure TFMain.FormShow(Sender : TObject); flags := flags or 8; if not Assigned(recN) and (Adr >= fromAdr) and (Adr > lastAdr) then lastAdr := Adr; End; - wid := AddAsmLine(curAdr, line, flags); + wid := AddAsmLine(curAdr, line, flags); Inc(row); if wid > maxwid then maxwid := wid; Inc(curPos, instrLen); @@ -5547,7 +5546,7 @@ procedure TFMain.FormShow(Sender : TObject); //Found @Halt0 - exit if recN.SameName('@Halt0') and (fromAdr = EP) and (lastAdr=0) then Begin - wid := AddAsmLine(curAdr, line, flags); + wid := AddAsmLine(curAdr, line, flags); Inc(row); if wid > maxwid then maxwid := wid; break; @@ -5556,23 +5555,24 @@ procedure TFMain.FormShow(Sender : TObject); End; recN := GetInfoRec(curAdr); if Assigned(recN) and Assigned(recN.Pcode) then line := line + ';' + MakeComment(recN.pcode); - wid := AddAsmLine(curAdr, line, flags); + wid := AddAsmLine(curAdr, line, flags); Inc(row); if wid > maxwid then maxwid := wid; - Inc(curPos, instrLen); + Inc(curPos, instrLen); Inc(curAdr, instrLen); continue; End - else if (b1 = 255) and ((b2 and $38) = $20) and (DisInfo.OpType[0] = otMEM) and IsValidImageAdr(DisInfo.Offset) then //near absolute indirect jmp (Case) + else if (b1 = 255) and ((b2 and $38) = $20) and (DisInfo.OpType[0] = otMEM) + and IsValidImageAdr(DisInfo.Offset) then //near absolute indirect jmp (Case) Begin - wid := AddAsmLine(curAdr, line, flags); + wid := AddAsmLine(curAdr, line, flags); Inc(row); if wid > maxwid then maxwid := wid; if not IsValidCodeAdr(DisInfo.Offset) then break; - + //First instruction //if (curAdr = fromAdr) break; - + cTblAdr := 0; jTblAdr := 0; Pos2 := curPos + instrLen; @@ -5589,10 +5589,10 @@ procedure TFMain.FormShow(Sender : TObject); Begin db := Code[Pos2]; CTab[k] := db; - wid := AddAsmLine(Adr, 'db ' + IntToStr(Ord(db)), $22); + wid := AddAsmLine(Adr, 'db ' + OutputHex(Ord(db),False), $22); Inc(row); if wid > maxwid then maxwid := wid; - Inc(Pos2); + Inc(Pos2); Inc(Adr); End; End; @@ -5610,17 +5610,17 @@ procedure TFMain.FormShow(Sender : TObject); if not IsValidCodeAdr(Adr1) or (Adr1 < fromAdr) then break; //Add row to assembler listing - wid := AddAsmLine(Adr, 'dd ' + Val2Str(Adr1,8), $22); + wid := AddAsmLine(Adr, 'dd ' + Val2Str(Adr1,8), $22); Inc(row); if wid > maxwid then maxwid := wid; //Set cfLoc SetFlag([cfLoc], Adr2Pos(Adr1)); - Inc(Pos2, 4); + Inc(Pos2, 4); Inc(Adr, 4); if Adr1 > lastAdr then lastAdr := Adr1; End; if Adr > lastAdr then lastAdr := Adr; - curPos := Pos2; + curPos := Pos2; curAdr := Adr; continue; End; @@ -5650,16 +5650,14 @@ procedure TFMain.FormShow(Sender : TObject); Begin NPos := curPos + instrLen; //check that next instruction is push fs:[reg] or retn - if ((Code[NPos] = #$64) and - (Code[NPos + 1] = #$FF) and - (((Code[NPos + 2] >= #$30) and (Code[NPos + 2] <= #$37)) or (Code[NPos + 2] = #$75)) - ) or (Code[NPos] = #$C3) then + if ((Code[NPos] = #$64) and (Code[NPos + 1] = #$FF) and (Code[NPos + 2] in [#$30..#$37,#$75])) + or (Code[NPos] = #$C3) then Begin Adr := DisInfo.Immediate; //Adr:=@1 if IsValidCodeAdr(Adr) then Begin if Adr > lastAdr then lastAdr := Adr; - Pos2 := Adr2Pos(Adr); + Pos2 := Adr2Pos(Adr); assert(Pos2 >= 0); delta := Pos2 - NPos; if delta >= 0 then // && delta < outRows) @@ -5690,7 +5688,7 @@ procedure TFMain.FormShow(Sender : TObject); else if recN.SameName('@HandleAnyException') or recN.SameName('@HandleAutoException') then Begin //jmp HandleAnyException - Inc(Pos2, instrLen1); + Inc(Pos2, instrLen1); Inc(Adr, instrLen1); //call DoneExcept instrLen2 := frmDisasm.Disassemble(Code + Pos2, Adr, Nil, Nil); @@ -5829,7 +5827,7 @@ procedure TFMain.FormShow(Sender : TObject); if comment <> '' then line := line + comment; if namei <> '' then line := line + 'Begin' + namei + 'End;'; End; - if Length(line) > MAXLEN then line := Copy(line,1, MAXLEN) + '...'; + //if Length(line) > MAXLEN then line := Copy(line,1, MAXLEN) + '...'; wid := AddAsmLine(curAdr, line, flags); Inc(row); if wid > maxwid then maxwid := wid; @@ -7862,7 +7860,7 @@ procedure TFMain.FindText(str:AnsiString); msg := 'Search string "' + str + '" not found'; case WhereSearch of SEARCH_UNITS: find_vt(UnitsSearchFrom,vtUnit,2); - SEARCH_UNITITEMS: find_vt(UnitItemsSearchFrom,vtProc,2); + SEARCH_UNITITEMS: find_vt(UnitItemsSearchFrom,vtProc,3); SEARCH_RTTIS: find_vt(RTTIsSearchFrom,vtRTTI,2); SEARCH_STRINGS: find_vt(StringsSearchFrom,vtString,2); SEARCH_NAMES: find_vt(NamesSearchFrom,vtName,1); @@ -8337,7 +8335,7 @@ procedure TFMain.miDelphiXE4Click(Sender : TObject); begin OpenDlg.InitialDir := WrkDir; OpenDlg.FileName := ''; - OpenDlg.Filter := 'EXE, DLL|*.exe;*.dll|All files|*.*'; + OpenDlg.Filter := 'EXE, DLL, BPL|*.exe;*.dll;*.bpl|All files|*.*'; if OpenDlg.Execute then FileName := OpenDlg.FileName; end; if FileName <> '' then @@ -8390,6 +8388,7 @@ procedure TFMain.miDelphiXE4Click(Sender : TObject); Screen.Cursor := crDefault; ShowMessage('File ' + FileName + ' is probably Delphi 4, 5, 6, 7, 2005, 2006 or 2007 file, try manual selection'); FInputDlg.Caption := 'Enter number of version (4, 5, 6, 7, 2005, 2006 or 2007)'; + FInputDlg.edtName.EditLabel.Caption:='Version'; FInputDlg.edtName.Text := ''; if FInputDlg.ShowModal = mrCancel then Begin @@ -8696,7 +8695,7 @@ procedure TFMain.miDelphiXE4Click(Sender : TObject); Begin if Application.MessageBox( PAnsiChar(Format('Possible invalid EP (NTHeader:%X, Evaluated:%X). Input valid EP?', - [NTHeaders.OptionalHeader.AddressOfEntryPoint + Cardinal(ImageBase), evalEP + CodeBase])), + [NTHeaders.OptionalHeader.AddressOfEntryPoint + Cardinal(ImageBase), evalEP + Integer(CodeBase)])), 'Confirmation', MB_YESNO) = IDYES then Begin sEP := InputDialogExec('New EP', 'EP:', Val2Str(Integer(NTHeaders.OptionalHeader.AddressOfEntryPoint) + ImageBase)); @@ -8747,10 +8746,10 @@ procedure TFMain.miDelphiXE4Click(Sender : TObject); //DataSize := DataEnd - DataStart; //DataBase := ImageBase + DataStart; - GetMem(FlagList,TotalSize*SizeOf(DWORD)); - FillMemory(FlagList, sizeof(DWORD) * TotalSize,0); + SetLength(FlagList,TotalSize); + FillMemory(@FlagList[0], sizeof(TCflagSet) * TotalSize,0); SetLength(InfoList, TotalSize); - FillMemory(@InfoList[0],TotalSize*SizeOf(InfoRec),0); + FillMemory(@InfoList[0],TotalSize*SizeOf(Pointer),0); BSSInfos := TStringList.Create; BSSInfos.Sorted := true; @@ -8819,7 +8818,7 @@ procedure TFMain.miDelphiXE4Click(Sender : TObject); NameLength := StrLen(Image + Adr2Pos(ImportDescriptor.DllNameRVA + ImageBase)); moduleName := MakeString(Image + Adr2Pos(ImportDescriptor.DllNameRVA + ImageBase), NameLength); - + ps := Pos('.',moduleName); if ps<>0 then modName := Copy(moduleName,1, ps - 1) @@ -10589,7 +10588,7 @@ procedure TFMain.lbCodeDrawItem(Control: TWinControl; Index:Integer; Rect:TRect; //Spaces after db Inc(Rect.Right, (ASMMAXCOPLEN - 2) * sWid); db := Byte(Code[Adr2Pos(adr)]); - DrawOneItem(Val2Str(db), canva, Rect, TColor($FF8080), flag); + DrawOneItem(OutputHex(db,False), canva, Rect, TColor($FF8080), flag); End else if ddPos<>0 then Begin @@ -10657,16 +10656,8 @@ procedure TFMain.lbCodeDrawItem(Control: TWinControl; Index:Integer; Rect:TRect; End else item := Val2Str(_val,8); End - else - Begin - if _val <= 9 then - item := IntToStr(_val) - else - Begin - item := Val2Str(_val); - if not (item[1] in ['0'..'9']) then item := '0' + item; - End; - End; + else item:=OutputHex(_val,Boolean(IfThen(frmDisasm.GetOp(disInfo.Mnem) + in [OP_CMP,OP_ADD,OP_ADC,OP_SUB,OP_SBB,OP_MUL,OP_IMUL,OP_DIV,OP_IDIV],1))); DrawOneItem(item, canva, Rect, col, flag); End else if (disInfo.OpType[n] = otREG) or (disInfo.OpType[n] = otFST) then @@ -10711,32 +10702,19 @@ procedure TFMain.lbCodeDrawItem(Control: TWinControl; Index:Integer; Rect:TRect; if offset<>0 then Begin if offset < 0 then - Begin - item := '-'; - offset := -offset; - End - else item := '+'; - DrawOneItem(item, canva, Rect, TColor(0), flag); - if offset < 9 then - item := IntToStr(offset) - else - Begin - item := Val2Str(offset); - if not (item[1] in ['0'..'9']) then item := '0' + item; - End; + begin + item := '-'; + offset := -offset; + end + else item := '+'; + DrawOneItem(item, canva, Rect, TColor(0), flag); + item := OutputHex(offset,False,0); DrawOneItem(item, canva, Rect, TColor($FF8080), flag); End; End else Begin - if offset < 0 then offset := -offset; - if offset < 9 then - item := IntToStr(offset) - else - Begin - item := Val2Str(offset); - if not (item[1] in ['0'..'9']) then item := '0' + item; - End; + item := OutputHex(offset,False,0); DrawOneItem(item, canva, Rect, TColor($FF8080), flag); End; DrawOneItem(']', canva, Rect, TColor(0), flag); @@ -11109,7 +11087,8 @@ procedure TFMain.OutputCode(Var outF:TextFile; fromAdr:Integer; prototype:AnsiSt Inc(curAdr, instrLen); continue; End - else if (b1 = 255) and ((b2 and $38) = $20) and (DisInfo.OpType[0] = otMEM) and IsValidImageAdr(DisInfo.Offset) then //near absolute indirect jmp (Case) + else if (b1 = 255) and ((b2 and $38) = $20) and (DisInfo.OpType[0] = otMEM) + and IsValidImageAdr(DisInfo.Offset) then //near absolute indirect jmp (Case) Begin OutputLine(outF, flags, curAdr, line); Inc(row); @@ -11132,7 +11111,7 @@ procedure TFMain.OutputCode(Var outF:TextFile; fromAdr:Integer; prototype:AnsiSt Begin db := Byte(Code[Ps]); CTab[k] := db; - OutputLine(outF, flags, curAdr, 'db ' + Char(db)); + OutputLine(outF, flags, curAdr, 'db ' + OutputHex(db,False)); Inc(row); Inc(Ps); Inc(Adr); @@ -11702,8 +11681,7 @@ procedure TFMain.miRenameUnitClick(Sender : TObject); end; kind := recN.kind; //Skip calls, that are in the body of some asm-procs (for example, FloatToText from SysUtils) - if (kind in [ikRefine..ikFunc]) and Assigned(recN.procInfo) - and IsFlagSet([cfImport,cfEmbedded],ps) then + if (kind in [ikRefine..ikFunc]) and Assigned(recN.procInfo) and IsFlagSet([cfImport],ps) then begin Inc(adr); continue; @@ -19445,7 +19423,15 @@ procedure TFMain.vtUnitKeyDown(Sender: TObject; var Key: Word; Shift: TShiftStat procedure TFMain.vtUnitMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin - if TWinControl(Sender).CanFocus then ActiveControl := TWinControl(Sender); + if TWinControl(Sender).CanFocus then + begin + ActiveControl := TWinControl(Sender); + if ActiveControl=vtUnit Then WhereSearch:=SEARCH_UNITS + else if ActiveControl=vtRTTI then WhereSearch:=SEARCH_RTTIS + else if ActiveControl=vtName then WhereSearch:=SEARCH_NAMES + else if ActiveControl=vtString then WhereSearch:=SEARCH_STRINGS + else if ActiveControl=vtProc then WhereSearch:=SEARCH_UNITITEMS; + end; end; procedure TFMain.vtUnitPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); diff --git a/Misc.pas b/Misc.pas index c77a950..9a3684e 100644 --- a/Misc.pas +++ b/Misc.pas @@ -110,6 +110,8 @@ procedure SetFlags(flag:TCFlagSet; p, num:Integer); Procedure RestoreCanvas(ACanvas:TCanvas); Procedure DrawOneItem(AItem:AnsiString; ACanvas:TCanvas; var ARect:TRect; AColor:TColor; flags:Integer); +Function OutputHex(v:Integer;sign:Boolean;dig:Integer=0):AnsiString; + var StringBuf:Array [0..MAXSTRBUFFER] of Char; //Buffer to make string @@ -165,7 +167,7 @@ implementation var k:Integer; Begin - Result:=1; + Result:=from; if Last<>0 then k:=Last else k:=Length(str); while (Result<=k)and not(str[Result] in [' ',#13,#10,#9]) Do Inc(Result); Dec(Result); @@ -387,7 +389,8 @@ implementation if AName <>'' then begin p:= Pos('.',AName); - if p<>0 then Result:=Copy(AName,p+1, Length(AName)); + if p<>0 then Result:=Copy(AName,p+1, Length(AName)) + else Result:=AName; End; end; @@ -2272,6 +2275,8 @@ if Pos('=record',str)<>0 then end; Procedure Copy2Clipboard (items:TStrings; leftMargin:Integer; asmCode:Boolean); +Const + CRLF:AnsiString = #13+#10; Var n,BufLen:Integer; line:AnsiString; @@ -2292,8 +2297,9 @@ if Pos('=record',str)<>0 then //Запихиваем все данные в буфер for n := 0 to items.Count-1 do begin - line := Copy(items[n],leftMargin+1,1024)+#13+#10; - buf.Write(line[1],Length(line)); + line := Copy(items[n],leftMargin+1,2000); + buf.Write(line[1],Length(line)-Ord(asmCode)); + buf.Write(CRLF[1],2); End; n:=0; buf.Write(n,1); @@ -2466,6 +2472,28 @@ function FloatNameToFloatType(AName:AnsiString): TFloatKind; RestoreCanvas(ACanvas); end; +Function OutputHex(v:Integer;sign:Boolean;dig:Integer=0):AnsiString; +begin + if sign then + begin + if (v>=-9) and (v<=9) then + begin + if v<0 then Result:=IntToStr(v) + else Result:='+'+IntToStr(v); + end + else + begin + if v<0 then Result:='-$'+IntToHex(-v,dig) + else Result:='+$'+IntToHex(v,dig); + end; + end + else + begin + if v in [0..9] then Result:=IntToStr(v) + else Result:='$'+IntToHex(v,dig); + end; +end; + Initialization IDRVersion:=GetModuleVersion(Application.ExeName);